diff options
author | Yorhel <git@yorhel.nl> | 2013-02-19 13:35:11 +0100 |
---|---|---|
committer | Yorhel <git@yorhel.nl> | 2013-02-19 13:38:37 +0100 |
commit | 319b7f93a4e9b4457f4593c9be1ec21500f47f0e (patch) | |
tree | 6ea0247da87499e30229bd9395e862f823ea26d8 | |
parent | 3f1e48f2e00480fdb59a2cc095ba60fd107cdf6c (diff) |
evtp: Don't hold a reference on the ev loop when nothing is queued
-rw-r--r-- | evtp.c | 8 | ||||
-rw-r--r-- | evtp.h | 9 | ||||
-rw-r--r-- | test/evtp.c | 5 |
3 files changed, 14 insertions, 8 deletions
@@ -75,6 +75,7 @@ static void evtp_async(EV_P_ ev_async *async, int revents) { items = items->next; /* Don't use 'first' after this function, application may have free()d it. */ func(first); + ev_unref(EV_A); } } @@ -91,6 +92,7 @@ evtp_t *evtp_create(EV_P_ int maxthreads) { ev_async_init(&tp->async, evtp_async); ev_async_start(EV_A_ &tp->async); + ev_unref(EV_A); tp->async.data = tp; #if EV_MULTIPLICITY tp->loop = loop; @@ -140,6 +142,7 @@ int evtp_destroy(evtp_t *threadpool) { pthread_cond_destroy(&threadpool->cond); pthread_cond_destroy(&threadpool->die_cond); pthread_mutex_destroy(&threadpool->lock); + ev_ref(EV_A); ev_async_stop(EV_A_ &threadpool->async); free(threadpool); return 1; @@ -247,6 +250,9 @@ static int evtp_new_thread(evtp_t *threadpool) { int evtp_submit(evtp_work_t *work, evtp_t *threadpool, evtp_func_t work_func, evtp_func_t done_func) { int rc = 0; int dosignal = 1; +#if EV_MULTIPLICITY + struct ev_loop *loop = threadpool->loop; +#endif work->work_func = work_func; work->done_func = done_func; @@ -266,6 +272,8 @@ int evtp_submit(evtp_work_t *work, evtp_t *threadpool, evtp_func_t work_func, ev pthread_cond_signal(&threadpool->cond); pthread_mutex_unlock(&threadpool->lock); + ev_ref(EV_A); + return rc; } @@ -31,9 +31,7 @@ THE SOFTWARE. * 3. https://github.com/jech/threadpool * * TODO: - * - Figure out shutdown * - Convenient create_work_object_and_submit() - * - Don't hold a ref on the libev loop when nothing is queued? * - Cancellation? * - Allow done_func = NULL? (Implies auto-free()-work-object-when-done) */ @@ -59,7 +57,12 @@ struct evtp_work_t { }; -/* Create a new thread pool. May return NULL if malloc() fails. */ +/* Create a new thread pool. May return NULL if malloc() fails. + * + * The thread pool object itself does not hold a reference on the ev loop. Each + * evtp_work_t object in the queue, however, does. This way, ev_run() may quit + * even when a thread pool object is alive, but it will never quit as long + * there is still work to do. */ evtp_t *evtp_create(EV_P_ int maxthreads); diff --git a/test/evtp.c b/test/evtp.c index 4c5f0d6..67d3d37 100644 --- a/test/evtp.c +++ b/test/evtp.c @@ -71,14 +71,9 @@ static void done_cb(evtp_work_t *w) { w = calloc(1, sizeof(evtp_work_t)); w->data = data; evtp_submit(w, tp, work_cb, done_cb); - return; } } #endif - - /* TODO: Shouldn't be necessary when evtp drops its ref when nothing is queued */ - if(done == 50) - ev_break(EV_DEFAULT_ EVBREAK_ONE); } |