void TaskGroup::joinThreads() { NPT_Cardinal count = m_threadList.GetItemCount(); NPT_Ordinal i = 0; while (i < count) { NPT_List<TaskThread*>::Iterator it = m_threadList.GetItem(i); TaskThread *thread = *it; if (NPT_SUCCEEDED(thread->Wait(0))) { m_threadList.Erase(it); delete thread; --count; } else { i++; } } }
NPT_Result TaskGroup::wait(NPT_Timeout timeout) { NPT_Result nr; { WriteLocker locker(m_stateLock); if (m_state != State_Stopping) { return NPT_ERROR_INVALID_STATE; } } if (timeout == NPT_TIMEOUT_INFINITE) { /*for (NPT_Ordinal i = 0; i < m_threadList.GetItemCount(); i++) { TaskThread *thread = *m_threadList.GetItem(i); thread->Wait(); delete thread; } m_threadList.Clear();*/ NPT_LOG_INFO_2("TaskGroup %p waiting for %d threads", this, m_threadList.GetItemCount()); while (m_threadList.GetItemCount() > 0) { NPT_Cardinal count = m_threadList.GetItemCount(); for (NPT_Ordinal i = 0; i < count; ) { NPT_List<TaskThread*>::Iterator it = m_threadList.GetItem(i); TaskThread *thread = *it; NPT_LOG_INFO_2("TaskGroup %p waiting for thread %p", this, thread); if (NPT_SUCCEEDED(thread->Wait(3000))) { NPT_LOG_INFO_2("TaskGroup %p waited thread %p, fine!", this, thread); delete thread; m_threadList.Erase(it); count--; } else { NPT_LOG_INFO_2("TaskGroup %p thread %p still pending, continue", this, thread); i++; } } } } else { NPT_Timeout waitTick = 10; if (waitTick > timeout) { waitTick = timeout; } NPT_TimeStamp ts1, ts2; NPT_Timeout totalTick = 0; while (m_threadList.GetItemCount() != 0 && timeout >= totalTick) { NPT_Cardinal count = m_threadList.GetItemCount(); NPT_Ordinal i = 0; while (i < count) { NPT_List<TaskThread*>::Iterator it = m_threadList.GetItem(i); TaskThread *thread = *it; NPT_System::GetCurrentTimeStamp(ts1); nr = thread->Wait(waitTick); NPT_System::GetCurrentTimeStamp(ts2); totalTick += (ts2 - ts1).ToMillis(); if (NPT_SUCCEEDED(nr)) { m_threadList.Erase(it); delete thread; --count; } else { i++; } if (timeout >= totalTick) { NPT_Timeout remainTick = timeout - totalTick; if (waitTick > remainTick) { waitTick = remainTick; } } else { waitTick = 0; } } } } if (m_threadList.GetItemCount() == 0) { m_state = State_Stopped; } return m_threadList.GetItemCount() == 0 ? NPT_SUCCESS : NPT_ERROR_TIMEOUT; }