bool dxEventObject::WaitInfinitely() { bool result = false; int lock_result = pthread_mutex_lock(&m_event_mutex); dICHECK(lock_result == EOK); int wait_result = EOK; if (!m_event_value) { wait_result = pthread_cond_wait(&m_event_cond, &m_event_mutex); dICHECK(wait_result != EINTR); // Would caller be so kind to disable signal handling for thread for duration of the call to ODE at least? } if (wait_result == EOK) { dIASSERT(m_event_value); if (!m_event_manual) { m_event_value = false; } result = true; } int unlock_result = pthread_mutex_unlock(&m_event_mutex); dICHECK(unlock_result == EOK); return result; }
void dxEventObject::ResetEvent() { int lock_result = pthread_mutex_lock(&m_event_mutex); dICHECK(lock_result == EOK); m_event_value = false; int unlock_result = pthread_mutex_unlock(&m_event_mutex); dICHECK(unlock_result == EOK); }
void dxEventObject::FinalizeObject() { if (m_event_allocated) { int mutex_destroy_result = pthread_mutex_destroy(&m_event_mutex); dICHECK(mutex_destroy_result == EOK); // Why would mutex be unable to be destroyed? int cond_destroy_result = pthread_cond_destroy(&m_event_cond); dICHECK(cond_destroy_result == EOK); // Why would condvar be unable to be destroyed? m_event_allocated = false; } }
void dxEventObject::SetEvent() { int lock_result = pthread_mutex_lock(&m_event_mutex); dICHECK(lock_result == EOK); if (!m_event_value) { m_event_value = true; // NOTE! Event only releases a single thread even for manual mode to simplify implementation. int signal_result = pthread_cond_signal(&m_event_cond); dICHECK(signal_result == EOK); } int unlock_result = pthread_mutex_unlock(&m_event_mutex); dICHECK(unlock_result == EOK); }
void dxThreadPoolThreadInfo::ExecuteThreadCommand(dxTHREADCOMMAND command, void *param, bool wait_response) { bool acknowledgement_wait_result = m_acknowledgement_event.WaitInfinitely(); dICHECK(acknowledgement_wait_result); m_acknowledgement_event.ResetEvent(); m_command_code = command; m_command_param = param; m_command_event.SetEvent(); if (wait_response) { bool new_acknowledgement_wait_result = m_acknowledgement_event.WaitInfinitely(); dICHECK(new_acknowledgement_wait_result); } }
void dxThreadPoolThreadInfo::WaitAndCloseThreadHandle(HANDLE thread_handle) { DWORD thread_wait_result = WaitForSingleObject(thread_handle, INFINITE); dICHECK(thread_wait_result == WAIT_OBJECT_0); BOOL thread_close_result = CloseHandle(thread_handle); dIVERIFY(thread_close_result); }
bool dxThreadPoolThreadInfo::WaitInitStatus() { bool acknowledgement_wait_result = m_acknowledgement_event.WaitInfinitely(); dICHECK(acknowledgement_wait_result); DWORD error_code = (DWORD)(size_t)m_command_param; bool init_status = error_code == ERROR_SUCCESS ? true : (SetLastError(error_code), false); return init_status; }
bool dxThreadPoolThreadInfo::WaitInitStatus() { bool acknowledgement_wait_result = m_acknowledgement_event.WaitInfinitely(); dICHECK(acknowledgement_wait_result); int error_code = (int)(size_t)m_command_param; bool init_status = error_code == EOK ? true : ((errno = error_code), false); return init_status; }
void dxEventObject::FinalizeObject() { HANDLE event_handle = m_event_handle; if (event_handle != NULL) { BOOL close_result = ::CloseHandle(event_handle); dICHECK(close_result); // Object destruction should always succeed m_event_handle = NULL; } }
void dxThreadingThreadPool::ServeThreadingImplementation(dThreadingImplementationID impl) { dxThreadPoolThreadInfo::dxServeImplementationParams params(impl, &m_ready_wait_event); dxThreadPoolThreadInfo *const infos_end = m_thread_infos + m_thread_count; for (dxThreadPoolThreadInfo *current_info = m_thread_infos; current_info != infos_end; ++current_info) { current_info->ExecuteThreadCommand(dxThreadPoolThreadInfo::dxTHREAD_COMMAND_SERVE_IMPLEMENTATION, ¶ms, true); bool ready_wait_result = m_ready_wait_event.WaitInfinitely(); dICHECK(ready_wait_result); } }
void dxThreadPoolThreadInfo::RunCommandHandlingLoop() { bool exit_requested = false; while (!exit_requested) { bool command_wait_result = m_command_event.WaitInfinitely(); dICHECK(command_wait_result); const dxTHREADCOMMAND command_code = m_command_code; switch (command_code) { case dxTHREAD_COMMAND_EXIT: { m_acknowledgement_event.SetEvent(); exit_requested = true; break; } default: { dIASSERT(false); // break; -- proceed to case dxTHREAD_COMMAND_NOOP } case dxTHREAD_COMMAND_NOOP: { m_acknowledgement_event.SetEvent(); // Do nothing break; } case dxTHREAD_COMMAND_SERVE_IMPLEMENTATION: { const dxServeImplementationParams *serve_params = (const dxServeImplementationParams *)m_command_param; dThreadingImplementationID impl = serve_params->m_impl; dxEventObject *ready_wait_event = serve_params->m_ready_wait_event; m_acknowledgement_event.SetEvent(); ThreadedServeImplementation(impl, ready_wait_event); break; } } } }
static void OPCODEAbort() { dICHECK(!"OPCODE Library Abort"); }
void dxEventObject::ResetEvent() { BOOL reset_result = ::ResetEvent(m_event_handle); dICHECK(reset_result); }
void dxThreadPoolThreadInfo::WaitAndCloseThreadHandle(pthread_t thread_handle) { int join_result = pthread_join(thread_handle, NULL); dICHECK(join_result == EOK); }