예제 #1
0
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++;
		}
	}
}
예제 #2
0
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;
}