Diff for /libaitsched/src/hooks.c between versions 1.35 and 1.39

version 1.35, 2021/06/08 21:45:07 version 1.39, 2022/12/20 22:40:32
Line 12  terms: Line 12  terms:
 All of the documentation and software included in the ELWIX and AITNET  All of the documentation and software included in the ELWIX and AITNET
 Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>  Releases is copyrighted by ELWIX - Sofia/Bulgaria <info@elwix.org>
   
Copyright 2004 - 2021Copyright 2004 - 2022
         by Michael Pounov <misho@elwix.org>.  All rights reserved.          by Michael Pounov <misho@elwix.org>.  All rights reserved.
   
 Redistribution and use in source and binary forms, with or without  Redistribution and use in source and binary forms, with or without
Line 156  sched_hook_init(void *root, void *arg __unused) Line 156  sched_hook_init(void *root, void *arg __unused)
         }          }
 #else  #else
         r->root_kq ^= r->root_kq;          r->root_kq ^= r->root_kq;
   #endif
   
         FD_ZERO(&r->root_fds[0]);          FD_ZERO(&r->root_fds[0]);
         FD_ZERO(&r->root_fds[1]);          FD_ZERO(&r->root_fds[1]);
#endif        FD_ZERO(&r->root_fds[2]);
   
         return NULL;          return NULL;
 }  }
Line 184  sched_hook_fini(void *root, void *arg __unused) Line 186  sched_hook_fini(void *root, void *arg __unused)
                 r->root_kq = 0;                  r->root_kq = 0;
         }          }
 #else  #else
         FD_ZERO(&r->root_fds[1]);  
         FD_ZERO(&r->root_fds[0]);  
         r->root_kq ^= r->root_kq;          r->root_kq ^= r->root_kq;
 #endif  #endif
   
           FD_ZERO(&r->root_fds[2]);
           FD_ZERO(&r->root_fds[1]);
           FD_ZERO(&r->root_fds[0]);
   
         return NULL;          return NULL;
 }  }
   
