From c1bb5b68d033a35fd0ef23e27fa53e83a3d6a3c0 Mon Sep 17 00:00:00 2001 From: Ralph Castain Date: Tue, 22 Jul 2014 16:55:23 +0000 Subject: [PATCH] It is possible to have a "standard" progress thread, so simplify the usage of the opal_progress_thread code. This commit was SVN r32277. --- opal/runtime/opal_progress_threads.c | 23 ++++++++++++++++++----- opal/runtime/opal_progress_threads.h | 7 +++---- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/opal/runtime/opal_progress_threads.c b/opal/runtime/opal_progress_threads.c index 18b3ea6f89..06f8128997 100644 --- a/opal/runtime/opal_progress_threads.c +++ b/opal/runtime/opal_progress_threads.c @@ -23,6 +23,7 @@ typedef struct { opal_list_item_t super; char *name; opal_event_base_t *ev_base; + volatile bool ev_active; bool block_active; opal_event_t block; bool engine_defined; @@ -33,6 +34,7 @@ static void trkcon(opal_progress_tracker_t *p) { p->name = NULL; p->ev_base = NULL; + p->ev_active = true; p->block_active = false; p->engine_defined = false; p->pipe[0] = -1; @@ -74,10 +76,17 @@ static void wakeup(int fd, short args, void *cbdata) * it so we don't try to delete it again */ trk->block_active = false; } +static void* progress_engine(opal_object_t *obj) +{ + opal_progress_tracker_t *trk = (opal_progress_tracker_t*)obj; + while (trk->ev_active) { + opal_event_loop(trk->ev_base, OPAL_EVLOOP_ONCE); + } + return OPAL_THREAD_CANCELLED; +} opal_event_base_t *opal_start_progress_thread(char *name, - opal_thread_fn_t func, bool create_block) { opal_progress_tracker_t *trk; @@ -115,7 +124,8 @@ opal_event_base_t *opal_start_progress_thread(char *name, OBJ_CONSTRUCT(&trk->engine, opal_thread_t); trk->engine_defined = true; /* fork off a thread to progress it */ - trk->engine.t_run = func; + trk->engine.t_run = progress_engine; + trk->engine.t_arg = trk; if (OPAL_SUCCESS != (rc = opal_thread_start(&trk->engine))) { OPAL_ERROR_LOG(rc); OBJ_RELEASE(trk); @@ -142,15 +152,18 @@ void opal_stop_progress_thread(char *name, bool cleanup) /* find the specified engine */ OPAL_LIST_FOREACH(trk, &tracking, opal_progress_tracker_t) { if (0 == strcmp(name, trk->name)) { + /* mark it as inactive */ + trk->ev_active = false; + /* break the event loop - this will cause the loop to exit + * upon completion of any current event */ + opal_event_base_loopbreak(trk->ev_base); /* if present, use the block to break it loose just in - * case the thread is blocking in a call to select for + * case the thread is blocked in a call to select for * a long time */ if (trk->block_active) { i=1; write(trk->pipe[1], &i, sizeof(int)); } - /* break the event loop */ - opal_event_base_loopbreak(trk->ev_base); /* wait for thread to exit */ opal_thread_join(&trk->engine, NULL); /* cleanup, if they indicated they are done with this event base */ diff --git a/opal/runtime/opal_progress_threads.h b/opal/runtime/opal_progress_threads.h index 8bfe87b777..b66097b376 100644 --- a/opal/runtime/opal_progress_threads.h +++ b/opal/runtime/opal_progress_threads.h @@ -14,13 +14,12 @@ #include "opal/mca/event/event.h" -/* start a progress thread using the given function, assigning - * it the provided name for tracking purposes. This function will - * also create a pipe so that libevent has something to block +/* start a progress thread, assigning it the provided name for + * tracking purposes. If create_block is true, then this function + * will also create a pipe so that libevent has something to block * against, thus keeping the thread from free-running */ OPAL_DECLSPEC opal_event_base_t *opal_start_progress_thread(char *name, - opal_thread_fn_t func, bool create_block); /* stop the progress thread of the provided name. This function will