Diff for /libaitsched/src/hooks.c between versions 1.1.1.1 and 1.3.4.3

version 1.1.1.1, 2011/08/05 15:52:00 version 1.3.4.3, 2012/01/24 14:51:03
Line 119  sched_hook_cancel(void *task, void *arg __unused) Line 119  sched_hook_cancel(void *task, void *arg __unused)
         struct sched_IO *io;          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;        struct timespec timeout = { 0, 0 };
   
        if (!t || !t->task_root || !ROOT_DATA(t->task_root) || !ROOT_DATLEN(t->task_root))        if (!t || !TASK_ROOT(t) || !ROOT_DATA(t->task_root) || !ROOT_DATLEN(t->task_root))
                 return (void*) -1;                  return (void*) -1;
         else          else
                 io = ROOT_DATA(t->task_root);                  io = ROOT_DATA(t->task_root);
   
        timespecclear(&timeout);        switch (TASK_TYPE(t)) {
        switch (t->task_type) { 
                 case taskREAD:                  case taskREAD:
                        if (FD_ISSET(TASK_FD(t), &io->wfd))#ifdef __NetBSD__
                                EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_ADD, 0, 0, &TASK_FD(t));                        EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_DELETE, 0, 0, (intptr_t) TASK_FD(t));
                        else#else
                                EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_DELETE, 0, 0, &TASK_FD(t));                        EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_DELETE, 0, 0, (void*) TASK_FD(t));
                        kevent(t->task_root->root_kq, chg, 1, NULL, 0, &timeout);#endif
                        kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout);
                         FD_CLR(TASK_FD(t), &io->rfd);                          FD_CLR(TASK_FD(t), &io->rfd);
                         break;                          break;
                 case taskWRITE:                  case taskWRITE:
                        if (FD_ISSET(TASK_FD(t), &io->rfd))#ifdef __NetBSD__
                                EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_ADD, 0, 0, &TASK_FD(t));                        EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_DELETE, 0, 0, (intptr_t) TASK_FD(t));
                        else#else
                                EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_DELETE, 0, 0, &TASK_FD(t));                        EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_DELETE, 0, 0, (void*) TASK_FD(t));
                        kevent(t->task_root->root_kq, chg, 1, NULL, 0, &timeout);#endif
                        kevent(TASK_ROOT(t)->root_kq, chg, 1, NULL, 0, &timeout);
                         FD_CLR(TASK_FD(t), &io->wfd);                          FD_CLR(TASK_FD(t), &io->wfd);
                         break;                          break;
                 default:                  default:
Line 165  sched_hook_read(void *task, void *arg __unused) Line 164  sched_hook_read(void *task, void *arg __unused)
         struct sched_IO *io;          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;        struct timespec timeout = { 0, 0 };
   
        if (!t || !t->task_root || !ROOT_DATA(t->task_root) || !ROOT_DATLEN(t->task_root))        if (!t || !TASK_ROOT(t) || !ROOT_DATA(t->task_root) || !ROOT_DATLEN(t->task_root))
                 return (void*) -1;                  return (void*) -1;
         else          else
                 io = ROOT_DATA(t->task_root);                  io = ROOT_DATA(t->task_root);
Line 177  sched_hook_read(void *task, void *arg __unused) Line 176  sched_hook_read(void *task, void *arg __unused)
         else          else
                 FD_SET(TASK_FD(t), &io->rfd);                  FD_SET(TASK_FD(t), &io->rfd);
   
        timespecclear(&timeout);#ifdef __NetBSD__
        EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_ADD, 0, 0, &TASK_FD(t));        EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_ADD, 0, 0, (intptr_t) TASK_FD(t));
        if (kevent(t->task_root->root_kq, chg, 1, NULL, 0, &timeout) == -1) {#else
                LOGERR;        EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_ADD, 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 (void*) -1;
         }          }
   
Line 199  sched_hook_write(void *task, void *arg __unused) Line 204  sched_hook_write(void *task, void *arg __unused)
         struct sched_IO *io;          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;        struct timespec timeout = { 0, 0 };
   
        if (!t || !t->task_root || !ROOT_DATA(t->task_root) || !ROOT_DATLEN(t->task_root))        if (!t || !TASK_ROOT(t) || !ROOT_DATA(t->task_root) || !ROOT_DATLEN(t->task_root))
                 return (void*) -1;                  return (void*) -1;
         else          else
                 io = ROOT_DATA(t->task_root);                  io = ROOT_DATA(t->task_root);
Line 211  sched_hook_write(void *task, void *arg __unused) Line 216  sched_hook_write(void *task, void *arg __unused)
         else          else
                 FD_SET(TASK_FD(t), &io->wfd);                  FD_SET(TASK_FD(t), &io->wfd);
   
        timespecclear(&timeout);#ifdef __NetBSD__
        EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_ADD, 0, 0, &TASK_FD(t));        EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_ADD, 0, 0, (intptr_t) TASK_FD(t));
        if (kevent(t->task_root->root_kq, chg, 1, NULL, 0, &timeout) == -1) {#else
                LOGERR;        EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_ADD, 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 (void*) -1;
         }          }
   
Line 233  sched_hook_fetch(void *root, void *arg __unused) Line 244  sched_hook_fetch(void *root, void *arg __unused)
         struct sched_IO *io;          struct sched_IO *io;
         sched_root_task_t *r = root;          sched_root_task_t *r = root;
         sched_task_t *task;          sched_task_t *task;
        struct timeval now, m, mtmp;        struct timespec now, m, mtmp;
        struct timespec nw, *timeout;        struct timespec *timeout;
         struct kevent evt[1], res[KQ_EVENTS];          struct kevent evt[1], res[KQ_EVENTS];
         register int i;          register int i;
         int en;          int en;
Line 245  sched_hook_fetch(void *root, void *arg __unused) Line 256  sched_hook_fetch(void *root, void *arg __unused)
         /* get new task by queue priority */          /* get new task by queue priority */
 retry:  retry:
         while ((task = TAILQ_FIRST(&r->root_event))) {          while ((task = TAILQ_FIRST(&r->root_event))) {
   #ifdef HAVE_LIBPTHREAD
                   pthread_mutex_lock(&r->root_mtx[taskEVENT]);
   #endif
                 TAILQ_REMOVE(&r->root_event, task, task_node);                  TAILQ_REMOVE(&r->root_event, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                   pthread_mutex_unlock(&r->root_mtx[taskEVENT]);
   #endif
                 task->task_type = taskUNUSE;                  task->task_type = taskUNUSE;
   #ifdef HAVE_LIBPTHREAD
                   pthread_mutex_lock(&r->root_mtx[taskUNUSE]);
   #endif
                 TAILQ_INSERT_TAIL(&r->root_unuse, task, task_node);                  TAILQ_INSERT_TAIL(&r->root_unuse, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                   pthread_mutex_unlock(&r->root_mtx[taskUNUSE]);
   #endif
                 return task;                  return task;
         }          }
         while ((task = TAILQ_FIRST(&r->root_ready))) {          while ((task = TAILQ_FIRST(&r->root_ready))) {
   #ifdef HAVE_LIBPTHREAD
                   pthread_mutex_lock(&r->root_mtx[taskREADY]);
   #endif
                 TAILQ_REMOVE(&r->root_ready, task, task_node);                  TAILQ_REMOVE(&r->root_ready, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                   pthread_mutex_unlock(&r->root_mtx[taskREADY]);
   #endif
                 task->task_type = taskUNUSE;                  task->task_type = taskUNUSE;
   #ifdef HAVE_LIBPTHREAD
                   pthread_mutex_lock(&r->root_mtx[taskUNUSE]);
   #endif
                 TAILQ_INSERT_TAIL(&r->root_unuse, task, task_node);                  TAILQ_INSERT_TAIL(&r->root_unuse, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                   pthread_mutex_unlock(&r->root_mtx[taskUNUSE]);
   #endif
                 return task;                  return task;
         }          }
   
 #ifdef TIMER_WITHOUT_SORT  #ifdef TIMER_WITHOUT_SORT
        clock_gettime(CLOCK_MONOTONIC, &nw);        clock_gettime(CLOCK_MONOTONIC, &now);
        now.tv_sec = nw.tv_sec; 
        now.tv_usec = nw.tv_nsec / 1000; 
   
        timerclear(&r->root_wait);        timespecclear(&r->root_wait);
         TAILQ_FOREACH(task, &r->root_timer, task_node) {          TAILQ_FOREACH(task, &r->root_timer, task_node) {
                if (!timerisset(&r->root_wait))                if (!timespecisset(&r->root_wait))
                        r->root_wait = TASK_TV(task);                        r->root_wait = TASK_TS(task);
                else if (timercmp(&TASK_TV(task), &r->root_wait, -) < 0)                else if (timespeccmp(&TASK_TS(task), &r->root_wait, -) < 0)
                        r->root_wait = TASK_TV(task);                        r->root_wait = TASK_TS(task);
         }          }
   
         if (TAILQ_FIRST(&r->root_timer)) {          if (TAILQ_FIRST(&r->root_timer)) {
                 m = r->root_wait;                  m = r->root_wait;
                timersub(&m, &now, &mtmp);                timespecsub(&m, &now, &mtmp);
                 r->root_wait = mtmp;                  r->root_wait = mtmp;
         } else {          } else {
                 /* set wait INFTIM */                  /* set wait INFTIM */
                r->root_wait.tv_sec = r->root_wait.tv_usec = -1;                r->root_wait.tv_sec = r->root_wait.tv_nsec = -1;
         }          }
 #else  #else
         if (!TAILQ_FIRST(&r->root_eventlo) && (task = TAILQ_FIRST(&r->root_timer))) {          if (!TAILQ_FIRST(&r->root_eventlo) && (task = TAILQ_FIRST(&r->root_timer))) {
                clock_gettime(CLOCK_MONOTONIC, &nw);                clock_gettime(CLOCK_MONOTONIC, &now);
                now.tv_sec = nw.tv_sec; 
                now.tv_usec = nw.tv_nsec / 1000; 
   
                m = TASK_TV(task);                m = TASK_TS(task);
                timersub(&m, &now, &mtmp);                timespecsub(&m, &now, &mtmp);
                 r->root_wait = mtmp;                  r->root_wait = mtmp;
         } else {          } else {
                 /* set wait INFTIM */                  /* set wait INFTIM */
                r->root_wait.tv_sec = r->root_wait.tv_usec = -1;                r->root_wait.tv_sec = r->root_wait.tv_nsec = -1;
         }          }
 #endif  #endif
         /* if present member of eventLo, set NOWAIT */          /* if present member of eventLo, set NOWAIT */
         if (TAILQ_FIRST(&r->root_eventlo))          if (TAILQ_FIRST(&r->root_eventlo))
                timerclear(&r->root_wait);                timespecclear(&r->root_wait);
   
        if (r->root_wait.tv_sec != -1 && r->root_wait.tv_usec != -1) {        if (r->root_wait.tv_sec != -1 && r->root_wait.tv_nsec != -1)
                nw.tv_sec = r->root_wait.tv_sec;                timeout = &r->root_wait;
                nw.tv_nsec = r->root_wait.tv_usec * 1000;        else if (r->root_poll.tv_sec == -1 && r->root_poll.tv_nsec == -1)
                timeout = &nw; 
        } else  /* wait INFTIM */ 
                 timeout = NULL;                  timeout = NULL;
           else
                   timeout = &r->root_poll;
         if ((en = kevent(r->root_kq, NULL, 0, res, KQ_EVENTS, timeout)) == -1) {          if ((en = kevent(r->root_kq, NULL, 0, res, KQ_EVENTS, timeout)) == -1) {
                LOGERR;                if (r->root_hooks.hook_exec.exception) {
                         if (r->root_hooks.hook_exec.exception(r, NULL))
                                 return NULL;
                 } else
                         LOGERR;
 #ifdef NDEBUG
                 /* kevent no exit by error, if non-debug version */
                 goto retry;                  goto retry;
   #else
                   /* diagnostic exit from scheduler if kevent error occur */
                   return NULL;
   #endif
         }          }
   
        timespecclear(&nw);        now.tv_sec = now.tv_nsec = 0;
         /* Go and catch the cat into pipes ... */          /* Go and catch the cat into pipes ... */
         for (i = 0; i < en; i++) {          for (i = 0; i < en; i++) {
                 memcpy(evt, &res[i], sizeof evt);                  memcpy(evt, &res[i], sizeof evt);
Line 316  retry: Line 357  retry:
                 switch (res[i].filter) {                  switch (res[i].filter) {
                         case EVFILT_READ:                          case EVFILT_READ:
                                 TAILQ_FOREACH(task, &r->root_read, task_node) {                                  TAILQ_FOREACH(task, &r->root_read, task_node) {
                                        if (TASK_FD(task) != *((int*) res[i].udata))                                        if (TASK_FD(task) != ((intptr_t) res[i].udata))
                                                 continue;                                                  continue;
                                         /* remove read handle */                                          /* remove read handle */
                                         io = ROOT_DATA(task->task_root);                                          io = ROOT_DATA(task->task_root);
                                         FD_CLR(TASK_FD(task), &io->rfd);                                          FD_CLR(TASK_FD(task), &io->rfd);
   
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_lock(&r->root_mtx[taskREAD]);
   #endif
                                         TAILQ_REMOVE(&r->root_read, task, task_node);                                          TAILQ_REMOVE(&r->root_read, task, task_node);
                                        task->task_type = taskREADY;#ifdef HAVE_LIBPTHREAD
                                        TAILQ_INSERT_TAIL(&r->root_ready, task, task_node);                                        pthread_mutex_unlock(&r->root_mtx[taskREAD]);
 #endif
                                         if (r->root_hooks.hook_exec.exception && res[i].flags & EV_EOF) {
                                                 if (r->root_hooks.hook_exec.exception(r, (void*) EV_EOF)) {
                                                         task->task_type = taskUNUSE;
 #ifdef HAVE_LIBPTHREAD
                                                         pthread_mutex_lock(&r->root_mtx[taskUNUSE]);
 #endif
                                                         TAILQ_INSERT_TAIL(&r->root_unuse, task, task_node);
 #ifdef HAVE_LIBPTHREAD
                                                         pthread_mutex_unlock(&r->root_mtx[taskUNUSE]);
 #endif
                                                 } else {
                                                         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
                                                 }
                                         } else {
                                                 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
                                         }
                                         break;                                          break;
                                 }                                  }
                                 break;                                  break;
                         case EVFILT_WRITE:                          case EVFILT_WRITE:
                                 TAILQ_FOREACH(task, &r->root_write, task_node) {                                  TAILQ_FOREACH(task, &r->root_write, task_node) {
                                        if (TASK_FD(task) != *((int*) res[i].udata))                                        if (TASK_FD(task) != ((intptr_t) res[i].udata))
                                                 continue;                                                  continue;
                                         /* remove write handle */                                          /* remove write handle */
                                         io = ROOT_DATA(task->task_root);                                          io = ROOT_DATA(task->task_root);
                                         FD_CLR(TASK_FD(task), &io->wfd);                                          FD_CLR(TASK_FD(task), &io->wfd);
   
   #ifdef HAVE_LIBPTHREAD
                                           pthread_mutex_lock(&r->root_mtx[taskWRITE]);
   #endif
                                         TAILQ_REMOVE(&r->root_write, task, task_node);                                          TAILQ_REMOVE(&r->root_write, task, task_node);
                                        task->task_type = taskREADY;#ifdef HAVE_LIBPTHREAD
                                        TAILQ_INSERT_TAIL(&r->root_ready, task, task_node);                                        pthread_mutex_unlock(&r->root_mtx[taskWRITE]);
 #endif
                                         if (r->root_hooks.hook_exec.exception && res[i].flags & EV_EOF) {
                                                 if (r->root_hooks.hook_exec.exception(r, (void*) EV_EOF)) {
                                                         task->task_type = taskUNUSE;
 #ifdef HAVE_LIBPTHREAD
                                                         pthread_mutex_lock(&r->root_mtx[taskUNUSE]);
 #endif
                                                         TAILQ_INSERT_TAIL(&r->root_unuse, task, task_node);
 #ifdef HAVE_LIBPTHREAD
                                                         pthread_mutex_unlock(&r->root_mtx[taskUNUSE]);
 #endif
                                                 } else {
                                                         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
                                                 }
                                         } else {
                                                 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
                                         }
                                         break;                                          break;
                                 }                                  }
                                 break;                                  break;
                 }                  }
                if (kevent(r->root_kq, evt, 1, NULL, 0, &now) == -1) {
                if (kevent(r->root_kq, evt, 1, NULL, 0, &nw) == -1)                        if (r->root_hooks.hook_exec.exception) {
                        LOGERR;                                if (r->root_hooks.hook_exec.exception(r, NULL))
                                         return NULL;
                         } else
                                 LOGERR;
                 }
         }          }
   
        /* timer update */        /* timer update & put in ready queue */
        clock_gettime(CLOCK_MONOTONIC, &nw);        clock_gettime(CLOCK_MONOTONIC, &now);
        now.tv_sec = nw.tv_sec; 
        now.tv_usec = nw.tv_nsec / 1000; 
   
         TAILQ_FOREACH(task, &r->root_timer, task_node)          TAILQ_FOREACH(task, &r->root_timer, task_node)
                if (timercmp(&now, &TASK_TV(task), -) >= 0) {                if (timespeccmp(&now, &TASK_TS(task), -) >= 0) {
 #ifdef HAVE_LIBPTHREAD
                         pthread_mutex_lock(&r->root_mtx[taskTIMER]);
 #endif
                         TAILQ_REMOVE(&r->root_timer, task, task_node);                          TAILQ_REMOVE(&r->root_timer, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                           pthread_mutex_unlock(&r->root_mtx[taskTIMER]);
   #endif
                         task->task_type = taskREADY;                          task->task_type = taskREADY;
   #ifdef HAVE_LIBPTHREAD
                           pthread_mutex_lock(&r->root_mtx[taskREADY]);
   #endif
                         TAILQ_INSERT_TAIL(&r->root_ready, task, task_node);                          TAILQ_INSERT_TAIL(&r->root_ready, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                           pthread_mutex_unlock(&r->root_mtx[taskREADY]);
   #endif
                 }                  }
   
         /* put eventlo priority task to ready queue, if there is no ready task or           /* put eventlo priority task to ready queue, if there is no ready task or 
Line 366  retry: Line 489  retry:
                 if (!TAILQ_FIRST(&r->root_ready) || r->root_eventlo_miss > MAX_EVENTLO_MISS) {                  if (!TAILQ_FIRST(&r->root_ready) || r->root_eventlo_miss > MAX_EVENTLO_MISS) {
                         r->root_eventlo_miss = 0;                          r->root_eventlo_miss = 0;
   
   #ifdef HAVE_LIBPTHREAD
                           pthread_mutex_lock(&r->root_mtx[taskEVENTLO]);
   #endif
                         TAILQ_REMOVE(&r->root_eventlo, task, task_node);                          TAILQ_REMOVE(&r->root_eventlo, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                           pthread_mutex_unlock(&r->root_mtx[taskEVENTLO]);
   #endif
                         task->task_type = taskREADY;                          task->task_type = taskREADY;
   #ifdef HAVE_LIBPTHREAD
                           pthread_mutex_lock(&r->root_mtx[taskREADY]);
   #endif
                         TAILQ_INSERT_TAIL(&r->root_ready, task, task_node);                          TAILQ_INSERT_TAIL(&r->root_ready, task, task_node);
   #ifdef HAVE_LIBPTHREAD
                           pthread_mutex_unlock(&r->root_mtx[taskREADY]);
   #endif
                 } else                  } else
                         r->root_eventlo_miss++;                          r->root_eventlo_miss++;
         } else          } else
Line 377  retry: Line 512  retry:
         /* OK, lets get ready task !!! */          /* OK, lets get ready task !!! */
         if (!(task = TAILQ_FIRST(&r->root_ready)))          if (!(task = TAILQ_FIRST(&r->root_ready)))
                 goto retry;                  goto retry;
   #ifdef HAVE_LIBPTHREAD
           pthread_mutex_lock(&r->root_mtx[taskREADY]);
   #endif
         TAILQ_REMOVE(&r->root_ready, task, task_node);          TAILQ_REMOVE(&r->root_ready, task, task_node);
   #ifdef HAVE_LIBPTHREAD
           pthread_mutex_unlock(&r->root_mtx[taskREADY]);
   #endif
         task->task_type = taskUNUSE;          task->task_type = taskUNUSE;
   #ifdef HAVE_LIBPTHREAD
           pthread_mutex_lock(&r->root_mtx[taskUNUSE]);
   #endif
         TAILQ_INSERT_TAIL(&r->root_unuse, task, task_node);          TAILQ_INSERT_TAIL(&r->root_unuse, task, task_node);
   #ifdef HAVE_LIBPTHREAD
           pthread_mutex_unlock(&r->root_mtx[taskUNUSE]);
   #endif
         return task;          return task;
 }  }
   
   /*
    * sched_hook_exception() - Default EXCEPTION hook
    * @root = root task
    * @arg = custom handling: if arg == EV_EOF or other value; default: arg == NULL log errno
    * return: <0 errors and 0 ok
    */
   void *
   sched_hook_exception(void *root, void *arg)
   {
           sched_root_task_t *r = root;
   
           if (!r || !ROOT_DATA(r) || !ROOT_DATLEN(r))
                   return NULL;
   
           /* custom exception handling ... */
           if (arg) {
                   if (arg == (void*) EV_EOF)
                           return NULL;
                   return (void*) -1;      /* raise scheduler error!!! */
           }
   
           /* if error hook exists */
           if (r->root_hooks.hook_root.error)
                   return (r->root_hooks.hook_root.error(root, (void*) ((intptr_t) errno)));
   
           /* default case! */
           LOGERR;
           return NULL;
   }

Removed from v.1.1.1.1  
changed lines
  Added in v.1.3.4.3


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