Line 204  sched_hook_cancel(void *task, void *arg __unused) Line 208  sched_hook_cancel(void *task, void *arg __unused)
 {  {
         sched_task_t *t = task, *tmp, *tt;          sched_task_t *t = task, *tmp, *tt;
         sched_root_task_t *r = NULL;          sched_root_task_t *r = NULL;
        int flg;        int flg = 0;
 #if SUP_ENABLE == KQ_SUPPORT  #if SUP_ENABLE == KQ_SUPPORT
         struct kevent chg[1];          struct kevent chg[1];
         struct timespec timeout = { 0, 0 };          struct timespec timeout = { 0, 0 };
 #elif SUP_ENABLE == EP_SUPPORT  #elif SUP_ENABLE == EP_SUPPORT
        struct epoll_event ee = { .events = 0, .data.fd = 0 };        struct epoll_event ee = { .events = 0, .data.u64 = 0l };
 #else  #else
         register int i;          register int i;
 #endif  #endif
Line 229  sched_hook_cancel(void *task, void *arg __unused) Line 233  sched_hook_cancel(void *task, void *arg __unused)
         switch (TASK_TYPE(t)) {          switch (TASK_TYPE(t)) {
                 case taskREAD:                  case taskREAD:
                         /* check for multi subscribers */                          /* check for multi subscribers */
                         flg = 0;  
                         TAILQ_FOREACH_SAFE(tt, &r->root_read, task_node, tmp)                          TAILQ_FOREACH_SAFE(tt, &r->root_read, task_node, tmp)
                                if (TASK_FD(tt) != TASK_FD(t))                                if (TASK_FD(tt) == TASK_FD(t))
                                        continue; 
                                else 
                                         flg++;                                          flg++;
 #if SUP_ENABLE == KQ_SUPPORT  #if SUP_ENABLE == KQ_SUPPORT
 #ifdef __NetBSD__  #ifdef __NetBSD__
Line 247  sched_hook_cancel(void *task, void *arg __unused) Line 248  sched_hook_cancel(void *task, void *arg __unused)
                         ee.data.fd = TASK_FD(t);                          ee.data.fd = TASK_FD(t);
                         ee.events ^= ee.events;                          ee.events ^= ee.events;
                         if (FD_ISSET(TASK_FD(t), &r->root_fds[1]))                          if (FD_ISSET(TASK_FD(t), &r->root_fds[1]))
                                ee.events = EPOLLOUT;                                ee.events |= EPOLLOUT;
   
                        if (flg < 2)                        if (flg < 2) {
                                 FD_CLR(TASK_FD(t), &r->root_fds[0]);                                  FD_CLR(TASK_FD(t), &r->root_fds[0]);
                        else                                FD_CLR(TASK_FD(t), &r->root_fds[2]);
                                ee.events |= EPOLLIN | EPOLLPRI;                        } else {
                                 if (FD_ISSET(TASK_FD(t), &r->root_fds[0]))
                                         ee.events |= EPOLLIN;
                                 if (FD_ISSET(TASK_FD(t), &r->root_fds[2]))
                                         ee.events |= EPOLLPRI;
                         }
 #else  #else
                         if (flg < 2) {                          if (flg < 2) {
                                 FD_CLR(TASK_FD(t), &r->root_fds[0]);                                  FD_CLR(TASK_FD(t), &r->root_fds[0]);
                                   FD_CLR(TASK_FD(t), &r->root_fds[2]);
   
                                 /* optimize select */                                  /* optimize select */
                                for (i = r->root_kq - 1; i > 2; i--)                                for (i = r->root_kq - 1; i >= 0; i--)
                                        if (FD_ISSET(i, &r->root_fds[0]) || FD_ISSET(i, &r->root_fds[1]))                                        if (FD_ISSET(i, &r->root_fds[0]) || 
                                                         FD_ISSET(i, &r->root_fds[1]) || 
                                                         FD_ISSET(i, &r->root_fds[2]))
                                                 break;                                                  break;
                                if (i > 2)                                r->root_kq = i + 1;
                                        r->root_kq = i + 1; 
                         }                          }
 #endif  #endif
                         break;                          break;
                 case taskWRITE:                  case taskWRITE:
                         /* check for multi subscribers */                          /* check for multi subscribers */
                         flg = 0;  
                         TAILQ_FOREACH_SAFE(tt, &r->root_write, task_node, tmp)                          TAILQ_FOREACH_SAFE(tt, &r->root_write, task_node, tmp)
                                if (TASK_FD(tt) != TASK_FD(t))                                if (TASK_FD(tt) == TASK_FD(t))
                                        continue; 
                                else 
                                         flg++;                                          flg++;
 #if SUP_ENABLE == KQ_SUPPORT  #if SUP_ENABLE == KQ_SUPPORT
 #ifdef __NetBSD__  #ifdef __NetBSD__
Line 286  sched_hook_cancel(void *task, void *arg __unused) Line 291  sched_hook_cancel(void *task, void *arg __unused)
                         ee.data.fd = TASK_FD(t);                          ee.data.fd = TASK_FD(t);
                         ee.events ^= ee.events;                          ee.events ^= ee.events;
                         if (FD_ISSET(TASK_FD(t), &r->root_fds[0]))                          if (FD_ISSET(TASK_FD(t), &r->root_fds[0]))
                                ee.events = EPOLLIN | EPOLLPRI;                                ee.events |= EPOLLIN;
                         if (FD_ISSET(TASK_FD(t), &r->root_fds[2]))
                                 ee.events |= EPOLLPRI;
   
                         if (flg < 2)                          if (flg < 2)
                                 FD_CLR(TASK_FD(t), &r->root_fds[1]);                                  FD_CLR(TASK_FD(t), &r->root_fds[1]);
Line 297  sched_hook_cancel(void *task, void *arg __unused) Line 304  sched_hook_cancel(void *task, void *arg __unused)
                                 FD_CLR(TASK_FD(t), &r->root_fds[1]);                                  FD_CLR(TASK_FD(t), &r->root_fds[1]);
   
                                 /* optimize select */                                  /* optimize select */
                                for (i = r->root_kq - 1; i > 2; i--)                                for (i = r->root_kq - 1; i >= 0; i--)
                                        if (FD_ISSET(i, &r->root_fds[0]) || FD_ISSET(i, &r->root_fds[1]))                                        if (FD_ISSET(i, &r->root_fds[0]) || 
                                                         FD_ISSET(i, &r->root_fds[1]) || 
                                                         FD_ISSET(i, &r->root_fds[2]))
                                                 break;                                                  break;
                                if (i > 2)                                r->root_kq = i + 1;
                                        r->root_kq = i + 1; 
                         }                          }
 #endif  #endif
                         break;                          break;
                 case taskALARM:                  case taskALARM:
 #if SUP_ENABLE == KQ_SUPPORT  #if SUP_ENABLE == KQ_SUPPORT
                         /* check for multi subscribers */                          /* check for multi subscribers */
                         flg = 0;  
                         TAILQ_FOREACH_SAFE(tt, &r->root_alarm, task_node, tmp)                          TAILQ_FOREACH_SAFE(tt, &r->root_alarm, task_node, tmp)
                                if (TASK_DATA(tt) != TASK_DATA(t))                                if (TASK_DATA(tt) == TASK_DATA(t))
                                        continue; 
                                else 
                                         flg++;                                          flg++;
 #ifdef __NetBSD__  #ifdef __NetBSD__
                         EV_SET(&chg[0], (uintptr_t) TASK_DATA(t), EVFILT_TIMER, flg < 2 ? EV_DELETE : 0,                           EV_SET(&chg[0], (uintptr_t) TASK_DATA(t), EVFILT_TIMER, flg < 2 ? EV_DELETE : 0, 
Line 326  sched_hook_cancel(void *task, void *arg __unused) Line 331  sched_hook_cancel(void *task, void *arg __unused)
                 case taskNODE:                  case taskNODE:
 #if SUP_ENABLE == KQ_SUPPORT  #if SUP_ENABLE == KQ_SUPPORT
                         /* check for multi subscribers */                          /* check for multi subscribers */
                         flg = 0;  
                         TAILQ_FOREACH_SAFE(tt, &r->root_node, task_node, tmp)                          TAILQ_FOREACH_SAFE(tt, &r->root_node, task_node, tmp)
                                if (TASK_FD(tt) != TASK_FD(t))                                if (TASK_FD(tt) == TASK_FD(t))
                                        continue; 
                                else 
                                         flg++;                                          flg++;
 #ifdef __NetBSD__  #ifdef __NetBSD__
                         EV_SET(&chg[0], TASK_FD(t), EVFILT_VNODE, flg < 2 ? EV_DELETE : 0,                           EV_SET(&chg[0], TASK_FD(t), EVFILT_VNODE, flg < 2 ? EV_DELETE : 0, 
Line 344  sched_hook_cancel(void *task, void *arg __unused) Line 346  sched_hook_cancel(void *task, void *arg __unused)
                 case taskPROC:                  case taskPROC:
 #if SUP_ENABLE == KQ_SUPPORT  #if SUP_ENABLE == KQ_SUPPORT
                         /* check for multi subscribers */                          /* check for multi subscribers */
                         flg = 0;  
                         TAILQ_FOREACH_SAFE(tt, &r->root_proc, task_node, tmp)                          TAILQ_FOREACH_SAFE(tt, &r->root_proc, task_node, tmp)
                                if (TASK_VAL(tt) != TASK_VAL(t))                                if (TASK_VAL(tt) == TASK_VAL(t))
                                        continue; 
                                else 
                                         flg++;                                          flg++;
 #ifdef __NetBSD__  #ifdef __NetBSD__
                         EV_SET(&chg[0], TASK_VAL(t), EVFILT_PROC, flg < 2 ? EV_DELETE : 0,                           EV_SET(&chg[0], TASK_VAL(t), EVFILT_PROC, flg < 2 ? EV_DELETE : 0, 
Line 362  sched_hook_cancel(void *task, void *arg __unused) Line 361  sched_hook_cancel(void *task, void *arg __unused)
                 case taskSIGNAL:                  case taskSIGNAL:
 #if SUP_ENABLE == KQ_SUPPORT  #if SUP_ENABLE == KQ_SUPPORT
                         /* check for multi subscribers */                          /* check for multi subscribers */
                         flg = 0;  
                         TAILQ_FOREACH_SAFE(tt, &r->root_signal, task_node, tmp)                          TAILQ_FOREACH_SAFE(tt, &r->root_signal, task_node, tmp)
                                if (TASK_VAL(tt) != TASK_VAL(t))                                if (TASK_VAL(tt) == TASK_VAL(t))
                                        continue; 
                                else 
                                         flg++;                                          flg++;
 #ifdef __NetBSD__  #ifdef __NetBSD__
                         EV_SET(&chg[0], TASK_VAL(t), EVFILT_SIGNAL, flg < 2 ? EV_DELETE : 0,                           EV_SET(&chg[0], TASK_VAL(t), EVFILT_SIGNAL, flg < 2 ? EV_DELETE : 0, 
Line 384  sched_hook_cancel(void *task, void *arg __unused) Line 380  sched_hook_cancel(void *task, void *arg __unused)
                 case taskAIO:                  case taskAIO:
 #if SUP_ENABLE == KQ_SUPPORT  #if SUP_ENABLE == KQ_SUPPORT
                         /* check for multi subscribers */                          /* check for multi subscribers */
                         flg = 0;  
                         TAILQ_FOREACH_SAFE(tt, &r->root_aio, task_node, tmp)                          TAILQ_FOREACH_SAFE(tt, &r->root_aio, task_node, tmp)
                                if (TASK_VAL(tt) != TASK_VAL(t))                                if (TASK_VAL(tt) == TASK_VAL(t))
                                        continue; 
                                else 
                                         flg++;                                          flg++;
 #ifdef __NetBSD__  #ifdef __NetBSD__
                         EV_SET(&chg[0], TASK_VAL(t), EVFILT_AIO, flg < 2 ? EV_DELETE : 0,                           EV_SET(&chg[0], TASK_VAL(t), EVFILT_AIO, flg < 2 ? EV_DELETE : 0, 
Line 401  sched_hook_cancel(void *task, void *arg __unused) Line 394  sched_hook_cancel(void *task, void *arg __unused)
                         if (acb) {                          if (acb) {
                                 if (aio_cancel(acb->aio_fildes, acb) == AIO_CANCELED)                                  if (aio_cancel(acb->aio_fildes, acb) == AIO_CANCELED)
                                         aio_return(acb);                                          aio_return(acb);
                                free(acb);                                e_free(acb);
                                 TASK_VAL(t) = 0;                                  TASK_VAL(t) = 0;
                         }                          }
 #endif  #endif
Line 410  sched_hook_cancel(void *task, void *arg __unused) Line 403  sched_hook_cancel(void *task, void *arg __unused)
                 case taskLIO:                  case taskLIO:
 #if SUP_ENABLE == KQ_SUPPORT  #if SUP_ENABLE == KQ_SUPPORT
                         /* check for multi subscribers */                          /* check for multi subscribers */
                         flg = 0;  
                         TAILQ_FOREACH_SAFE(tt, &r->root_lio, task_node, tmp)                          TAILQ_FOREACH_SAFE(tt, &r->root_lio, task_node, tmp)
                                if (TASK_VAL(tt) != TASK_VAL(t))                                if (TASK_VAL(tt) == TASK_VAL(t))
                                        continue; 
                                else 
                                         flg++;                                          flg++;
 #ifdef __NetBSD__  #ifdef __NetBSD__
                         EV_SET(&chg[0], TASK_VAL(t), EVFILT_LIO, flg < 2 ? EV_DELETE : 0,                           EV_SET(&chg[0], TASK_VAL(t), EVFILT_LIO, flg < 2 ? EV_DELETE : 0, 
Line 428  sched_hook_cancel(void *task, void *arg __unused) Line 418  sched_hook_cancel(void *task, void *arg __unused)
                                 for (i = 0; i < TASK_DATLEN(t); i++) {                                  for (i = 0; i < TASK_DATLEN(t); i++) {
                                         if (aio_cancel(acbs[i]->aio_fildes, acbs[i]) == AIO_CANCELED)                                          if (aio_cancel(acbs[i]->aio_fildes, acbs[i]) == AIO_CANCELED)
                                                 aio_return(acbs[i]);                                                  aio_return(acbs[i]);
                                        free(acbs[i]);                                        e_free(acbs[i]);
                                 }                                  }
                                free(acbs);                                e_free(acbs);
                                 TASK_VAL(t) = 0;                                  TASK_VAL(t) = 0;
                         }                          }
 #endif  #endif
Line 441  sched_hook_cancel(void *task, void *arg __unused) Line 431  sched_hook_cancel(void *task, void *arg __unused)
                 case taskUSER:                  case taskUSER:
 #if SUP_ENABLE == KQ_SUPPORT  #if SUP_ENABLE == KQ_SUPPORT
                         /* check for multi subscribers */                          /* check for multi subscribers */
                         flg = 0;  
                         TAILQ_FOREACH_SAFE(tt, &r->root_user, task_node, tmp)                          TAILQ_FOREACH_SAFE(tt, &r->root_user, task_node, tmp)
                                if (TASK_VAL(tt) != TASK_VAL(t))                                if (TASK_VAL(tt) == TASK_VAL(t))
                                        continue; 
                                else 
                                         flg++;                                          flg++;
 #ifdef __NetBSD__  #ifdef __NetBSD__
                         EV_SET(&chg[0], TASK_VAL(t), EVFILT_USER, flg < 2 ? EV_DELETE : 0,                           EV_SET(&chg[0], TASK_VAL(t), EVFILT_USER, flg < 2 ? EV_DELETE : 0, 
Line 477  sched_hook_cancel(void *task, void *arg __unused) Line 464  sched_hook_cancel(void *task, void *arg __unused)
                         schedCancel((sched_task_t*) TASK_RET(t));                          schedCancel((sched_task_t*) TASK_RET(t));
 #else  #else
                         /* check for multi subscribers */                          /* check for multi subscribers */
                         flg = 0;  
                         TAILQ_FOREACH_SAFE(tt, &r->root_rtc, task_node, tmp)                          TAILQ_FOREACH_SAFE(tt, &r->root_rtc, task_node, tmp)
                                if (TASK_DATA(tt) != TASK_DATA(t))                                if (TASK_DATA(tt) == TASK_DATA(t))
                                        continue; 
                                else 
                                         flg++;                                          flg++;
   
                         /* restore signal */                          /* restore signal */
Line 497  sched_hook_cancel(void *task, void *arg __unused) Line 481  sched_hook_cancel(void *task, void *arg __unused)
 #if SUP_ENABLE == KQ_SUPPORT  #if SUP_ENABLE == KQ_SUPPORT
         kevent(r->root_kq, chg, 1, NULL, 0, &timeout);          kevent(r->root_kq, chg, 1, NULL, 0, &timeout);
 #elif SUP_ENABLE == EP_SUPPORT  #elif SUP_ENABLE == EP_SUPPORT
        epoll_ctl(r->root_kq, ee.events ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, ee.data.fd, &ee);        if (TASK_TYPE(t) == taskREAD || TASK_TYPE(t) == taskWRITE) {
                 epoll_ctl(r->root_kq, ee.events ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, ee.data.fd, &ee);
         }
 #endif  #endif
         return NULL;          return NULL;
 }  }
Line 547  sched_hook_thread(void *task, void *arg) Line 533  sched_hook_thread(void *task, void *arg)
  * return: <0 errors and 0 ok   * return: <0 errors and 0 ok
  */   */
 void *  void *
sched_hook_read(void *task, void *arg __unused)sched_hook_read(void *task, void *arg)
 {  {
         sched_task_t *t = task;          sched_task_t *t = task;
         sched_root_task_t *r = NULL;          sched_root_task_t *r = NULL;
           uintptr_t mask = (uintptr_t) arg;
 #if SUP_ENABLE == KQ_SUPPORT  #if SUP_ENABLE == KQ_SUPPORT
         struct kevent chg[1];          struct kevent chg[1];
         struct timespec timeout = { 0, 0 };          struct timespec timeout = { 0, 0 };
 #elif SUP_ENABLE == EP_SUPPORT  #elif SUP_ENABLE == EP_SUPPORT
        struct epoll_event ee;        struct epoll_event ee = { 0 };
         int flg = 0;          int flg = 0;
 #endif  #endif
   
Line 566  sched_hook_read(void *task, void *arg __unused) Line 553  sched_hook_read(void *task, void *arg __unused)
   
 #if SUP_ENABLE == KQ_SUPPORT  #if SUP_ENABLE == KQ_SUPPORT
 #ifdef __NetBSD__  #ifdef __NetBSD__
        EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, (intptr_t) TASK_FD(t));        EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_ADD | EV_CLEAR | mask, 
                         0, 0, (intptr_t) TASK_FD(t));
 #else  #else
        EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, (void*) TASK_FD(t));        EV_SET(&chg[0], TASK_FD(t), EVFILT_READ, EV_ADD | EV_CLEAR | mask, 
                         0, 0, (void*) TASK_FD(t));
 #endif  #endif
         if (kevent(r->root_kq, chg, 1, NULL, 0, &timeout) == -1) {          if (kevent(r->root_kq, chg, 1, NULL, 0, &timeout) == -1) {
                 if (r->root_hooks.hook_exec.exception)                  if (r->root_hooks.hook_exec.exception)
Line 578  sched_hook_read(void *task, void *arg __unused) Line 567  sched_hook_read(void *task, void *arg __unused)
                 return (void*) -1;                  return (void*) -1;
         }          }
 #elif SUP_ENABLE == EP_SUPPORT  #elif SUP_ENABLE == EP_SUPPORT
           if (!mask)
                   mask = EPOLLIN | EPOLLPRI;
         ee.data.fd = TASK_FD(t);          ee.data.fd = TASK_FD(t);
        ee.events = EPOLLIN | EPOLLPRI;        ee.events = mask;
        if (FD_ISSET(TASK_FD(t), &r->root_fds[0]))        if (FD_ISSET(TASK_FD(t), &r->root_fds[2])) {
                 flg |= 4;
                 ee.events |= EPOLLPRI;
         }
         if (FD_ISSET(TASK_FD(t), &r->root_fds[0])) {
                 flg |= 1;                  flg |= 1;
                   ee.events |= EPOLLIN;
           }
         if (FD_ISSET(TASK_FD(t), &r->root_fds[1])) {          if (FD_ISSET(TASK_FD(t), &r->root_fds[1])) {
                 flg |= 2;                  flg |= 2;
                 ee.events |= EPOLLOUT;                  ee.events |= EPOLLOUT;
Line 593  sched_hook_read(void *task, void *arg __unused) Line 590  sched_hook_read(void *task, void *arg __unused)
                 else                  else
                         LOGERR;                          LOGERR;
                 return (void*) -1;                  return (void*) -1;
        } else        } else {
                FD_SET(TASK_FD(t), &r->root_fds[0]);                if (mask & EPOLLIN)
                         FD_SET(TASK_FD(t), &r->root_fds[0]);
                 if (mask & EPOLLPRI)
                         FD_SET(TASK_FD(t), &r->root_fds[2]);
         }
 #else  #else
        FD_SET(TASK_FD(t), &r->root_fds[0]);        if (!mask) {
                 FD_SET(TASK_FD(t), &r->root_fds[0]);
                 FD_SET(TASK_FD(t), &r->root_fds[2]);
         } else {
                 if (mask & 1)
                         FD_SET(TASK_FD(t), &r->root_fds[0]);
                 if (mask & 2)
                         FD_SET(TASK_FD(t), &r->root_fds[2]);
         }
 
         if (TASK_FD(t) >= r->root_kq)          if (TASK_FD(t) >= r->root_kq)
                 r->root_kq = TASK_FD(t) + 1;                  r->root_kq = TASK_FD(t) + 1;
 #endif  #endif
Line 612  sched_hook_read(void *task, void *arg __unused) Line 622  sched_hook_read(void *task, void *arg __unused)
  * return: <0 errors and 0 ok   * return: <0 errors and 0 ok
  */   */
 void *  void *
sched_hook_write(void *task, void *arg __unused)sched_hook_write(void *task, void *arg)
 {  {
         sched_task_t *t = task;          sched_task_t *t = task;
         sched_root_task_t *r = NULL;          sched_root_task_t *r = NULL;
           uintptr_t mask = (uintptr_t) arg;
 #if SUP_ENABLE == KQ_SUPPORT  #if SUP_ENABLE == KQ_SUPPORT
         struct kevent chg[1];          struct kevent chg[1];
         struct timespec timeout = { 0, 0 };          struct timespec timeout = { 0, 0 };
 #elif SUP_ENABLE == EP_SUPPORT  #elif SUP_ENABLE == EP_SUPPORT
        struct epoll_event ee;        struct epoll_event ee = { 0 };
         int flg = 0;          int flg = 0;
 #endif  #endif
   
Line 631  sched_hook_write(void *task, void *arg __unused) Line 642  sched_hook_write(void *task, void *arg __unused)
   
 #if SUP_ENABLE == KQ_SUPPORT  #if SUP_ENABLE == KQ_SUPPORT
 #ifdef __NetBSD__  #ifdef __NetBSD__
        EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, (intptr_t) TASK_FD(t));        EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_ADD | EV_CLEAR | mask, 
                         0, 0, (intptr_t) TASK_FD(t));
 #else  #else
        EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, (void*) TASK_FD(t));        EV_SET(&chg[0], TASK_FD(t), EVFILT_WRITE, EV_ADD | EV_CLEAR | mask, 
                         0, 0, (void*) TASK_FD(t));
 #endif  #endif
         if (kevent(r->root_kq, chg, 1, NULL, 0, &timeout) == -1) {          if (kevent(r->root_kq, chg, 1, NULL, 0, &timeout) == -1) {
                 if (r->root_hooks.hook_exec.exception)                  if (r->root_hooks.hook_exec.exception)
Line 643  sched_hook_write(void *task, void *arg __unused) Line 656  sched_hook_write(void *task, void *arg __unused)
                 return (void*) -1;                  return (void*) -1;
         }          }
 #elif SUP_ENABLE == EP_SUPPORT  #elif SUP_ENABLE == EP_SUPPORT
           if (!mask)
                   mask = EPOLLOUT;
         ee.data.fd = TASK_FD(t);          ee.data.fd = TASK_FD(t);
        ee.events = EPOLLOUT;        ee.events = mask;
   
           if (FD_ISSET(TASK_FD(t), &r->root_fds[2])) {
                   flg |= 4;
                   ee.events |= EPOLLPRI;
           }
         if (FD_ISSET(TASK_FD(t), &r->root_fds[0])) {          if (FD_ISSET(TASK_FD(t), &r->root_fds[0])) {
                 flg |= 1;                  flg |= 1;
                ee.events |= EPOLLIN | EPOLLPRI;                ee.events |= EPOLLIN;
         }          }
        if (FD_ISSET(TASK_FD(t), &r->root_fds[1]))        if (FD_ISSET(TASK_FD(t), &r->root_fds[1])) {
                 flg |= 2;                  flg |= 2;
                   ee.events |= EPOLLOUT;
           }
   
         if (epoll_ctl(r->root_kq, flg ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, TASK_FD(t), &ee) == -1) {          if (epoll_ctl(r->root_kq, flg ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, TASK_FD(t), &ee) == -1) {
                 if (r->root_hooks.hook_exec.exception)                  if (r->root_hooks.hook_exec.exception)
Line 660  sched_hook_write(void *task, void *arg __unused) Line 681  sched_hook_write(void *task, void *arg __unused)
                         LOGERR;                          LOGERR;
                 return (void*) -1;                  return (void*) -1;
         } else          } else
                FD_SET(TASK_FD(t), &r->root_fds[1]);                if (mask & EPOLLOUT)
                         FD_SET(TASK_FD(t), &r->root_fds[1]);
 #else  #else
        FD_SET(TASK_FD(t), &r->root_fds[1]);        if (!mask)
                 FD_SET(TASK_FD(t), &r->root_fds[1]);
         else
                 if (mask & 1)
                         FD_SET(TASK_FD(t), &r->root_fds[1]);
 
         if (TASK_FD(t) >= r->root_kq)          if (TASK_FD(t) >= r->root_kq)
                 r->root_kq = TASK_FD(t) + 1;                  r->root_kq = TASK_FD(t) + 1;
 #endif  #endif
Line 1015  fetch_hook_kevent_proceed(int en, struct kevent *res,  Line 1042  fetch_hook_kevent_proceed(int en, struct kevent *res, 
                                                                         LOGERR;                                                                          LOGERR;
                                                         } else                                                          } else
                                                                 LOGERR;                                                                  LOGERR;
                                                        free(acb);                                                        e_free(acb);
                                                         TASK_DATLEN(task) = (u_long) len;                                                          TASK_DATLEN(task) = (u_long) len;
                                                         TASK_FD(task) = fd;                                                          TASK_FD(task) = fd;
                                                 }                                                  }
Line 1043  fetch_hook_kevent_proceed(int en, struct kevent *res,  Line 1070  fetch_hook_kevent_proceed(int en, struct kevent *res, 
                                                                         l = 0;                                                                          l = 0;
                                                                 else                                                                  else
                                                                         l = iv[i].iov_len;                                                                          l = iv[i].iov_len;
                                                                free(acbs[i]);                                                                e_free(acbs[i]);
                                                         }                                                          }
                                                        free(acbs);                                                        e_free(acbs);
                                                         TASK_DATLEN(task) = (u_long) len;                                                          TASK_DATLEN(task) = (u_long) len;
                                                         TASK_FD(task) = fd;                                                          TASK_FD(task) = fd;
   
Line 1093  fetch_hook_kevent_proceed(int en, struct kevent *res,  Line 1120  fetch_hook_kevent_proceed(int en, struct kevent *res, 
 static inline void  static inline void
 fetch_hook_epoll_proceed(int en, struct epoll_event *res, sched_root_task_t *r)  fetch_hook_epoll_proceed(int en, struct epoll_event *res, sched_root_task_t *r)
 {  {
        register int i, flg;        register int i, rflg, wflg;
         int ops = EPOLL_CTL_DEL;          int ops = EPOLL_CTL_DEL;
         sched_task_t *t, *tmp, *task;          sched_task_t *t, *tmp, *task;
         struct epoll_event evt[1];          struct epoll_event evt[1];
   
         for (i = 0; i < en; i++) {          for (i = 0; i < en; i++) {
                 memcpy(evt, &res[i], sizeof evt);                  memcpy(evt, &res[i], sizeof evt);
                   evt->events ^= evt->events;
                   rflg = wflg = 0;
   
                if (evt->events & (EPOLLIN | EPOLLPRI)) {                if (res[i].events & (EPOLLIN | EPOLLPRI)) {
                        flg = 0; 
                         task = NULL;                          task = NULL;
                         TAILQ_FOREACH_SAFE(t, &r->root_read, task_node, tmp) {                          TAILQ_FOREACH_SAFE(t, &r->root_read, task_node, tmp) {
                                 if (TASK_FD(t) == evt->data.fd) {                                  if (TASK_FD(t) == evt->data.fd) {
                                        if (!flg)                                        if (!task)
                                                 task = t;                                                  task = t;
                                        flg++;                                        rflg++;
                                 }                                  }
                         }                          }
   
                        if (flg && task) {                        if (task) {
                                 TASK_FLAG(task) = ioctl(TASK_FD(task), FIONREAD, &TASK_RET(task));                                  TASK_FLAG(task) = ioctl(TASK_FD(task), FIONREAD, &TASK_RET(task));
                                 /* remove read handle */                                  /* remove read handle */
                                 remove_task_from(task, &r->root_read);                                  remove_task_from(task, &r->root_read);
Line 1131  fetch_hook_epoll_proceed(int en, struct epoll_event *r Line 1159  fetch_hook_epoll_proceed(int en, struct epoll_event *r
                                         insert_task_to(task, &r->root_ready);                                          insert_task_to(task, &r->root_ready);
                                 }                                  }
   
                                evt->events ^= evt->events;                                if (!(res[i].events & EPOLLOUT) && FD_ISSET(evt->data.fd, &r->root_fds[1])) {
                                if (FD_ISSET(evt->data.fd, &r->root_fds[1])) { 
                                        ops = EPOLL_CTL_MOD; 
                                         evt->events |= EPOLLOUT;                                          evt->events |= EPOLLOUT;
                                           wflg = 42;
                                 }                                  }
                                if (flg > 1) {                                if (rflg > 1) {
                                        ops = EPOLL_CTL_MOD;                                        if (FD_ISSET(evt->data.fd, &r->root_fds[0]))
                                        evt->events |= EPOLLIN | EPOLLPRI;                                                evt->events |= EPOLLIN;
                                } else                                        if (FD_ISSET(evt->data.fd, &r->root_fds[2]))
                                                 evt->events |= EPOLLPRI;
                                 } else {
                                         FD_CLR(evt->data.fd, &r->root_fds[0]);                                          FD_CLR(evt->data.fd, &r->root_fds[0]);
                                           FD_CLR(evt->data.fd, &r->root_fds[2]);
                                   }
                         }                          }
                } else if (evt->events & EPOLLOUT) {                }
                        flg = 0;                if (res[i].events & EPOLLOUT) {
                         task = NULL;                          task = NULL;
                         TAILQ_FOREACH_SAFE(t, &r->root_write, task_node, tmp) {                          TAILQ_FOREACH_SAFE(t, &r->root_write, task_node, tmp) {
                                 if (TASK_FD(t) == evt->data.fd) {                                  if (TASK_FD(t) == evt->data.fd) {
                                        if (!flg)                                        if (!task)
                                                 task = t;                                                  task = t;
                                        flg++;                                        wflg++;
                                 }                                  }
                         }                          }
   
                        if (flg && task) {                        if (task) {
                                 TASK_FLAG(task) = ioctl(TASK_FD(task), FIONWRITE, &TASK_RET(task));                                  TASK_FLAG(task) = ioctl(TASK_FD(task), FIONWRITE, &TASK_RET(task));
                                 /* remove write handle */                                  /* remove write handle */
                                 remove_task_from(task, &r->root_write);                                  remove_task_from(task, &r->root_write);
Line 1172  fetch_hook_epoll_proceed(int en, struct epoll_event *r Line 1203  fetch_hook_epoll_proceed(int en, struct epoll_event *r
                                         insert_task_to(task, &r->root_ready);                                          insert_task_to(task, &r->root_ready);
                                 }                                  }
   
                                evt->events ^= evt->events;                                if (!(res[i].events & EPOLLIN) && FD_ISSET(evt->data.fd, &r->root_fds[0])) {
                                if (FD_ISSET(evt->data.fd, &r->root_fds[0])) {                                        evt->events |= EPOLLIN;
                                        ops = EPOLL_CTL_MOD;                                        rflg = 42;
                                        evt->events |= EPOLLIN | EPOLLPRI; 
                                 }                                  }
                                if (flg > 1) {                                if (!(res[i].events & EPOLLPRI) && FD_ISSET(evt->data.fd, &r->root_fds[2])) {
                                        ops = EPOLL_CTL_MOD;                                        evt->events |= EPOLLPRI;
                                         rflg = 42;
                                 }
                                 if (wflg > 1)
                                         evt->events |= EPOLLOUT;                                          evt->events |= EPOLLOUT;
                                } else                                else
                                         FD_CLR(evt->data.fd, &r->root_fds[1]);                                          FD_CLR(evt->data.fd, &r->root_fds[1]);
                         }                          }
                 }                  }
   
                   ops = EPOLL_CTL_DEL;
                   if (rflg > 1 || wflg > 1)
                           ops = EPOLL_CTL_MOD;
   
                 if (epoll_ctl(r->root_kq, ops, evt->data.fd, evt) == -1) {                  if (epoll_ctl(r->root_kq, ops, evt->data.fd, evt) == -1) {
                         if (r->root_hooks.hook_exec.exception) {                          if (r->root_hooks.hook_exec.exception) {
                                 r->root_hooks.hook_exec.exception(r, NULL);                                  r->root_hooks.hook_exec.exception(r, NULL);
Line 1199  fetch_hook_epoll_proceed(int en, struct epoll_event *r Line 1236  fetch_hook_epoll_proceed(int en, struct epoll_event *r
 static inline void   static inline void 
 fetch_hook_select_proceed(int en, fd_set rfd, fd_set wfd, fd_set xfd, sched_root_task_t *r)  fetch_hook_select_proceed(int en, fd_set rfd, fd_set wfd, fd_set xfd, sched_root_task_t *r)
 {  {
        register int i, flg;        register int i, rflg, wflg;
        sched_task_t *t, *tmp, *task = NULL;        sched_task_t *t, *tmp, *task;
   
         /* skip select check if return value from select is zero */          /* skip select check if return value from select is zero */
         if (!en)          if (!en)
                 return;                  return;
   
         for (i = 0; i < r->root_kq; i++) {          for (i = 0; i < r->root_kq; i++) {
                   if (!FD_ISSET(i, &r->root_fds[0]) && 
                                   !FD_ISSET(i, &r->root_fds[1]) && 
                                   !FD_ISSET(i, &r->root_fds[2]))
                           continue;
   
                   rflg = wflg = 0;
   
                 if (FD_ISSET(i, &rfd) || FD_ISSET(i, &xfd)) {                  if (FD_ISSET(i, &rfd) || FD_ISSET(i, &xfd)) {
                        flg = 0;                        task = NULL;
                         TAILQ_FOREACH_SAFE(t, &r->root_read, task_node, tmp) {                          TAILQ_FOREACH_SAFE(t, &r->root_read, task_node, tmp) {
                                 if (TASK_FD(t) == i) {                                  if (TASK_FD(t) == i) {
                                        if (!flg)                                        if (!task)
                                                 task = t;                                                  task = t;
                                        flg++;                                        rflg++;
                                 }                                  }
                         }                          }
   
                        if (flg && task) {                        if (task) {
                                 TASK_FLAG(task) = ioctl(TASK_FD(task), FIONREAD, &TASK_RET(task));                                  TASK_FLAG(task) = ioctl(TASK_FD(task), FIONREAD, &TASK_RET(task));
   
                                 /* remove read handle */                                  /* remove read handle */
Line 1237  fetch_hook_select_proceed(int en, fd_set rfd, fd_set w Line 1281  fetch_hook_select_proceed(int en, fd_set rfd, fd_set w
                                 }                                  }
   
                                 /* remove resouce */                                  /* remove resouce */
                                if (flg == 1)                                if (rflg == 1) {
                                         FD_CLR(i, &r->root_fds[0]);                                          FD_CLR(i, &r->root_fds[0]);
                                           FD_CLR(i, &r->root_fds[2]);
                                   }
                         }                          }
                } else if (FD_ISSET(i, &wfd)) {                }
                        flg = 0;                if (FD_ISSET(i, &wfd)) {
                         task = NULL;
                         TAILQ_FOREACH_SAFE(t, &r->root_write, task_node, tmp) {                          TAILQ_FOREACH_SAFE(t, &r->root_write, task_node, tmp) {
                                 if (TASK_FD(t) == i) {                                  if (TASK_FD(t) == i) {
                                        if (!flg)                                        if (!task)
                                                 task = t;                                                  task = t;
                                        flg++;                                        wflg++;
                                 }                                  }
                         }                          }
   
                        if (flg && task) {                        if (task) {
                                 TASK_FLAG(task) = ioctl(TASK_FD(task), FIONWRITE, &TASK_RET(task));                                  TASK_FLAG(task) = ioctl(TASK_FD(task), FIONWRITE, &TASK_RET(task));
   
                                 /* remove write handle */                                  /* remove write handle */
Line 1270  fetch_hook_select_proceed(int en, fd_set rfd, fd_set w Line 1317  fetch_hook_select_proceed(int en, fd_set rfd, fd_set w
                                 }                                  }
   
                                 /* remove resouce */                                  /* remove resouce */
                                if (flg == 1)                                if (wflg == 1)
                                         FD_CLR(i, &r->root_fds[1]);                                          FD_CLR(i, &r->root_fds[1]);
                         }                          }
                 }                  }
         }          }
   
         /* optimize select */          /* optimize select */
        for (i = r->root_kq - 1; i > 2; i--)        for (i = r->root_kq - 1; i >= 0; i--)
                if (FD_ISSET(i, &r->root_fds[0]) || FD_ISSET(i, &r->root_fds[1]))                if (FD_ISSET(i, &r->root_fds[0]) || 
                                 FD_ISSET(i, &r->root_fds[1]) || 
                                 FD_ISSET(i, &r->root_fds[2]))
                         break;                          break;
        if (i > 2)        r->root_kq = i + 1;
                r->root_kq = i + 1; 
 }  }
 #endif  #endif
   
Line 1391  sched_hook_fetch(void *root, void *arg __unused) Line 1439  sched_hook_fetch(void *root, void *arg __unused)
 #elif SUP_ENABLE == EP_SUPPORT  #elif SUP_ENABLE == EP_SUPPORT
         if ((en = epoll_wait(r->root_kq, res, KQ_EVENTS, timeout)) == -1) {          if ((en = epoll_wait(r->root_kq, res, KQ_EVENTS, timeout)) == -1) {
 #else  #else
        rfd = xfd = r->root_fds[0];        xfd = r->root_fds[2];
         rfd = r->root_fds[0];
         wfd = r->root_fds[1];          wfd = r->root_fds[1];
         if ((en = select(r->root_kq, &rfd, &wfd, &xfd, timeout)) == -1) {          if ((en = select(r->root_kq, &rfd, &wfd, &xfd, timeout)) == -1) {
 #endif  /* KQ_SUPPORT */  #endif  /* KQ_SUPPORT */

Removed from v.1.35  
changed lines
  Added in v.1.39


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