| 79 | } |
| 80 | |
| 81 | LIB_PRIVATE |
| 82 | int |
| 83 | timer_create_sigev_thread(clockid_t clock_id, |
| 84 | struct sigevent *evp, |
| 85 | timer_t *timerid, |
| 86 | struct sigevent *sevOut) |
| 87 | { |
| 88 | /* If the user wants notification via a thread we need to handle |
| 89 | this special. */ |
| 90 | JASSERT(evp == NULL || evp->sigev_notify == SIGEV_THREAD); |
| 91 | |
| 92 | /* Create the helper thread. */ |
| 93 | pthread_once(&helper_once, start_helper_thread); |
| 94 | sem_wait(&helper_notification); |
| 95 | if (helper_tid == 0) { |
| 96 | /* No resources to start the helper thread. */ |
| 97 | errno = EAGAIN; |
| 98 | return -1; |
| 99 | } |
| 100 | |
| 101 | struct timer *newp; |
| 102 | newp = (struct timer *)JALLOC_MALLOC(sizeof(struct timer)); |
| 103 | if (newp == NULL) { |
| 104 | return -1; |
| 105 | } |
| 106 | |
| 107 | /* Copy the thread parameters the user provided. */ |
| 108 | newp->sival = evp->sigev_value; |
| 109 | newp->thrfunc = evp->sigev_notify_function; |
| 110 | newp->sigev_notify = SIGEV_THREAD; |
| 111 | |
| 112 | /* We cannot simply copy the thread attributes since the |
| 113 | implementation might keep internal information for |
| 114 | each instance. */ |
| 115 | (void)pthread_attr_init(&newp->attr); |
| 116 | |
| 117 | // TODO: Copy attributes from evp->sigev_notify_attributes to newp->attr. |
| 118 | |
| 119 | /* In any case set the detach flag. */ |
| 120 | (void)pthread_attr_setdetachstate(&newp->attr, PTHREAD_CREATE_DETACHED); |
| 121 | |
| 122 | /* Create the event structure for the kernel timer. */ |
| 123 | sevOut->sigev_value.sival_ptr = newp; |
| 124 | sevOut->sigev_signo = SIGTIMER; |
| 125 | sevOut->sigev_notify = SIGEV_SIGNAL | SIGEV_THREAD_ID; |
| 126 | sevOut->_sigev_un._tid = helper_tid; |
| 127 | |
| 128 | /* Create the timer. */ |
| 129 | int res = _real_timer_create(clock_id, sevOut, timerid); |
| 130 | if (res == 0) { |
| 131 | /* Add to the queue of active timers with thread delivery. */ |
| 132 | DmtcpMutexLock(&active_timer_sigev_thread_lock); |
| 133 | newp->next = active_timer_sigev_thread; |
| 134 | active_timer_sigev_thread = newp; |
| 135 | DmtcpMutexUnlock(&active_timer_sigev_thread_lock); |
| 136 | return 0; |
| 137 | } |
| 138 |
no test coverage detected