/* * __wt_cond_signal -- * Signal a waiting thread. */ int __wt_cond_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond) { WT_DECL_RET; int locked; locked = 0; /* * !!! * This function MUST handle a NULL session handle. */ if (session != NULL) WT_RET(__wt_verbose(session, WT_VERB_MUTEX, "signal %s cond (%p)", cond->name, cond)); /* Fast path if already signalled. */ if (cond->waiters == -1) return (0); if (cond->waiters > 0 || !__wt_atomic_casi32(&cond->waiters, 0, -1)) { WT_ERR(pthread_mutex_lock(&cond->mtx)); locked = 1; WT_ERR(pthread_cond_broadcast(&cond->cond)); } err: if (locked) WT_TRET(pthread_mutex_unlock(&cond->mtx)); if (ret == 0) return (0); WT_RET_MSG(session, ret, "pthread_cond_broadcast"); }
/* * __wt_cond_signal -- * Signal a waiting thread. */ void __wt_cond_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond) { WT_DECL_RET; __wt_verbose(session, WT_VERB_MUTEX, "signal %s", cond->name); /* * Our callers often set flags to cause a thread to exit. Add a barrier * to ensure exit flags are seen by the sleeping threads, otherwise we * can wake up a thread, it immediately goes back to sleep, and we'll * hang. Use a full barrier (we may not write before waiting on thread * join). */ WT_FULL_BARRIER(); /* * Fast path if we are in (or can enter), a state where the next waiter * will return immediately as already signaled. */ if (cond->waiters == -1 || (cond->waiters == 0 && __wt_atomic_casi32(&cond->waiters, 0, -1))) return; EnterCriticalSection(&cond->mtx); WakeAllConditionVariable(&cond->cond); LeaveCriticalSection(&cond->mtx); }
/* * __wt_cond_signal -- * Signal a waiting thread. */ int __wt_cond_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond) { WT_DECL_RET; bool locked; locked = false; /* * !!! * This function MUST handle a NULL session handle. */ if (session != NULL) WT_RET(__wt_verbose(session, WT_VERB_MUTEX, "signal %s cond (%p)", cond->name, cond)); /* Fast path if already signalled. */ if (cond->waiters == -1) return (0); if (cond->waiters > 0 || !__wt_atomic_casi32(&cond->waiters, 0, -1)) { EnterCriticalSection(&cond->mtx); locked = true; WakeAllConditionVariable(&cond->cond); } if (locked) LeaveCriticalSection(&cond->mtx); if (ret == 0) return (0); WT_RET_MSG(session, ret, "WakeAllConditionVariable"); }