bool dxThreadingThreadPool::InitializeThreads(size_t thread_count, size_t stack_size, unsigned int ode_data_allocate_flags) { dIASSERT(m_thread_infos == NULL); bool result = false; bool wait_event_allocated = false; dxThreadPoolThreadInfo *thread_infos = NULL; bool thread_infos_allocated = false; do { if (!m_ready_wait_event.InitializeObject(false, false)) { break; } wait_event_allocated = true; thread_infos = (dxThreadPoolThreadInfo *)dAlloc(thread_count * sizeof(dxThreadPoolThreadInfo)); if (thread_infos == NULL) { break; } thread_infos_allocated = true; if (!InitializeIndividualThreadInfos(thread_infos, thread_count, stack_size, ode_data_allocate_flags)) { break; } m_thread_infos = thread_infos; m_thread_count = thread_count; result = true; } while (false); if (!result) { if (wait_event_allocated) { if (thread_infos_allocated) { dFree(thread_infos, thread_count * sizeof(dxThreadPoolThreadInfo)); } m_ready_wait_event.FinalizeObject(); } } return result; }
void dxThreadPoolThreadInfo::Finalize() { if (m_thread_allocated) { ExecuteThreadCommand(dxTHREAD_COMMAND_EXIT, NULL, false); WaitAndCloseThreadHandle(m_thread_handle); m_thread_allocated = false; m_command_event.FinalizeObject(); m_acknowledgement_event.FinalizeObject(); } }
void dxThreadPoolThreadInfo::Finalize() { HANDLE thread_handle = m_thread_handle; if (thread_handle != NULL) { ExecuteThreadCommand(dxTHREAD_COMMAND_EXIT, NULL, false); WaitAndCloseThreadHandle(thread_handle); m_thread_handle = NULL; m_command_event.FinalizeObject(); m_acknowledgement_event.FinalizeObject(); } }
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; } } } }
void dxThreadPoolThreadInfo::ReportInitStatus(bool init_result) { DWORD error_code; m_command_param = (void *)(size_t)(init_result ? ERROR_SUCCESS : ((error_code = GetLastError()) != ERROR_SUCCESS ? error_code : ERROR_INTERNAL_ERROR)); m_acknowledgement_event.SetEvent(); }
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); } }
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 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 dxThreadingThreadPool::FinalizeThreads() { dxThreadPoolThreadInfo *thread_infos = m_thread_infos; if (thread_infos != NULL) { size_t thread_count = m_thread_count; FinalizeIndividualThreadInfos(thread_infos, thread_count); dFree(thread_infos, thread_count * sizeof(dxThreadPoolThreadInfo)); m_ready_wait_event.FinalizeObject(); } }
bool dxThreadPoolThreadInfo::Initialize(size_t stack_size, unsigned int ode_data_allocate_flags) { bool result = false; bool command_event_allocated = false, acknowledgement_event_allocated = false; HANDLE thread_handle = NULL; do { if (stack_size > THREAD_STACK_MAX) { SetLastError(ERROR_INVALID_PARAMETER); break; } if (!m_command_event.InitializeObject(false, false)) { break; } command_event_allocated = true; if (!m_acknowledgement_event.InitializeObject(true, false)) { break; } acknowledgement_event_allocated = true; m_ode_data_allocate_flags = ode_data_allocate_flags; thread_handle = (HANDLE)_beginthreadex(NULL, (unsigned)stack_size, &ThreadProcedure_Callback, (void *)this, 0, NULL); if (thread_handle == NULL) // Not a bug!!! _beginthreadex() returns NULL on failure { break; } // It is OK to alter priority for thread without creating it in suspended state as // it is anyway going to be waited for (waited for its init result) and // will not be issues commands until after that. int own_priority = GetThreadPriority(GetCurrentThread()); if (own_priority != THREAD_PRIORITY_ERROR_RETURN) { if (!SetThreadPriority(thread_handle, own_priority)) { // own_priority = THREAD_PRIORITY_ERROR_RETURN; -- Well, if priority inheritance fails - just ignore it :-/ } } bool thread_init_result = WaitInitStatus(); if (!thread_init_result) { DWORD error_save = GetLastError(); WaitAndCloseThreadHandle(thread_handle); SetLastError(error_save); break; } m_thread_handle = thread_handle; result = true; } while (false); if (!result) { if (command_event_allocated) { if (acknowledgement_event_allocated) { m_acknowledgement_event.FinalizeObject(); } m_command_event.FinalizeObject(); } } return result; }
void dxThreadPoolThreadInfo::ReportInitStatus(bool init_result) { m_command_param = (void *)(size_t)(init_result ? EOK : ((errno != EOK) ? errno : EFAULT)); m_acknowledgement_event.SetEvent(); }
bool dxThreadPoolThreadInfo::Initialize(size_t stack_size, unsigned int ode_data_allocate_flags) { bool result = false; bool command_event_allocated = false, acknowledgement_event_allocated = false; do { // -- There is no implicit limit on stack size in POSIX implementation // if (stack_size > ...) // { // errno = EINVAL; // break; // } if (!m_command_event.InitializeObject(false, false)) { break; } command_event_allocated = true; if (!m_acknowledgement_event.InitializeObject(true, false)) { break; } acknowledgement_event_allocated = true; m_ode_data_allocate_flags = ode_data_allocate_flags; pthread_attr_t thread_attr; if (!InitializeThreadAttributes(&thread_attr, stack_size)) { break; } int thread_create_result = pthread_create(&m_thread_handle, &thread_attr, &ThreadProcedure_Callback, (void *)this); FinalizeThreadAttributes(&thread_attr); if (thread_create_result != EOK) { errno = thread_create_result; break; } bool thread_init_result = WaitInitStatus(); if (!thread_init_result) { WaitAndCloseThreadHandle(m_thread_handle); break; } m_thread_allocated = true; result = true; } while (false); if (!result) { if (command_event_allocated) { if (acknowledgement_event_allocated) { m_acknowledgement_event.FinalizeObject(); } m_command_event.FinalizeObject(); } } return result; }