// returns 0 on success to take mutex, -1 on genric failure of releasing mutex, -2 on failure upon null pointer. m is pointer obtained w/ ace_mutex_new(), int8_t ace_mutex_release(void* m) { ACE_Recursive_Thread_Mutex* acemtx = (ACE_Recursive_Thread_Mutex*)m; if(NULL == acemtx) { return(-2); } acemtx->release(); return(0); }
// returns 0 on success to take mutex, -3 on failure upon timeout, -2 on failure upon null pointer. m is pointer obtained w/ ace_mutex_new(), tout_usec is in microsec (no timeout is 0xffffffff). int8_t ace_mutex_take(void* m, uint32_t tout_usec) { ACE_Recursive_Thread_Mutex* acemtx = (ACE_Recursive_Thread_Mutex*)m; if(NULL == acemtx) { return(-2); } acemtx->acquire(); return(0); }
int ThreadTest::run(bool doubleLock) { ACE_hthread_t m_workerThreadHandle; ACE_thread_t m_workerThreadId; m_workerRunning = false; m_doubleLock = doubleLock; m_mutex.acquire(); // Start worker thread int rval = ACE_Thread::spawn((ACE_THR_FUNC) workerThreadWrapper, this, THR_JOINABLE | THR_NEW_LWP, &m_workerThreadId, &m_workerThreadHandle, ACE_DEFAULT_THREAD_PRIORITY); if (rval == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%t Could not start worker thread!\n")), 1); } if (!m_workerRunning) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%t Waiting for worker thread to start running...\n"))); m_startedCondition.wait(); } ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%t Worker thread is running...\n"))); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%t Broadcasting STOP Condition...\n"))); m_stopCondition.broadcast(); m_mutex.release(); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%t Joining worker thread...\n"))); ACE_Thread::join(m_workerThreadHandle); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%t Test finished...\n"))); return 0; }
int ACE_Condition<ACE_Recursive_Thread_Mutex>::wait (ACE_Recursive_Thread_Mutex &mutex, const ACE_Time_Value *abstime) { ACE_recursive_mutex_state mutex_state_holder; ACE_recursive_thread_mutex_t &recursive_mutex = mutex.lock (); if (ACE_OS::recursive_mutex_cond_unlock (&recursive_mutex, mutex_state_holder) == -1) return -1; // We wait on the condition, specifying the nesting mutex. For platforms // with ACE_HAS_RECURSIVE_MUTEXES, this is the recursive mutex itself, // and is the same as recursive_mutex, above. The caller should have been // holding the lock on entry to this method, and it is still held. // For other platforms, this is the nesting mutex that guards the // ACE_recursive_mutex_t internals, and recursive_mutex_cond_unlock() // returned with the lock held, but waiters primed and waiting to be // released. At cond_wait below, the mutex will be released. // On return, it will be reacquired. int const result = abstime == 0 ? ACE_OS::cond_wait (&this->cond_, &mutex.get_nesting_mutex ()) : ACE_OS::cond_timedwait (&this->cond_, &mutex.get_nesting_mutex (), const_cast <ACE_Time_Value *> (abstime)); // We are holding the mutex, whether the wait succeeded or failed. // Stash errno (in case it failed) and then we need to reset the // recursive mutex state to what it was on entry to this method. // Resetting it may require a wait for another thread to release // the ACE_recursive_thread_mutex_t if this is a platform without // ACE_HAS_RECURSIVE_MUTEXES, and recursive_mutex_cond_relock() takes // care of that. { ACE_Errno_Guard error (errno); ACE_OS::recursive_mutex_cond_relock (&recursive_mutex, mutex_state_holder); } return result; }