--- libaitsched/src/hooks.c 2014/06/05 22:16:00 1.27.2.8 +++ libaitsched/src/hooks.c 2017/08/31 12:22:16 1.31.2.3 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: hooks.c,v 1.27.2.8 2014/06/05 22:16:00 misho Exp $ +* $Id: hooks.c,v 1.31.2.3 2017/08/31 12:22:16 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -12,7 +12,7 @@ terms: All of the documentation and software included in the ELWIX and AITNET Releases is copyrighted by ELWIX - Sofia/Bulgaria -Copyright 2004 - 2014 +Copyright 2004 - 2017 by Michael Pounov . All rights reserved. Redistribution and use in source and binary forms, with or without @@ -88,7 +88,8 @@ _sched_threadWrapper(sched_task_t *t) } #endif -#if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME) && defined(HAVE_TIMER_DELETE) +#if defined(HAVE_LIBRT) && defined(HAVE_TIMER_CREATE) && \ + defined(HAVE_TIMER_SETTIME) && defined(HAVE_TIMER_DELETE) #if SUP_ENABLE == KQ_SUPPORT static void * _sched_rtcWrapper(sched_task_t *t) @@ -244,13 +245,14 @@ sched_hook_cancel(void *task, void *arg __unused) #endif #elif SUP_ENABLE == EP_SUPPORT ee.data.fd = TASK_FD(t); + ee.events ^= ee.events; if (FD_ISSET(TASK_FD(t), &r->root_fds[1])) ee.events = EPOLLOUT; if (flg < 2) FD_CLR(TASK_FD(t), &r->root_fds[0]); else - ee.events |= (EPOLLIN | EPOLLPRI | EPOLLRDHUP); + ee.events |= EPOLLIN | EPOLLPRI; #else if (flg < 2) { FD_CLR(TASK_FD(t), &r->root_fds[0]); @@ -282,8 +284,9 @@ sched_hook_cancel(void *task, void *arg __unused) #endif #elif SUP_ENABLE == EP_SUPPORT ee.data.fd = TASK_FD(t); + ee.events ^= ee.events; if (FD_ISSET(TASK_FD(t), &r->root_fds[0])) - ee.events = EPOLLIN | EPOLLPRI | EPOLLRDHUP; + ee.events = EPOLLIN | EPOLLPRI; if (flg < 2) FD_CLR(TASK_FD(t), &r->root_fds[1]); @@ -466,7 +469,8 @@ sched_hook_cancel(void *task, void *arg __unused) } #endif return NULL; -#if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME) && defined(HAVE_TIMER_DELETE) +#if defined(HAVE_LIBRT) && defined(HAVE_TIMER_CREATE) && \ + defined(HAVE_TIMER_SETTIME) && defined(HAVE_TIMER_DELETE) case taskRTC: timer_delete((timer_t) TASK_FLAG(t)); #if SUP_ENABLE == KQ_SUPPORT @@ -551,7 +555,7 @@ sched_hook_read(void *task, void *arg __unused) struct kevent chg[1]; struct timespec timeout = { 0, 0 }; #elif SUP_ENABLE == EP_SUPPORT - struct epoll_event ee = { .events = EPOLLIN | EPOLLPRI | EPOLLRDHUP, .data.fd = 0 }; + struct epoll_event ee = { .events = EPOLLIN | EPOLLPRI, .data.fd = 0 }; int flg = 0; #endif @@ -640,7 +644,7 @@ sched_hook_write(void *task, void *arg __unused) #elif SUP_ENABLE == EP_SUPPORT if (FD_ISSET(TASK_FD(t), &r->root_fds[0])) { flg |= 1; - ee.events |= EPOLLIN | EPOLLPRI | EPOLLRDHUP; + ee.events |= EPOLLIN | EPOLLPRI; } if (FD_ISSET(TASK_FD(t), &r->root_fds[1])) flg |= 2; @@ -859,7 +863,7 @@ static inline void fetch_hook_kevent_proceed(int en, struct kevent *res, sched_root_task_t *r) { struct kevent evt[1]; - register int i, flg; + register int i; sched_task_t *task, *tmp; struct timespec now = { 0, 0 }; #ifdef AIO_SUPPORT @@ -867,7 +871,6 @@ fetch_hook_kevent_proceed(int en, struct kevent *res, struct aiocb *acb; #ifdef EVFILT_LIO int l; - register int j; off_t off; struct aiocb **acbs; struct iovec *iv; @@ -880,12 +883,10 @@ fetch_hook_kevent_proceed(int en, struct kevent *res, /* Put read/write task to ready queue */ switch (res[i].filter) { case EVFILT_READ: - flg = 0; TAILQ_FOREACH_SAFE(task, &r->root_read, task_node, tmp) { if (TASK_FD(task) != ((intptr_t) res[i].udata)) continue; else { - flg++; TASK_RET(task) = res[i].data; TASK_FLAG(task) = (u_long) res[i].fflags; } @@ -905,17 +906,12 @@ fetch_hook_kevent_proceed(int en, struct kevent *res, insert_task_to(task, &r->root_ready); } } - /* if match at least 2, don't remove resouce of event */ - if (flg > 1) - evt->flags ^= evt->flags; break; case EVFILT_WRITE: - flg = 0; TAILQ_FOREACH_SAFE(task, &r->root_write, task_node, tmp) { if (TASK_FD(task) != ((intptr_t) res[i].udata)) continue; else { - flg++; TASK_RET(task) = res[i].data; TASK_FLAG(task) = (u_long) res[i].fflags; } @@ -935,87 +931,62 @@ fetch_hook_kevent_proceed(int en, struct kevent *res, insert_task_to(task, &r->root_ready); } } - /* if match at least 2, don't remove resouce of event */ - if (flg > 1) - evt->flags ^= evt->flags; 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++; TASK_RET(task) = res[i].data; TASK_FLAG(task) = (u_long) res[i].fflags; } /* remove alarm handle */ transit_task2ready(task, &r->root_alarm); } - /* 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_RET(task) = res[i].data; TASK_FLAG(task) = (u_long) res[i].fflags; } /* remove node handle */ transit_task2ready(task, &r->root_node); } - /* 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_RET(task) = res[i].data; TASK_FLAG(task) = (u_long) res[i].fflags; } /* remove proc handle */ transit_task2ready(task, &r->root_proc); } - /* 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++; TASK_RET(task) = res[i].data; TASK_FLAG(task) = (u_long) res[i].fflags; } /* remove signal handle */ transit_task2ready(task, &r->root_signal); } - /* if match at least 2, don't remove resouce of event */ - if (flg > 1) - evt->flags ^= evt->flags; break; #ifdef AIO_SUPPORT case EVFILT_AIO: - flg = 0; TAILQ_FOREACH_SAFE(task, &r->root_aio, task_node, tmp) { acb = (struct aiocb*) TASK_VAL(task); if (acb != ((struct aiocb*) res[i].udata)) continue; else { - flg++; TASK_RET(task) = res[i].data; TASK_FLAG(task) = (u_long) res[i].fflags; } @@ -1032,19 +1003,14 @@ fetch_hook_kevent_proceed(int en, struct kevent *res, TASK_DATLEN(task) = (u_long) len; TASK_FD(task) = fd; } - /* if match at least 2, don't remove resouce of event */ - if (flg > 1) - evt->flags ^= evt->flags; break; #ifdef EVFILT_LIO case EVFILT_LIO: - flg = 0; TAILQ_FOREACH_SAFE(task, &r->root_lio, task_node, tmp) { acbs = (struct aiocb**) TASK_VAL(task); if (acbs != ((struct aiocb**) res[i].udata)) continue; else { - flg++; TASK_RET(task) = res[i].data; TASK_FLAG(task) = (u_long) res[i].fflags; } @@ -1054,7 +1020,7 @@ fetch_hook_kevent_proceed(int en, struct kevent *res, iv = (struct iovec*) TASK_DATA(task); fd = acbs[0]->aio_fildes; off = acbs[0]->aio_offset; - for (j = len = 0; i < TASK_DATLEN(task); len += l, i++) { + for (len = 0; i < TASK_DATLEN(task); len += l, i++) { if ((iv[i].iov_len = aio_return(acbs[i])) == -1) l = 0; else @@ -1068,29 +1034,21 @@ fetch_hook_kevent_proceed(int en, struct kevent *res, if (lseek(fd, off + len, SEEK_CUR) == -1) LOGERR; } - /* if match at least 2, don't remove resouce of event */ - if (flg > 1) - evt->flags ^= evt->flags; break; #endif /* EVFILT_LIO */ #endif /* AIO_SUPPORT */ #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_RET(task) = res[i].data; TASK_FLAG(task) = (u_long) res[i].fflags; } /* remove user handle */ transit_task2ready(task, &r->root_user); } - /* if match at least 2, don't remove resouce of event */ - if (flg > 1) - evt->flags ^= evt->flags; break; #endif /* EVFILT_USER */ } @@ -1109,29 +1067,23 @@ fetch_hook_kevent_proceed(int en, struct kevent *res, static inline void fetch_hook_epoll_proceed(int en, struct epoll_event *res, sched_root_task_t *r) { - register int i, flg; + register int i, flg, oevt; int ops = EPOLL_CTL_DEL; sched_task_t *task, *tmp; struct epoll_event evt[1]; for (i = 0; i < en; i++) { memcpy(evt, &res[i], sizeof evt); + oevt = evt->events & EPOLLOUT; - if (evt->events & (EPOLLIN | EPOLLPRI | EPOLLET)) { + if (evt->events & (EPOLLIN | EPOLLPRI)) { flg = 0; TAILQ_FOREACH_SAFE(task, &r->root_read, task_node, tmp) { if (TASK_FD(task) != evt->data.fd) continue; else { flg++; - FD_CLR(TASK_FD(task), &r->root_fds[0]); TASK_FLAG(task) = ioctl(TASK_FD(task), FIONREAD, &TASK_RET(task)); - - evt->events &= ~(EPOLLIN | EPOLLPRI | EPOLLET | EPOLLRDHUP); - if (FD_ISSET(TASK_FD(task), &r->root_fds[1])) { - ops = EPOLL_CTL_MOD; - evt->events |= EPOLLOUT; - } } /* remove read handle */ remove_task_from(task, &r->root_read); @@ -1150,26 +1102,30 @@ fetch_hook_epoll_proceed(int en, struct epoll_event *r insert_task_to(task, &r->root_ready); } } - if (flg > 1) - ops = EPOLL_CTL_MOD; + + if (flg) { + evt->events ^= evt->events; + if (FD_ISSET(evt->data.fd, &r->root_fds[1])) { + ops = EPOLL_CTL_MOD; + evt->events |= EPOLLOUT; + } + if (flg > 1) { + ops = EPOLL_CTL_MOD; + evt->events |= EPOLLIN | EPOLLPRI; + } else + FD_CLR(evt->data.fd, &r->root_fds[0]); + } } - if (evt->events & EPOLLOUT) { + if (oevt) { flg = 0; TAILQ_FOREACH_SAFE(task, &r->root_write, task_node, tmp) { if (TASK_FD(task) != evt->data.fd) continue; else { flg++; - FD_CLR(TASK_FD(task), &r->root_fds[1]); TASK_FLAG(task) = ioctl(TASK_FD(task), FIONWRITE, &TASK_RET(task)); - - evt->events &= ~EPOLLOUT; - if (FD_ISSET(TASK_FD(task), &r->root_fds[0])) { - ops = EPOLL_CTL_MOD; - evt->events |= EPOLLIN | EPOLLPRI | EPOLLRDHUP; - } } /* remove write handle */ remove_task_from(task, &r->root_write); @@ -1188,8 +1144,19 @@ fetch_hook_epoll_proceed(int en, struct epoll_event *r insert_task_to(task, &r->root_ready); } } - if (flg > 1) - ops = EPOLL_CTL_MOD; + + if (flg) { + evt->events ^= evt->events; + if (FD_ISSET(evt->data.fd, &r->root_fds[0])) { + ops = EPOLL_CTL_MOD; + evt->events |= EPOLLIN | EPOLLPRI; + } + if (flg > 1) { + ops = EPOLL_CTL_MOD; + evt->events |= EPOLLOUT; + } else + FD_CLR(evt->data.fd, &r->root_fds[1]); + } } if (epoll_ctl(r->root_kq, ops, evt->data.fd, evt) == -1) { @@ -1240,7 +1207,7 @@ fetch_hook_select_proceed(int en, fd_set rfd, fd_set w insert_task_to(task, &r->root_ready); } } - /* if match equal to 1, remove resouce */ + /* remove resouce */ if (flg == 1) FD_CLR(i, &r->root_fds[0]); } @@ -1271,7 +1238,7 @@ fetch_hook_select_proceed(int en, fd_set rfd, fd_set w insert_task_to(task, &r->root_ready); } } - /* if match equal to 1, remove resouce */ + /* remove resouce */ if (flg == 1) FD_CLR(i, &r->root_fds[1]); } @@ -1497,10 +1464,11 @@ sched_hook_condition(void *root, void *arg) * @arg = unused * return: <0 errors and 0 ok */ -#if defined(HAVE_TIMER_CREATE) && defined(HAVE_TIMER_SETTIME) && defined(HAVE_TIMER_DELETE) void * sched_hook_rtc(void *task, void *arg __unused) { +#if defined(HAVE_LIBRT) && defined(HAVE_TIMER_CREATE) && \ + defined(HAVE_TIMER_SETTIME) && defined(HAVE_TIMER_DELETE) sched_task_t *sigt = NULL, *t = task; struct itimerspec its; struct sigevent evt; @@ -1566,7 +1534,6 @@ sched_hook_rtc(void *task, void *arg __unused) timer_delete(tmr); return (void*) -1; } - +#endif /* HAVE_TIMER_CREATE */ return NULL; } -#endif /* HAVE_TIMER_CREATE */