static void * looper_thread(void *arg) { int r; void (*cleanup)(void *); struct looper_thread_share *ts = (struct looper_thread_share *)arg; dfpr("looper thread"); r = ymsglooper_create(0, ts->destroy_on_exit); fatali0(pthread_mutex_lock(&ts->lock)); if (unlikely(r)) { ts->result = r; goto cond_done; } ts->result = 1; /* success */ ts->ml = ymsglooper_get(); cond_done: fatali0(pthread_cond_broadcast(&ts->cond)); fatali0(pthread_mutex_unlock(&ts->lock)); if (unlikely(r)) return NULL; cleanup = ts->destroy_on_exit? &destroy_msglooper: &dummy_do_nothing; pthread_cleanup_push(cleanup, ts->ml); ymsglooper_loop(); pthread_cleanup_pop(1); /* execute cleanup */ return NULL; }
int ymsglooper_create(int msgq_capacity, bool destroy_on_exit) { struct ymsglooper *ml; ml = ymsglooper_get(); if (unlikely(ml)) /* looper is already assigned! */ return -EPERM; ml = create_msglooper(pthread_self(), msgq_capacity); if (unlikely(!ml)) return -EINVAL; /* unknown */ ml->destroy_on_exit = destroy_on_exit; fatali0(pthread_setspecific(_tkey, ml)); set_state(ml, YMSGLOOPER_READY); return 0; }
static void mexit(void) { fatali0(pthread_key_delete(_tkey)); }
static inline void unlock_state(struct ymsglooper *ml) { fatali0(pthread_mutex_unlock(&ml->state_lock)); }
static void destroy_lock(struct ypool *p) { fatali0(pthread_spin_destroy(&p->lock)); }
static inline void unlock(struct ypool *p) { fatali0(pthread_spin_unlock(&p->lock)); }
static void init_lock(struct ypool *p) { fatali0(pthread_spin_init(&p->lock, PTHREAD_PROCESS_PRIVATE)); }