forked from organicmaps/organicmaps
Fix ScheduledTask tests with blocking Cancel.
This commit is contained in:
parent
116a2e8c27
commit
4f7f6fb6bd
6 changed files with 45 additions and 23 deletions
|
@ -247,7 +247,7 @@ namespace android
|
|||
{
|
||||
if (m_scheduledTask)
|
||||
{
|
||||
if (!m_scheduledTask->Cancel())
|
||||
if (!m_scheduledTask->CancelNoBlocking())
|
||||
{
|
||||
// The task is already running - skip new task.
|
||||
return false;
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#include "../scheduled_task.hpp"
|
||||
#include "../thread.hpp"
|
||||
#include "../../testing/testing.hpp"
|
||||
|
||||
#include "../scheduled_task.hpp"
|
||||
|
||||
#include "../../std/bind.hpp"
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
void add_int(int & val, int a)
|
||||
|
@ -17,12 +19,16 @@ namespace
|
|||
}
|
||||
|
||||
|
||||
/// @todo Next tests are based on assumptions that some delays are suitable for
|
||||
/// performing needed checks, before a task will fire.
|
||||
|
||||
UNIT_TEST(ScheduledTask_Smoke)
|
||||
{
|
||||
int val = 0;
|
||||
|
||||
ScheduledTask t(bind(&add_int, ref(val), 10), 1000);
|
||||
|
||||
// Assume that t thread isn't fired yet.
|
||||
TEST_EQUAL(val, 0, ());
|
||||
|
||||
threads::Sleep(1100);
|
||||
|
@ -34,9 +40,11 @@ UNIT_TEST(ScheduledTask_CancelInfinite)
|
|||
{
|
||||
int val = 2;
|
||||
|
||||
ScheduledTask t0(bind(&add_int, ref(val), 10), -1);
|
||||
ScheduledTask t0(bind(&add_int, ref(val), 10), static_cast<unsigned>(-1));
|
||||
|
||||
t0.Cancel();
|
||||
t0.CancelBlocking();
|
||||
|
||||
TEST_EQUAL(val, 2, ());
|
||||
}
|
||||
|
||||
UNIT_TEST(ScheduledTask_Cancel)
|
||||
|
@ -48,7 +56,8 @@ UNIT_TEST(ScheduledTask_Cancel)
|
|||
|
||||
TEST_EQUAL(val, 2, ());
|
||||
|
||||
t0.Cancel();
|
||||
// Assume that t0 thread isn't fired yet.
|
||||
t0.CancelBlocking();
|
||||
|
||||
threads::Sleep(1100);
|
||||
|
||||
|
@ -62,8 +71,9 @@ UNIT_TEST(ScheduledTask_NoWaitInCancel)
|
|||
ScheduledTask t0(bind(&add_int, ref(val), 10), 1000);
|
||||
ScheduledTask t1(bind(&mul_int, ref(val), 3), 500);
|
||||
|
||||
t0.Cancel();
|
||||
t0.CancelBlocking();
|
||||
|
||||
// Assume that t1 thread isn't fired yet.
|
||||
val += 3;
|
||||
|
||||
threads::Sleep(600);
|
||||
|
|
|
@ -31,24 +31,32 @@ void ScheduledTask::Routine::Do()
|
|||
m_pCond->Unlock();
|
||||
}
|
||||
|
||||
void ScheduledTask::Routine::Cancel()
|
||||
{
|
||||
threads::IRoutine::Cancel();
|
||||
|
||||
m_pCond->Signal();
|
||||
m_pCond->Unlock();
|
||||
}
|
||||
|
||||
ScheduledTask::ScheduledTask(fn_t const & fn, unsigned ms)
|
||||
: m_routine(new Routine(fn, ms, &m_cond))
|
||||
{
|
||||
m_thread.Create(m_routine.get());
|
||||
}
|
||||
|
||||
bool ScheduledTask::Cancel()
|
||||
bool ScheduledTask::CancelNoBlocking()
|
||||
{
|
||||
if (m_cond.TryLock())
|
||||
{
|
||||
m_routine->Cancel();
|
||||
|
||||
m_cond.Signal();
|
||||
m_cond.Unlock();
|
||||
|
||||
m_thread.Join();
|
||||
m_thread.Cancel();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ScheduledTask::CancelBlocking()
|
||||
{
|
||||
m_cond.Lock();
|
||||
m_thread.Cancel();
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ class ScheduledTask
|
|||
public:
|
||||
Routine(fn_t const & fn, unsigned ms, threads::Condition * cond);
|
||||
virtual void Do();
|
||||
virtual void Cancel();
|
||||
};
|
||||
|
||||
scoped_ptr<Routine> m_routine;
|
||||
|
@ -32,7 +33,10 @@ public:
|
|||
/// Constructor by function and time in miliseconds.
|
||||
ScheduledTask(fn_t const & fn, unsigned ms);
|
||||
|
||||
/// Task could be cancelled before time elapses. This function is NON-blocking.
|
||||
/// @return false If the task is already running.
|
||||
bool Cancel();
|
||||
/// @name Task could be cancelled before time elapses.
|
||||
//@{
|
||||
/// @return false If the task is already running or in some intermediate state.
|
||||
bool CancelNoBlocking();
|
||||
void CancelBlocking();
|
||||
//@}
|
||||
};
|
||||
|
|
|
@ -336,20 +336,20 @@ namespace qt
|
|||
void DrawWidget::StartPressTask(m2::PointD const & pt, unsigned ms)
|
||||
{
|
||||
if (KillPressTask())
|
||||
m_scheduledTasks.reset(new ScheduledTask(bind(&DrawWidget::OnPressTaskEvent, this, pt, ms), ms));
|
||||
m_scheduledTask.reset(new ScheduledTask(bind(&DrawWidget::OnPressTaskEvent, this, pt, ms), ms));
|
||||
}
|
||||
|
||||
bool DrawWidget::KillPressTask()
|
||||
{
|
||||
if (m_scheduledTasks)
|
||||
if (m_scheduledTask)
|
||||
{
|
||||
if (!m_scheduledTasks->Cancel())
|
||||
if (!m_scheduledTask->CancelNoBlocking())
|
||||
{
|
||||
// The task is already running - skip new task.
|
||||
return false;
|
||||
}
|
||||
|
||||
m_scheduledTasks.reset();
|
||||
m_scheduledTask.reset();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -142,7 +142,7 @@ namespace qt
|
|||
|
||||
QScaleSlider * m_pScale;
|
||||
|
||||
scoped_ptr<ScheduledTask> m_scheduledTasks;
|
||||
scoped_ptr<ScheduledTask> m_scheduledTask;
|
||||
m2::PointD m_taskPoint;
|
||||
bool m_wasLongClick, m_isCleanSingleClick;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue