void rte_orte_progress (void) { if (!opal_using_threads()) opal_progress(); }
pid_t orte_waitpid(pid_t wpid, int *status, int options) { pending_pids_item_t *pending = NULL; blk_waitpid_data_t *data = NULL; struct timespec spintime; pid_t ret; if ((wpid <= 0) || (0 != (options & WUNTRACED))) { errno = ORTE_ERR_NOT_IMPLEMENTED; return (pid_t) -1; } OPAL_THREAD_LOCK(&mutex); do_waitall(options); pending = find_pending_pid(wpid, false); if (NULL != pending) { *status = pending->status; ret = pending->pid; opal_list_remove_item(&pending_pids, (opal_list_item_t*) pending); OBJ_RELEASE(pending); goto cleanup; } if (0 == (options & WNOHANG)) { /* blocking - create a blk_waitpid_data_t, register the callback with it, and wait for the trigger. Hold mutex until after we register so that waitpid isn't called before the callback is registered. There is a race condition between starting to sit in the condition_wait and the callback being triggered, so poll for completion on the event just in case. */ data = OBJ_NEW(blk_waitpid_data_t); if (NULL == data) { ret = -1; goto cleanup; } register_callback(wpid, blk_waitpid_cb, data); while (0 == data->done) { spintime.tv_sec = 0; spintime.tv_nsec = 1 * 1000 * 1000; /* 1 milliseconds */ opal_condition_timedwait(data->cond, &mutex, &spintime); /* if we have pthreads and progress threads and we are the event thread, opal_condition_timedwait won't progress anything, so we need to do it. */ #if OPAL_HAVE_POSIX_THREADS && ORTE_ENABLE_PROGRESS_THREADS if (opal_using_threads()) { opal_mutex_unlock(&mutex); opal_event_loop(opal_event_base, OPAL_EVLOOP_NONBLOCK); opal_mutex_lock(&mutex); } #endif do_waitall(0); } ret = wpid; *status = data->status; /* Unlock the mutex first, so as to not cause any deadlocks. We aren't going to touch any variables that could cause problems with thread badness, so it's ok to be here without the thread locked. Wich is also the reason we go to done instead of cleanup. */ OPAL_THREAD_UNLOCK(&mutex); while (0 == data->free) { /* don't free the condition variable until we are positive that the broadcast is done being sent. Otherwise, pthreads gets really unhappy when we pull the rug out from under it. Yes, it's spinning. No, we won't spin for long. */ if (!OPAL_ENABLE_MULTI_THREADS) { opal_event_loop(opal_event_base, OPAL_EVLOOP_NONBLOCK); } } OBJ_RELEASE(data); /* see note above while loop for why we jump to done */ goto done; } else { /* non-blocking - return what waitpid would */ ret = waitpid(wpid, status, options); } cleanup: OPAL_THREAD_UNLOCK(&mutex); done: return ret; }