--- libaitsched/src/hooks.c 2014/06/03 20:42:48 1.27.2.7 +++ libaitsched/src/hooks.c 2014/06/05 22:16:00 1.27.2.8 @@ -3,7 +3,7 @@ * by Michael Pounov * * $Author: misho $ -* $Id: hooks.c,v 1.27.2.7 2014/06/03 20:42:48 misho Exp $ +* $Id: hooks.c,v 1.27.2.8 2014/06/05 22:16:00 misho Exp $ * ************************************************************************** The ELWIX and AITNET software is distributed under the following @@ -56,6 +56,76 @@ transit_task2ready(sched_task_t * __restrict t, sched_ insert_task_to(t, &(TASK_ROOT(t))->root_ready); } +#ifdef HAVE_LIBPTHREAD +static void * +_sched_threadWrapper(sched_task_t *t) +{ + void *ret = NULL; + sched_root_task_t *r; + + if (!t || !TASK_ROOT(t)) + pthread_exit(ret); + else + r = (sched_root_task_t*) TASK_ROOT(t); + + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + /* + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL); + */ + + /* notify parent, thread is ready for execution */ + pthread_testcancel(); + + ret = schedCall(t); + r->root_ret = ret; + + if (TASK_VAL(t)) { + transit_task2unuse(t, &r->root_thread); + TASK_VAL(t) = 0; + } + + pthread_exit(ret); +} +#endif + +#if 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) +{ + sched_task_t *task; + void *ret; + + if (!t || !TASK_ROOT(t) || !TASK_DATA(t)) + return NULL; + else { + task = (sched_task_t*) TASK_DATA(t); + timer_delete((timer_t) TASK_DATLEN(t)); + } + + ret = schedCall(task); + + transit_task2unuse(task, &(TASK_ROOT(task))->root_rtc); + return ret; +} +#else +static void +_sched_rtcSigWrapper(int sig, siginfo_t *si, void *uc) +{ + sched_task_t *task; + + if (si && si->si_value.sival_ptr) { + task = (sched_task_t*) si->si_value.sival_ptr; + timer_delete((timer_t) TASK_FLAG(task)); + + TASK_RET(task) = (intptr_t) schedCall(task); + + transit_task2unuse(task, &(TASK_ROOT(task))->root_rtc); + } +} +#endif +#endif + /* * sched_hook_init() - Default INIT hook * @@ -303,7 +373,8 @@ sched_hook_cancel(void *task, void *arg __unused) 0, 0, (void*) TASK_VAL(t)); #endif /* restore signal */ - signal(TASK_VAL(t), SIG_DFL); + if (flg < 2) + signal(TASK_VAL(t), SIG_DFL); #endif break; #ifdef AIO_SUPPORT @@ -398,7 +469,21 @@ sched_hook_cancel(void *task, void *arg __unused) #if 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 schedCancel((sched_task_t*) TASK_RET(t)); +#else + /* check for multi subscribers */ + flg = 0; + TAILQ_FOREACH_SAFE(tt, &r->root_rtc, task_node, tmp) + if (TASK_DATA(tt) != TASK_DATA(t)) + continue; + else + flg++; + + /* restore signal */ + if (flg < 2) + signal((intptr_t) TASK_DATA(t) + SIGRTMIN, SIG_DFL); +#endif return NULL; #endif /* HAVE_TIMER_CREATE */ default: @@ -726,24 +811,6 @@ sched_hook_signal(void *task, void *arg __unused) LOGERR; return (void*) -1; } -#else -#if 0 - sched_task_t *t = task; - struct sigaction sa; - - memset(&sa, 0, sizeof sa); - sigemptyset(&sa.sa_mask); - sa.sa_handler = _sched_sigHandler; - sa.sa_flags = SA_RESETHAND | SA_RESTART; - - if (sigaction(TASK_VAL(t), &sa, NULL) == -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; - } -#endif /* 0 */ #endif return NULL; } @@ -1438,6 +1505,9 @@ sched_hook_rtc(void *task, void *arg __unused) struct itimerspec its; struct sigevent evt; timer_t tmr; +#if SUP_ENABLE != KQ_SUPPORT + struct sigaction sa; +#endif if (!t || !TASK_ROOT(t)) return (void*) -1; @@ -1445,7 +1515,7 @@ sched_hook_rtc(void *task, void *arg __unused) memset(&evt, 0, sizeof evt); evt.sigev_notify = SIGEV_SIGNAL; evt.sigev_signo = (intptr_t) TASK_DATA(t) + SIGRTMIN; - evt.sigev_value.sival_ptr = TASK_DATA(t); + evt.sigev_value.sival_ptr = t; if (timer_create(CLOCK_MONOTONIC, &evt, &tmr) == -1) { if (TASK_ROOT(t)->root_hooks.hook_exec.exception) @@ -1456,6 +1526,7 @@ sched_hook_rtc(void *task, void *arg __unused) } else TASK_FLAG(t) = (u_long) tmr; +#if SUP_ENABLE == KQ_SUPPORT if (!(sigt = schedSignal(TASK_ROOT(t), _sched_rtcWrapper, TASK_ARG(t), evt.sigev_signo, t, (size_t) tmr))) { if (TASK_ROOT(t)->root_hooks.hook_exec.exception) @@ -1466,6 +1537,21 @@ sched_hook_rtc(void *task, void *arg __unused) return (void*) -1; } else TASK_RET(t) = (uintptr_t) sigt; +#else + memset(&sa, 0, sizeof sa); + sigemptyset(&sa.sa_mask); + sa.sa_sigaction = _sched_rtcSigWrapper; + sa.sa_flags = SA_SIGINFO | SA_RESTART; + + if (sigaction(evt.sigev_signo, &sa, NULL) == -1) { + if (TASK_ROOT(t)->root_hooks.hook_exec.exception) + TASK_ROOT(t)->root_hooks.hook_exec.exception(TASK_ROOT(t), NULL); + else + LOGERR; + timer_delete(tmr); + return (void*) -1; + } +#endif memset(&its, 0, sizeof its); its.it_value.tv_sec = t->task_val.ts.tv_sec;