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; }
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; }
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; }