on ThreadPool::Stop we need cancel tasks that were not taken into Thread, and call finish function.

This commit is contained in:
ExMix 2013-11-01 12:38:16 +03:00 committed by Alex Zolotarev
parent fb53952900
commit 5c1486814e
2 changed files with 49 additions and 2 deletions

View file

@ -53,6 +53,38 @@ UNIT_TEST(ThreadPool_CanceledTaskTest)
TEST_EQUAL(finishCounter, TASK_COUNT, ());
}
namespace
{
class EmptyPoolTask : public threads::IRoutine
{
public:
~EmptyPoolTask()
{
TEST_EQUAL(IsCancelled(), true, ());
}
virtual void Do()
{
TEST_EQUAL(true, false, ());
}
};
}
UNIT_TEST(ThreadPool_StopOperationTest)
{
int finishCounter = 0;
threads::Condition cond;
// in this case we have empty pool, and all tasks must be finish only on Stop method call
threads::ThreadPool pool(0, bind(&JoinFinishFunction, _1, ref(finishCounter), ref(cond)));
for (int i = 0; i < TASK_COUNT; ++i)
pool.AddTask(new EmptyPoolTask());
pool.Stop();
TEST_EQUAL(finishCounter, TASK_COUNT, ());
}
namespace
{
class CancelTestTask : public threads::IRoutine

View file

@ -48,12 +48,13 @@ namespace threads
{
public:
Impl(size_t size, const finish_routine_fn & finishFn)
: m_finishFn(finishFn)
{
m_threads.resize(size);
for (size_t i = 0; i < size; ++i)
{
thread_info_t info = make_pair(new threads::Thread(), new PoolRoutine(bind(&ThreadPool::Impl::PopFront, this),
finishFn));
m_finishFn));
info.first->Create(info.second);
m_threads[i] = info;
}
@ -77,7 +78,6 @@ namespace threads
void Stop()
{
m_tasks.Cancel();
m_tasks.Clear();
for (size_t i = 0; i < m_threads.size(); ++i)
m_threads[i].second->Cancel();
@ -88,10 +88,25 @@ namespace threads
delete m_threads[i].second;
delete m_threads[i].first;
}
m_tasks.ProcessList(bind(&ThreadPool::Impl::FinishTasksOnStop, this, _1));
m_tasks.Clear();
}
private:
void FinishTasksOnStop(list<threads::IRoutine *> & tasks)
{
typedef list<threads::IRoutine *>::iterator task_iter;
for (task_iter it = tasks.begin(); it != tasks.end(); ++it)
{
(*it)->Cancel();
m_finishFn(*it);
}
}
private:
ThreadedList<threads::IRoutine *> m_tasks;
finish_routine_fn m_finishFn;
typedef pair<threads::Thread *, threads::IRoutine *> thread_info_t;
vector<thread_info_t> m_threads;