Advertisement
Guest User

Untitled

a guest
Feb 5th, 2016
253
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.50 KB | None | 0 0
  1. diff --git a/src/contrib/libpdel/util/pevent.c b/src/contrib/libpdel/util/pevent.c
  2. index 6cb2710..6fd382d 100644
  3. --- a/src/contrib/libpdel/util/pevent.c
  4. +++ b/src/contrib/libpdel/util/pevent.c
  5. @@ -39,6 +39,7 @@
  6.   */
  7.  
  8.  #include <sys/types.h>
  9. +#include <sys/event.h>
  10.  #include <sys/param.h>
  11.  #include <sys/queue.h>
  12.  #include <sys/time.h>
  13. @@ -56,6 +57,7 @@
  14.  #include <sched.h>
  15.  #include <pthread.h>
  16.  
  17. +
  18.  #include "structs/structs.h"
  19.  #include "structs/type/array.h"
  20.  #include "util/typed_mem.h"
  21. @@ -106,6 +108,9 @@ struct pevent_ctx {
  22.         u_char                  notified;       /* data in the pipe */
  23.         u_char                  has_attr;       /* 'attr' is valid */
  24.         u_int                   refs;           /* references to this context */
  25. +
  26. +       int                     kq;             /* kernel event queue fd */
  27. +       struct kevent           *klist;         /* kqueue(2) array */
  28.  };
  29.  
  30.  /* Event object */
  31. @@ -166,6 +171,7 @@ struct pevent {
  32.                         TAILQ_REMOVE(&(ctx)->events, (ev), next);       \
  33.                         TAILQ_INSERT_HEAD(&(ctx)->events, (ev), next);  \
  34.                 }                                                       \
  35. +               DBG(PEVENT, "ev %p (occured)", (ev));                   \
  36.         } while (0)
  37.  
  38.  /* Internal functions */
  39. @@ -538,13 +544,15 @@ static void *
  40.  pevent_ctx_main(void *arg)
  41.  {
  42.         struct pevent_ctx *const ctx = arg;
  43. +       struct kevent *kevents = NULL;
  44.         struct timeval now;
  45. -       struct pollfd *fd;
  46.         struct pevent *ev;
  47.         struct pevent *next_ev;
  48.         int poll_idx;
  49.         int timeout;
  50. -       int r;
  51. +       struct timespec ktimeout;
  52. +       struct timespec *pktimeout;
  53. +       int nev;
  54.  
  55.         /* Push cleanup hook */
  56.         pthread_cleanup_push(pevent_ctx_main_cleanup, ctx);
  57. @@ -560,6 +568,13 @@ pevent_ctx_main(void *arg)
  58.         gettimeofday(&now, NULL);
  59.         DBG(PEVENT, "ctx %p thread starting", ctx);
  60.  
  61. +       /* XXX */
  62. +       ctx->kq = kqueue();
  63. +       if (ctx->kq == -1) {
  64. +               DBG(PEVENT, "ctx %p can't create kqueue", ctx);
  65. +               goto done;
  66. +       }
  67. +
  68.  loop:
  69.         /* Are there any events left? */
  70.         if (TAILQ_EMPTY(&ctx->events)) {
  71. @@ -567,18 +582,25 @@ loop:
  72.                 goto done;
  73.         }
  74.  
  75. -       /* Make sure ctx->fds array is long enough */
  76. +       /* Make sure ctx->klist and kevents arrays are long enough */
  77.         if (ctx->fds_alloc < 1 + ctx->nrwevents) {
  78.                 const u_int new_alloc = roundup(1 + ctx->nrwevents, 16);
  79.                 void *mem;
  80.  
  81. -               if ((mem = REALLOC(ctx->mtype, ctx->fds,
  82. -                   new_alloc * sizeof(*ctx->fds))) == NULL)
  83. -                       alogf(LOG_ERR, "%s: %m", "realloc");
  84. +               if ((mem = REALLOC(ctx->mtype, ctx->klist,
  85. +                   new_alloc * sizeof(*ctx->klist))) == NULL)
  86. +                       alogf(LOG_ERR, "%s: %m", "realloc ctx->klist");
  87.                 else {
  88. -                       ctx->fds = mem;
  89. +                       ctx->klist = mem;
  90.                         ctx->fds_alloc = new_alloc;
  91.                 }
  92. +
  93. +               if ((mem = REALLOC(ctx->mtype, kevents,
  94. +                   new_alloc * sizeof(*kevents))) == NULL)
  95. +                       alogf(LOG_ERR, "%s: %m", "realloc kevents");
  96. +               else {
  97. +                       kevents = mem;
  98. +               }
  99.         }
  100.  
  101.         /* If we were intentionally woken up, read the wakeup byte */
  102. @@ -588,16 +610,15 @@ loop:
  103.                 ctx->notified = 0;
  104.         }
  105.  
  106. -       /* Add event for the notify pipe */
  107. +       /* XXX Add event for notify pipe into kqueue */
  108.         poll_idx = 0;
  109.         if (ctx->fds_alloc > 0) {
  110. -               fd = &ctx->fds[poll_idx++];
  111. -               memset(fd, 0, sizeof(*fd));
  112. -               fd->fd = ctx->pipe[0];
  113. -               fd->events = POLLRDNORM;
  114. +               DBG(PEVENT, " => adding notify pipe fd=%i", ctx->pipe[0]);
  115. +               EV_SET(&ctx->klist[poll_idx++], ctx->pipe[0], EVFILT_READ,
  116. +                   EV_ADD | EV_ONESHOT, 0, 0, 0);
  117.         }
  118.  
  119. -       /* Fill in rest of poll() array */
  120. +       /* XXX Fill in rest of kqueue array */
  121.         timeout = INFTIM;
  122.         TAILQ_FOREACH(ev, &ctx->events, next) {
  123.                 switch (ev->type) {
  124. @@ -609,30 +630,26 @@ loop:
  125.                                 break;
  126.                         }
  127.                         ev->poll_idx = poll_idx++;
  128. -                       fd = &ctx->fds[ev->poll_idx];
  129. -                       memset(fd, 0, sizeof(*fd));
  130. -                       fd->fd = ev->u.fd;
  131. -                       fd->events = (ev->type == PEVENT_READ) ?
  132. -                           POLLRDNORM : POLLWRNORM;
  133. +                       DBG(PEVENT, " => adding fd=%i to ev=%p, index=%i",
  134. +                           ev->u.fd, ev, ev->poll_idx);
  135. +                       EV_SET(&ctx->klist[ev->poll_idx], ev->u.fd, (ev->type ==
  136. +                           PEVENT_READ) ? EVFILT_READ : EVFILT_WRITE, EV_ADD |
  137. +                           EV_ONESHOT, 0, 0, 0);
  138.                         break;
  139.                     }
  140.                 case PEVENT_TIME:
  141.                     {
  142.                         struct timeval remain;
  143. -                       int millis;
  144.  
  145.                         /* Compute milliseconds until event */
  146. -                       if (timercmp(&ev->when, &now, <=))
  147. -                               millis = 0;
  148. -                       else {
  149. +                       if (timercmp(&ev->when, &now, <=)) {
  150. +                               pktimeout = NULL;
  151. +                       } else {
  152.                                 timersub(&ev->when, &now, &remain);
  153. -                               millis = remain.tv_sec * 1000;
  154. -                               millis += remain.tv_usec / 1000;
  155. +                               TIMEVAL_TO_TIMESPEC(&remain, &ktimeout);
  156. +                               pktimeout = &ktimeout;
  157.                         }
  158.  
  159. -                       /* Remember the minimum delay */
  160. -                       if (timeout == INFTIM || millis < timeout)
  161. -                               timeout = millis;
  162.                         break;
  163.                     }
  164.                 default:
  165. @@ -652,7 +669,7 @@ loop:
  166.                         break;
  167.                 }
  168.                 if ((ev->flags & PEVENT_OCCURRED) != 0)
  169. -                       timeout = 0;                    /* don't delay */
  170. +                       pktimeout = NULL;
  171.         }
  172.  
  173.  #if PDEL_DEBUG
  174. @@ -665,41 +682,59 @@ loop:
  175.         /* Wait for something to happen */
  176.         MUTEX_UNLOCK(&ctx->mutex, ctx->mutex_count);
  177.         DBG(PEVENT, "ctx %p thread sleeping", ctx);
  178. -       r = poll(ctx->fds, poll_idx, timeout);
  179. +
  180. +       if (ktimeout.tv_sec == 0 && ktimeout.tv_nsec == 0)
  181. +               pktimeout = NULL;
  182. +
  183. +       DBG(PEVENT, "Total %i events will be submitted to kqueue()", poll_idx);
  184. +       nev = kevent(ctx->kq, ctx->klist, poll_idx, kevents, poll_idx, pktimeout);
  185.         DBG(PEVENT, "ctx %p thread woke up", ctx);
  186.         assert(ctx->magic == PEVENT_CTX_MAGIC);
  187.         MUTEX_LOCK(&ctx->mutex, ctx->mutex_count);
  188.  
  189. -       /* Check for errors */
  190. -       if (r == -1 && errno != EINTR) {
  191. -               alogf(LOG_CRIT, "%s: %m", "poll");
  192. +       /* XXX Check for errors */
  193. +       if (nev < 0) {
  194. +               alogf(LOG_CRIT, "%s: %m", "kqueue");
  195.                 assert(0);
  196.         }
  197.  
  198.         /* Update current time */
  199.         gettimeofday(&now, NULL);
  200.  
  201. -       /* Mark poll() events that have occurred */
  202. +       DBG(PEVENT, " => itterating over %i kqueue() events", nev);
  203. +       for (int i = 0; i < nev; i++) {
  204. +               for (ev = TAILQ_FIRST((&ctx->events)); ev != NULL; ev = next_ev) {
  205. +                       DBG(PEVENT, " => comparing %lu with %i",
  206. +                           kevents[i].ident, ev->u.fd);
  207. +                       next_ev = TAILQ_NEXT(ev, next);
  208. +                       assert(ev->magic == PEVENT_MAGIC);
  209. +                       if (kevents[i].ident == ev->u.fd) {
  210. +                               DBG(PEVENT, " => ctx %p ev %p found in kqueue()", ctx, ev);
  211. +                               switch (ev->type) {
  212. +                               case PEVENT_READ:
  213. +                               case PEVENT_WRITE:
  214. +                                       if (ev->poll_idx == -1)
  215. +                                               break;
  216. +                                       if ((ev->type == PEVENT_READ || ev->type ==
  217. +                                           PEVENT_WRITE) && kevents[i].data > 0)
  218. +                                               PEVENT_SET_OCCURRED(ctx, ev);
  219. +                                       break;
  220. +                               case PEVENT_TIME:
  221. +                                       if (timercmp(&ev->when, &now, <=))
  222. +                                               PEVENT_SET_OCCURRED(ctx, ev);
  223. +                                       break;
  224. +                               default:
  225. +                                       break;
  226. +                               }
  227. +                       }
  228. +               }
  229. +       }
  230. +
  231.         for (ev = TAILQ_FIRST((&ctx->events)); ev != NULL; ev = next_ev) {
  232.                 next_ev = TAILQ_NEXT(ev, next);
  233.                 assert(ev->magic == PEVENT_MAGIC);
  234. -               switch (ev->type) {
  235. -               case PEVENT_READ:
  236. -               case PEVENT_WRITE:
  237. -                       if (ev->poll_idx == -1)
  238. -                               break;
  239. -                       fd = &ctx->fds[ev->poll_idx];
  240. -                       if ((fd->revents & ((ev->type == PEVENT_READ) ?
  241. -                           READABLE_EVENTS : WRITABLE_EVENTS)) != 0)
  242. -                               PEVENT_SET_OCCURRED(ctx, ev);
  243. -                       break;
  244. -               case PEVENT_TIME:
  245. -                       if (timercmp(&ev->when, &now, <=))
  246. -                               PEVENT_SET_OCCURRED(ctx, ev);
  247. -                       break;
  248. -               default:
  249. -                       break;
  250. -               }
  251. +               if (ev->type == PEVENT_TIME && timercmp(&ev->when, &now, <=))
  252. +                       PEVENT_SET_OCCURRED(ctx, ev);
  253.         }
  254.  
  255.         /* Service all events that are marked as having occurred */
  256. @@ -988,6 +1023,7 @@ pevent_ctx_unref(struct pevent_ctx *ctx)
  257.         assert(ctx->thread == 0);
  258.         (void)close(ctx->pipe[0]);
  259.         (void)close(ctx->pipe[1]);
  260. +       (void)close(ctx->kq);
  261.         MUTEX_UNLOCK(&ctx->mutex, ctx->mutex_count);
  262.         pthread_mutex_destroy(&ctx->mutex);
  263.         if (ctx->has_attr)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement