Diff for /libaitsched/src/hooks.c between versions 1.5 and 1.10.2.3

version 1.5, 2012/03/13 10:01:59 version 1.10.2.3, 2012/08/01 14:27:52
Line 51  SUCH DAMAGE. Line 51  SUCH DAMAGE.
  * sched_hook_init() - Default INIT hook   * sched_hook_init() - Default INIT hook
  *   *
  * @root = root task   * @root = root task
 * @data = optional data if !=NULL * @arg = unused
  * return: <0 errors and 0 ok   * return: <0 errors and 0 ok
  */   */
 void *  void *
sched_hook_init(void *root, void *data)sched_hook_init(void *root, void *arg __unused)
 {  {
         sched_root_task_t *r = root;          sched_root_task_t *r = root;
   
        if (!r || r->root_data.iov_base || r->root_data.iov_len)        if (!r)
                 return (void*) -1;                  return (void*) -1;
   
         r->root_data.iov_base = malloc(sizeof(struct sched_IO));  
         if (!r->root_data.iov_base) {  
                 LOGERR;  
                 return (void*) -1;  
         } else {  
                 r->root_data.iov_len = sizeof(struct sched_IO);  
                 memset(r->root_data.iov_base, 0, r->root_data.iov_len);  
         }  
   
         r->root_kq = kqueue();          r->root_kq = kqueue();
         if (r->root_kq == -1) {          if (r->root_kq == -1) {
                 LOGERR;                  LOGERR;
Line 100  sched_hook_fini(void *root, void *arg __unused) Line 91  sched_hook_fini(void *root, void *arg __unused)
                 r->root_kq = 0;                  r->root_kq = 0;
         }          }
   
         if (r->root_data.iov_base && r->root_data.iov_len) {  
                 free(r->root_data.iov_base);  
                 r->root_data.iov_base = NULL;  
                 r->root_data.iov_len = 0;  
         }  
   
         return NULL;          return NULL;
 }  }
   
Line 119  sched_hook_fini(void *root, void *arg __unused) Line 104  sched_hook_fini(void *root, void *arg __unused)
 void *  void *
 sched_hook_cancel(void *task, void *arg __unused)  sched_hook_cancel(void *task, void *arg __unused)
 {  {
         struct sched_IO *io;  
         sched_task_t *t = task;          sched_task_t *t = task;
         struct kevent chg[1];          struct kevent chg[1];
         struct timespec timeout = { 0, 0 };          struct timespec timeout = { 0, 0 };
   #ifdef EVFILT_AIO
           struct aiocb *acb;
   #endif
   
        if (!t || !TASK_ROOT(t) || !ROOT_DATA(t->task_root) || !ROOT_DATLEN(t->task_root))        if (!t || !TASK_ROOT(t))
                 return (void*) -1;                  return (void*) -1;
         else  
                 io = ROOT_DATA(t->task_root);  
   
         switch (TASK_TYPE(t)) {          switch (TASK_TYPE(t)) {
                 case taskREAD:                  case taskREAD:
Line 136  sched_hook_cancel(void *task, void *arg __unused) Line 121  sched_hook_cancel(void *task, void *arg __unused)
 #else  #else
                         EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_DELETE, 0, 0, (void*) TASK_FD(t));                          EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_DELETE, 0, 0, (void*) TASK_FD(t));
 #endif  #endif
                         kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout);  
                         FD_CLR(TASK_FD(t), &io->rfd);  
                         break;                          break;
                 case taskWRITE:                  case taskWRITE:
 #ifdef __NetBSD__  #ifdef __NetBSD__
Line 145  sched_hook_cancel(void *task, void *arg __unused) Line 128  sched_hook_cancel(void *task, void *arg __unused)
 #else  #else
                         EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_DELETE, 0, 0, (void*) TASK_FD(t));                          EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_DELETE, 0, 0, (void*) TASK_FD(t));
 #endif  #endif
                         kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout);  
                         FD_CLR(TASK_FD(t), &io->wfd);  
                         break;                          break;
                default:                case taskALARM:
 #ifdef __NetBSD__
                         EV_SET(&chg[0], (uintptr_t) TASK_DATA(t), EVFILT_TIMER, EV_DELETE, 
                                         0, 0, (intptr_t) TASK_DATA(t));
 #else
                         EV_SET(&chg[0], (uintptr_t) TASK_DATA(t), EVFILT_TIMER, EV_DELETE, 
                                         0, 0, (void*) TASK_DATA(t));
 #endif
                         break;                          break;
                   case taskNODE:
   #ifdef __NetBSD__
                           EV_SET(&chg[0], TASK_FD(t), EVFILT_VNODE, EV_DELETE, 0, 0, (intptr_t) TASK_FD(t));
   #else
                           EV_SET(&chg[0], TASK_FD(t), EVFILT_VNODE, EV_DELETE, 0, 0, (void*) TASK_FD(t));
   #endif
                           break;
                   case taskPROC:
   #ifdef __NetBSD__
                           EV_SET(&chg[0], TASK_VAL(t), EVFILT_PROC, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t));
   #else
                           EV_SET(&chg[0], TASK_VAL(t), EVFILT_PROC, EV_DELETE, 0, 0, (void*) TASK_VAL(t));
   #endif
                           break;
                   case taskSIGNAL:
   #ifdef __NetBSD__
                           EV_SET(&chg[0], TASK_VAL(t), EVFILT_SIGNAL, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t));
   #else
                           EV_SET(&chg[0], TASK_VAL(t), EVFILT_SIGNAL, EV_DELETE, 0, 0, (void*) TASK_VAL(t));
   #endif
                           break;
   #ifdef EVFILT_AIO
                   case taskAIO:
   #ifdef __NetBSD__
                           EV_SET(&chg[0], TASK_VAL(t), EVFILT_AIO, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t));
   #else
                           EV_SET(&chg[0], TASK_VAL(t), EVFILT_AIO, EV_DELETE, 0, 0, (void*) TASK_VAL(t));
   #endif
                           acb = (struct aiocb*) TASK_VAL(t);
                           if (acb) {
                                   aio_cancel(acb->aio_fildes, acb);
                                   free(acb);
                                   TASK_VAL(t) = 0;
                           }
                           break;
   #endif
   #ifdef EVFILT_USER
                   case taskUSER:
   #ifdef __NetBSD__
                           EV_SET(&chg[0], TASK_VAL(t), EVFILT_USER, EV_DELETE, 0, 0, (intptr_t) TASK_VAL(t));
   #else
                           EV_SET(&chg[0], TASK_VAL(t), EVFILT_USER, EV_DELETE, 0, 0, (void*) TASK_VAL(t));
   #endif
                           break;
   #endif
                   default:
                           return NULL;
         }          }
   
           kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout);
         return NULL;          return NULL;
 }  }
   
Line 165  sched_hook_cancel(void *task, void *arg __unused) Line 201  sched_hook_cancel(void *task, void *arg __unused)
 void *  void *
 sched_hook_read(void *task, void *arg __unused)  sched_hook_read(void *task, void *arg __unused)
 {  {
         struct sched_IO *io;  
         sched_task_t *t = task;          sched_task_t *t = task;
         struct kevent chg[1];          struct kevent chg[1];
         struct timespec timeout = { 0, 0 };          struct timespec timeout = { 0, 0 };
   
        if (!t || !TASK_ROOT(t) || !ROOT_DATA(t->task_root) || !ROOT_DATLEN(t->task_root))        if (!t || !TASK_ROOT(t))
                 return (void*) -1;                  return (void*) -1;
         else  
                 io = ROOT_DATA(t->task_root);  
   
         if (FD_ISSET(TASK_FD(t), &io->rfd))  
                 return NULL;  
         else  
                 FD_SET(TASK_FD(t), &io->rfd);  
   
 #ifdef __NetBSD__  #ifdef __NetBSD__
        EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_ADD, 0, 0, (intptr_t) TASK_FD(t));        EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, (intptr_t) TASK_FD(t));
 #else  #else
        EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_ADD, 0, 0, (void*) TASK_FD(t));        EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, (void*) TASK_FD(t));
 #endif  #endif
         if (kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout) == -1) {          if (kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout) == -1) {
                 if (TASK_ROOT(t)->root_hooks.hook_exec.exception)                  if (TASK_ROOT(t)->root_hooks.hook_exec.exception)
Line 206  sched_hook_read(void *task, void *arg __unused) Line 234  sched_hook_read(void *task, void *arg __unused)
 void *  void *
 sched_hook_write(void *task, void *arg __unused)  sched_hook_write(void *task, void *arg __unused)
 {  {
         struct sched_IO *io;  
         sched_task_t *t = task;          sched_task_t *t = task;
         struct kevent chg[1];          struct kevent chg[1];
         struct timespec timeout = { 0, 0 };          struct timespec timeout = { 0, 0 };
   
        if (!t || !TASK_ROOT(t) || !ROOT_DATA(t->task_root) || !ROOT_DATLEN(t->task_root))        if (!t || !TASK_ROOT(t))
                 return (void*) -1;                  return (void*) -1;
         else  
                 io = ROOT_DATA(t->task_root);  
   
        if (FD_ISSET(TASK_FD(t), &io->wfd))#ifdef __NetBSD__
                return NULL;        EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, (intptr_t) TASK_FD(t));
        else#else
                FD_SET(TASK_FD(t), &io->wfd);        EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, (void*) TASK_FD(t));
 #endif
         if (kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout) == -1) {
                 if (TASK_ROOT(t)->root_hooks.hook_exec.exception)
                         TASK_ROOT(t)->root_hooks.hook_exec.exception(TASK_ROOT(t), NULL);
                 else
                         LOGERR;
                 return (void*) -1;
         }
   
           return NULL;
   }
   
   /*
    * sched_hook_alarm() - Default ALARM hook
    *
    * @task = current task
    * @arg = unused
    * return: <0 errors and 0 ok
    */
   void *
   sched_hook_alarm(void *task, void *arg __unused)
   {
           sched_task_t *t = task;
           struct kevent chg[1];
           struct timespec timeout = { 0, 0 };
   
           if (!t || !TASK_ROOT(t))
                   return (void*) -1;
   
 #ifdef __NetBSD__  #ifdef __NetBSD__
        EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_ADD, 0, 0, (intptr_t) TASK_FD(t));        EV_SET(&chg[0], (uintptr_t) TASK_DATA(t), EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 
                         t->task_val.ts.tv_sec * 1000 + t->task_val.ts.tv_nsec / 1000000, 
                         (intptr_t) TASK_DATA(t));
 #else  #else
        EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_ADD, 0, 0, (void*) TASK_FD(t));        EV_SET(&chg[0], (uintptr_t) TASK_DATA(t), EVFILT_TIMER, EV_ADD | EV_ONESHOT, 0, 
                         t->task_val.ts.tv_sec * 1000 + t->task_val.ts.tv_nsec / 1000000, 
                         (void*) TASK_DATA(t));
 #endif  #endif
         if (kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout) == -1) {          if (kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout) == -1) {
                 if (TASK_ROOT(t)->root_hooks.hook_exec.exception)                  if (TASK_ROOT(t)->root_hooks.hook_exec.exception)
Line 238  sched_hook_write(void *task, void *arg __unused) Line 295  sched_hook_write(void *task, void *arg __unused)
 }  }
   
 /*  /*
    * sched_hook_node() - Default NODE hook
    *
    * @task = current task
    * @arg = unused
    * return: <0 errors and 0 ok
    */
   void *
   sched_hook_node(void *task, void *arg __unused)
   {
           sched_task_t *t = task;
           struct kevent chg[1];
           struct timespec timeout = { 0, 0 };
   
           if (!t || !TASK_ROOT(t))
                   return (void*) -1;
   
   #ifdef __NetBSD__
           EV_SET(&chg[0], TASK_FD(t), EVFILT_VNODE, EV_ADD | EV_CLEAR, 
                           NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | 
                           NOTE_LINK | NOTE_RENAME | NOTE_REVOKE, 0, (intptr_t) TASK_FD(t));
   #else
           EV_SET(&chg[0], TASK_FD(t), EVFILT_VNODE, EV_ADD | EV_CLEAR, 
                           NOTE_DELETE | NOTE_WRITE | NOTE_EXTEND | NOTE_ATTRIB | 
                           NOTE_LINK | NOTE_RENAME | NOTE_REVOKE, 0, (void*) TASK_FD(t));
   #endif
           if (kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout) == -1) {
                   if (TASK_ROOT(t)->root_hooks.hook_exec.exception)
                           TASK_ROOT(t)->root_hooks.hook_exec.exception(TASK_ROOT(t), NULL);
                   else
                           LOGERR;
                   return (void*) -1;
           }
   
           return NULL;
   }
   
   /*
    * sched_hook_proc() - Default PROC hook
    *
    * @task = current task
    * @arg = unused
    * return: <0 errors and 0 ok
    */
   void *
   sched_hook_proc(void *task, void *arg __unused)
   {
           sched_task_t *t = task;
           struct kevent chg[1];
           struct timespec timeout = { 0, 0 };
   
           if (!t || !TASK_ROOT(t))
                   return (void*) -1;
   
   #ifdef __NetBSD__
           EV_SET(&chg[0], TASK_VAL(t), EVFILT_PROC, EV_ADD | EV_CLEAR, 
                           NOTE_EXIT | NOTE_FORK | NOTE_EXEC | NOTE_TRACK, 0, (intptr_t) TASK_VAL(t));
   #else
           EV_SET(&chg[0], TASK_VAL(t), EVFILT_PROC, EV_ADD | EV_CLEAR, 
                           NOTE_EXIT | NOTE_FORK | NOTE_EXEC | NOTE_TRACK, 0, (void*) TASK_VAL(t));
   #endif
           if (kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout) == -1) {
                   if (TASK_ROOT(t)->root_hooks.hook_exec.exception)
                           TASK_ROOT(t)->root_hooks.hook_exec.exception(TASK_ROOT(t), NULL);
                   else
                           LOGERR;
                   return (void*) -1;
           }
   
           return NULL;
   }
   
   /*
    * sched_hook_signal() - Default SIGNAL hook
    *
    * @task = current task
    * @arg = unused
    * return: <0 errors and 0 ok
    */
   void *
   sched_hook_signal(void *task, void *arg __unused)
   {
           sched_task_t *t = task;
           struct kevent chg[1];
           struct timespec timeout = { 0, 0 };
   
           if (!t || !TASK_ROOT(t))
                   return (void*) -1;
   
   #ifdef __NetBSD__
           EV_SET(&chg[0], TASK_VAL(t), EVFILT_SIGNAL, EV_ADD, 0, 0, (intptr_t) TASK_VAL(t));
   #else
           EV_SET(&chg[0], TASK_VAL(t), EVFILT_SIGNAL, EV_ADD, 0, 0, (void*) TASK_VAL(t));
   #endif
           if (kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout) == -1) {
                   if (TASK_ROOT(t)->root_hooks.hook_exec.exception)
                           TASK_ROOT(t)->root_hooks.hook_exec.exception(TASK_ROOT(t), NULL);
                   else
                           LOGERR;
                   return (void*) -1;
           }
   
           return NULL;
   }
   
   /*
    * sched_hook_user() - Default USER hook
    *
    * @task = current task
    * @arg = unused
    * return: <0 errors and 0 ok
    */
   #ifdef EVFILT_USER
   void *
   sched_hook_user(void *task, void *arg __unused)
   {
           sched_task_t *t = task;
           struct kevent chg[1];
           struct timespec timeout = { 0, 0 };
   
           if (!t || !TASK_ROOT(t))
                   return (void*) -1;
   
   #ifdef __NetBSD__
           EV_SET(&chg[0], TASK_VAL(t), EVFILT_USER, EV_ADD | EV_CLEAR, TASK_DATLEN(t), 
                           0, (intptr_t) TASK_VAL(t));
   #else
           EV_SET(&chg[0], TASK_VAL(t), EVFILT_USER, EV_ADD | EV_CLEAR, TASK_DATLEN(t), 
                           0, (void*) TASK_VAL(t));
   #endif
           if (kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout) == -1) {
                   if (TASK_ROOT(t)->root_hooks.hook_exec.exception)
                           TASK_ROOT(t)->root_hooks.hook_exec.exception(TASK_ROOT(t), NULL);
                   else
                           LOGERR;
                   return (void*) -1;
           }
   
           return NULL;
   }
   #endif
   
   /*
  * sched_hook_fetch() - Default FETCH hook   * sched_hook_fetch() - Default FETCH hook
  *   *
  * @root = root task   * @root = root task
Line 247  sched_hook_write(void *task, void *arg __unused) Line 446  sched_hook_write(void *task, void *arg __unused)
 void *  void *
 sched_hook_fetch(void *root, void *arg __unused)  sched_hook_fetch(void *root, void *arg __unused)
 {  {
         struct sched_IO *io;  
         sched_root_task_t *r = root;          sched_root_task_t *r = root;
        sched_task_t *task;        sched_task_t *task, *tmp;
         struct timespec now, m, mtmp;          struct timespec now, m, mtmp;
         struct timespec *timeout;          struct timespec *timeout;
         struct kevent evt[1], res[KQ_EVENTS];          struct kevent evt[1], res[KQ_EVENTS];
        register int i;        register int i, flg;
         int en;          int en;
   #ifdef EVFILT_AIO
           struct aiocb *acb;
   #endif
   
        if (!r || !ROOT_DATA(r) || !ROOT_DATLEN(r))        if (!r)
                 return NULL;                  return NULL;
   
         /* get new task by queue priority */          /* get new task by queue priority */
 retry:  
         while ((task = TAILQ_FIRST(&r->root_event))) {          while ((task = TAILQ_FIRST(&r->root_event))) {
 #ifdef HAVE_LIBPTHREAD  #ifdef HAVE_LIBPTHREAD
                 pthread_mutex_lock(&r->root_mtx[taskEVENT]);                  pthread_mutex_lock(&r->root_mtx[taskEVENT]);
Line 343  retry: Line 543  retry:
                 if (r->root_hooks.hook_exec.exception) {                  if (r->root_hooks.hook_exec.exception) {
                         if (r->root_hooks.hook_exec.exception(r, NULL))                          if (r->root_hooks.hook_exec.exception(r, NULL))
                                 return NULL;                                  return NULL;
                } else                } else if (errno != EINTR)
                         LOGERR;                          LOGERR;
 #ifdef NDEBUG  
                 /* kevent no exit by error, if non-debug version */  
                 goto retry;  
 #else  
                 /* diagnostic exit from scheduler if kevent error occur */  
                 return NULL;                  return NULL;
 #endif  
         }          }
   
         now.tv_sec = now.tv_nsec = 0;          now.tv_sec = now.tv_nsec = 0;
Line 362  retry: Line 556  retry:
                 /* Put read/write task to ready queue */                  /* Put read/write task to ready queue */
                 switch (res[i].filter) {                  switch (res[i].filter) {
                         case EVFILT_READ:                          case EVFILT_READ:
                                TAILQ_FOREACH(task, &r->root_read, task_node) {                                flg = 0;
                                 TAILQ_FOREACH_SAFE(task, &r->root_read, task_node, tmp) {
                                         if (TASK_FD(task) != ((intptr_t) res[i].udata))                                          if (TASK_FD(task) != ((intptr_t) res[i].udata))
                                                 continue;                                                  continue;
                                           else
                                                   flg++;
                                         /* remove read handle */                                          /* remove read handle */
                                         io = ROOT_DATA(task->task_root);  
                                         FD_CLR(TASK_FD(task), &io->rfd);  
   
 #ifdef HAVE_LIBPTHREAD  #ifdef HAVE_LIBPTHREAD
                                         pthread_mutex_lock(&r->root_mtx[taskREAD]);                                          pthread_mutex_lock(&r->root_mtx[taskREAD]);
 #endif  #endif
Line 406  retry: Line 600  retry:
                                                 pthread_mutex_unlock(&r->root_mtx[taskREADY]);                                                  pthread_mutex_unlock(&r->root_mtx[taskREADY]);
 #endif  #endif
                                         }                                          }
                                         break;  
                                 }                                  }
                                   /* if match at least 2, don't remove resouce of event */
                                   if (flg > 1)
                                           evt->flags ^= evt->flags;
                                 break;                                  break;
                         case EVFILT_WRITE:                          case EVFILT_WRITE:
                                TAILQ_FOREACH(task, &r->root_write, task_node) {                                flg = 0;
                                 TAILQ_FOREACH_SAFE(task, &r->root_write, task_node, tmp) {
                                         if (TASK_FD(task) != ((intptr_t) res[i].udata))                                          if (TASK_FD(task) != ((intptr_t) res[i].udata))
                                                 continue;                                                  continue;
                                           else
                                                   flg++;
                                         /* remove write handle */                                          /* remove write handle */
                                         io = ROOT_DATA(task->task_root);  
                                         FD_CLR(TASK_FD(task), &io->wfd);  
   
 #ifdef HAVE_LIBPTHREAD  #ifdef HAVE_LIBPTHREAD
                                         pthread_mutex_lock(&r->root_mtx[taskWRITE]);                                          pthread_mutex_lock(&r->root_mtx[taskWRITE]);
 #endif  #endif
Line 454  retry: Line 650  retry:
                                                 pthread_mutex_unlock(&r->root_mtx[taskREADY]);                                                  pthread_mutex_unlock(&r->root_mtx[taskREADY]);
 #endif  #endif
                                         }                                          }
                                         break;  
                                 }                                  }
                                   /* if match at least 2, don't remove resouce of event */
                                   if (flg > 1)
                                           evt->flags ^= evt->flags;
                                 break;                                  break;
                           case EVFILT_TIMER:
                                   flg = 0;
                                   TAILQ_FOREACH_SAFE(task, &r->root_alarm, task_node, tmp) {
                                           if ((uintptr_t) TASK_DATA(task) != ((uintptr_t) res[i].udata))
                                                   continue;
                                           else
                                                   flg++;
                                           /* remove alarm handle */
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_lock(&r->root_mtx[taskALARM]);
   #endif
                                           TAILQ_REMOVE(&r->root_alarm, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_unlock(&r->root_mtx[taskALARM]);
   #endif
                                           task->task_type = taskREADY;
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_lock(&r->root_mtx[taskREADY]);
   #endif
                                           TAILQ_INSERT_TAIL(&r->root_ready, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_unlock(&r->root_mtx[taskREADY]);
   #endif
                                   }
                                   /* if match at least 2, don't remove resouce of event */
                                   if (flg > 1)
                                           evt->flags ^= evt->flags;
                                   break;
                           case EVFILT_VNODE:
                                   flg = 0;
                                   TAILQ_FOREACH_SAFE(task, &r->root_node, task_node, tmp) {
                                           if (TASK_FD(task) != ((intptr_t) res[i].udata))
                                                   continue;
                                           else {
                                                   flg++;
                                                   TASK_DATA(task) = (void*) (uintptr_t) res[i].data;
                                                   TASK_DATLEN(task) = res[i].fflags;
                                           }
                                           /* remove node handle */
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_lock(&r->root_mtx[taskNODE]);
   #endif
                                           TAILQ_REMOVE(&r->root_node, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_unlock(&r->root_mtx[taskNODE]);
   #endif
                                           task->task_type = taskREADY;
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_lock(&r->root_mtx[taskREADY]);
   #endif
                                           TAILQ_INSERT_TAIL(&r->root_ready, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_unlock(&r->root_mtx[taskREADY]);
   #endif
                                   }
                                   /* if match at least 2, don't remove resouce of event */
                                   if (flg > 1)
                                           evt->flags ^= evt->flags;
                                   break;
                           case EVFILT_PROC:
                                   flg = 0;
                                   TAILQ_FOREACH_SAFE(task, &r->root_proc, task_node, tmp) {
                                           if (TASK_VAL(task) != ((uintptr_t) res[i].udata))
                                                   continue;
                                           else {
                                                   flg++;
                                                   TASK_DATA(task) = (void*) (uintptr_t) res[i].data;
                                                   TASK_DATLEN(task) = res[i].fflags;
                                           }
                                           /* remove proc handle */
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_lock(&r->root_mtx[taskPROC]);
   #endif
                                           TAILQ_REMOVE(&r->root_proc, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_unlock(&r->root_mtx[taskPROC]);
   #endif
                                           task->task_type = taskREADY;
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_lock(&r->root_mtx[taskREADY]);
   #endif
                                           TAILQ_INSERT_TAIL(&r->root_ready, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_unlock(&r->root_mtx[taskREADY]);
   #endif
                                   }
                                   /* if match at least 2, don't remove resouce of event */
                                   if (flg > 1)
                                           evt->flags ^= evt->flags;
                                   break;
                           case EVFILT_SIGNAL:
                                   flg = 0;
                                   TAILQ_FOREACH_SAFE(task, &r->root_signal, task_node, tmp) {
                                           if (TASK_VAL(task) != ((uintptr_t) res[i].udata))
                                                   continue;
                                           else
                                                   flg++;
                                           /* remove signal handle */
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_lock(&r->root_mtx[taskSIGNAL]);
   #endif
                                           TAILQ_REMOVE(&r->root_signal, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_unlock(&r->root_mtx[taskSIGNAL]);
   #endif
                                           task->task_type = taskREADY;
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_lock(&r->root_mtx[taskREADY]);
   #endif
                                           TAILQ_INSERT_TAIL(&r->root_ready, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_unlock(&r->root_mtx[taskREADY]);
   #endif
                                   }
                                   /* if match at least 2, don't remove resouce of event */
                                   if (flg > 1)
                                           evt->flags ^= evt->flags;
                                   break;
   #ifdef EVFILT_AIO
                           case EVFILT_AIO:
                                   flg = 0;
                                   acb = (struct aiocb*) TASK_VAL(task);
                                   TAILQ_FOREACH_SAFE(task, &r->root_aio, task_node, tmp) {
                                           if (acb != ((struct aiocb*) res[i].ident) || 
                                                           acb->aio_sigevent.sigev_value.sival_ptr != res[i].udata)
                                                   continue;
                                           else
                                                   flg++;
                                           /* remove user handle */
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_lock(&r->root_mtx[taskAIO]);
   #endif
                                           TAILQ_REMOVE(&r->root_aio, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_unlock(&r->root_mtx[taskAIO]);
   #endif
                                           task->task_type = taskREADY;
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_lock(&r->root_mtx[taskREADY]);
   #endif
                                           TAILQ_INSERT_TAIL(&r->root_ready, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_unlock(&r->root_mtx[taskREADY]);
   #endif
                                   }
                                   /* if match at least 2, don't remove resouce of event */
                                   if (flg > 1)
                                           evt->flags ^= evt->flags;
                                   break;
   #endif  /* EVFILT_AIO */
   #ifdef EVFILT_USER
                           case EVFILT_USER:
                                   flg = 0;
                                   TAILQ_FOREACH_SAFE(task, &r->root_user, task_node, tmp) {
                                           if (TASK_VAL(task) != ((uintptr_t) res[i].udata))
                                                   continue;
                                           else {
                                                   flg++;
                                                   TASK_DATA(task) = (void*) res[i].data;
                                                   TASK_DATLEN(task) = res[i].fflags;
                                           }
                                           /* remove user handle */
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_lock(&r->root_mtx[taskUSER]);
   #endif
                                           TAILQ_REMOVE(&r->root_user, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_unlock(&r->root_mtx[taskUSER]);
   #endif
                                           task->task_type = taskREADY;
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_lock(&r->root_mtx[taskREADY]);
   #endif
                                           TAILQ_INSERT_TAIL(&r->root_ready, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_unlock(&r->root_mtx[taskREADY]);
   #endif
                                   }
                                   /* if match at least 2, don't remove resouce of event */
                                   if (flg > 1)
                                           evt->flags ^= evt->flags;
                                   break;
   #endif  /* EVFILT_USER */
                 }                  }
                 if (kevent(r->root_kq, evt, 1, NULL, 0, &now) == -1) {                  if (kevent(r->root_kq, evt, 1, NULL, 0, &now) == -1) {
                         if (r->root_hooks.hook_exec.exception) {                          if (r->root_hooks.hook_exec.exception) {
Line 470  retry: Line 851  retry:
         /* timer update & put in ready queue */          /* timer update & put in ready queue */
         clock_gettime(CLOCK_MONOTONIC, &now);          clock_gettime(CLOCK_MONOTONIC, &now);
   
        TAILQ_FOREACH(task, &r->root_timer, task_node)        TAILQ_FOREACH_SAFE(task, &r->root_timer, task_node, tmp)
                 if (sched_timespeccmp(&now, &TASK_TS(task), -) >= 0) {                  if (sched_timespeccmp(&now, &TASK_TS(task), -) >= 0) {
 #ifdef HAVE_LIBPTHREAD  #ifdef HAVE_LIBPTHREAD
                         pthread_mutex_lock(&r->root_mtx[taskTIMER]);                          pthread_mutex_lock(&r->root_mtx[taskTIMER]);
Line 516  retry: Line 897  retry:
                 r->root_eventlo_miss = 0;                  r->root_eventlo_miss = 0;
   
         /* OK, lets get ready task !!! */          /* OK, lets get ready task !!! */
        if (!(task = TAILQ_FIRST(&r->root_ready)))        task = TAILQ_FIRST(&r->root_ready);
                goto retry;        if (!(task))
                 return NULL;
 
 #ifdef HAVE_LIBPTHREAD  #ifdef HAVE_LIBPTHREAD
         pthread_mutex_lock(&r->root_mtx[taskREADY]);          pthread_mutex_lock(&r->root_mtx[taskREADY]);
 #endif  #endif
Line 548  sched_hook_exception(void *root, void *arg) Line 931  sched_hook_exception(void *root, void *arg)
 {  {
         sched_root_task_t *r = root;          sched_root_task_t *r = root;
   
        if (!r || !ROOT_DATA(r) || !ROOT_DATLEN(r))        if (!r)
                 return NULL;                  return NULL;
   
         /* custom exception handling ... */          /* custom exception handling ... */
Line 579  sched_hook_condition(void *root, void *arg) Line 962  sched_hook_condition(void *root, void *arg)
 {  {
         sched_root_task_t *r = root;          sched_root_task_t *r = root;
   
        if (!r || !ROOT_DATA(r) || !ROOT_DATLEN(r))        if (!r)
                 return NULL;                  return NULL;
   
         return (void*) (r->root_cond - *(intptr_t*) arg);          return (void*) (r->root_cond - *(intptr_t*) arg);

Removed from v.1.5  
changed lines
  Added in v.1.10.2.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>