forked from organicmaps/organicmaps
on ThreadPool::Stop we need cancel tasks that were not taken into Thread, and call finish function.
This commit is contained in:
parent
fb53952900
commit
5c1486814e
2 changed files with 49 additions and 2 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue