#include #include #include #include #include #include #include #include struct join_cond_st { pthread_mutex_t join_alarm_mutex; pthread_cond_t join_alarm_cond; THREAD_T thread; }; static T_PROC_RET join_thread (void * arg) { int status; struct join_cond_st * join_cond = (struct join_cond_st *) arg; THREAD_CANCEL_ENABLE; THREAD_CANCEL_ASYNC; pthread_join (join_cond->thread, NULL); status = pthread_cond_signal (&(join_cond->join_alarm_cond)); if (status != 0) { perror ("problem with sending signal within join"); } return NULL; } THREAD_T thread_new (T_PROC_RET (*t_proc)(void *), void* arg) { THREAD_T handle; if (pthread_create (&handle, NULL, t_proc, arg) != 0) { SCOT_MEM_ZERO (&handle, sizeof (THREAD_T)); } return handle; } void thread_end (THREAD_T thread, uint32_t timeout) { int err; err = CANCEL_THREAD (thread); if (err != 0) THROW (EXC (EXC_ERROR, err, "[EVENT_SOURCE_THREAD]cancel request failed")); err = JOIN_THREAD (thread, timeout); if (err == JOIN_TIMEOUT) THROW (EXC (EXC_ERROR, err, "[EVENT_SOURCE_THREAD]timeout exceeded while waiting " "for threads end")); if (err == JOIN_ERROR) THROW (EXC (EXC_ERROR, err, "[EVENT_SOURCE_THREAD]failure on waiting for threads end")); } int thread_join (THREAD_T thread, uint32_t timeout) { int status, join_state = JOIN_OK; struct timespec alarm; pthread_t join_thr; struct join_cond_st join_cond = { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, thread }; if (timeout == INFINITE) { if (pthread_join (thread, NULL) == 0) { return JOIN_OK; } else { return JOIN_ERROR; } } alarm.tv_sec = time (NULL) + timeout; alarm.tv_nsec = 0; status = pthread_mutex_lock (&join_cond.join_alarm_mutex); if (status != 0) { perror ("problem achiving mutex within join"); } join_thr = NEW_THREAD (join_thread, (void *) &join_cond); status = pthread_cond_timedwait ( &(join_cond.join_alarm_cond), &(join_cond.join_alarm_mutex), &alarm); if (status != 0) { if (status == ETIMEDOUT) { join_state = JOIN_TIMEOUT; pthread_cancel (join_thr); pthread_join (join_thr, NULL); } else { perror ("problem with condition wait within join"); } } return join_state; } void thread_mutex_new (THREAD_MUTEX_T * mutex) { pthread_mutex_init (mutex, NULL); } void thread_cond_new (THREAD_COND_T * cond) { pthread_cond_init (cond, NULL); } int thread_mutex_lock (THREAD_MUTEX_T * mutex) { if (pthread_mutex_lock (mutex) == 0) { return MUTEX_LOCK_OK; } else { return MUTEX_LOCK_ERROR; } } int thread_cond_wait (THREAD_COND_T * cond, THREAD_COND_CS_T * cs, uint32_t t) { if (t == INFINITE) return pthread_cond_wait (cond, cs); else { struct timespec tout; tout.tv_sec = time (NULL) + t; tout.tv_nsec = 0; return pthread_cond_timedwait (cond, cs, &tout); } }