diff options
author | vng <viktor.govako@gmail.com> | 2013-07-05 16:44:03 +0400 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 01:58:12 +0300 |
commit | d39d7542f3a45ada3907506a6880053634e35274 (patch) | |
tree | 620ea9ef74d4927aa56712027715ba28147c69ee /base | |
parent | 19d314d1fa1d61e651ebe78af25eaae0a064ba2b (diff) |
- Do non-blocking Cancel in ScheduledTask. Blocking Cancel "causes" deadlock and freezing of main thread.
- Fix memory leak.
Diffstat (limited to 'base')
-rw-r--r-- | base/scheduled_task.cpp | 26 | ||||
-rw-r--r-- | base/scheduled_task.hpp | 25 |
2 files changed, 26 insertions, 25 deletions
diff --git a/base/scheduled_task.cpp b/base/scheduled_task.cpp index 6aebefdd7c..e96f9ad01e 100644 --- a/base/scheduled_task.cpp +++ b/base/scheduled_task.cpp @@ -31,20 +31,24 @@ void ScheduledTask::Routine::Do() m_pCond->Unlock(); } -void ScheduledTask::Routine::Cancel() -{ - m_pCond->Lock(); - IRoutine::Cancel(); - m_pCond->Signal(); - m_pCond->Unlock(); -} - ScheduledTask::ScheduledTask(fn_t const & fn, unsigned ms) { - m_thread.Create(new Routine(fn, ms, &m_cond)); + m_routine.reset(new Routine(fn, ms, &m_cond)); + m_thread.Create(m_routine.get()); } -void ScheduledTask::Cancel() +bool ScheduledTask::Cancel() { - m_thread.Cancel(); + if (m_cond.TryLock()) + { + m_routine->Cancel(); + + m_cond.Signal(); + m_cond.Unlock(); + + m_thread.Join(); + return true; + } + + return false; } diff --git a/base/scheduled_task.hpp b/base/scheduled_task.hpp index f8eed92611..86a885c1a1 100644 --- a/base/scheduled_task.hpp +++ b/base/scheduled_task.hpp @@ -1,41 +1,38 @@ #pragma once -#include "../std/function.hpp" - #include "thread.hpp" #include "condition.hpp" +#include "../std/function.hpp" +#include "../std/scoped_ptr.hpp" + + /// Class, which performs any function when the specified /// amount of time is elapsed. class ScheduledTask { -public: - typedef function<void()> fn_t; class Routine : public threads::IRoutine { - private: fn_t m_fn; unsigned m_ms; threads::Condition * m_pCond; - public: + public: Routine(fn_t const & fn, unsigned ms, threads::Condition * cond); - - void Do(); - void Cancel(); + virtual void Do(); }; -private: - + scoped_ptr<Routine> m_routine; threads::Thread m_thread; threads::Condition m_cond; public: - /// Constructor by function and time in miliseconds. ScheduledTask(fn_t const & fn, unsigned ms); - /// Task could be cancelled before time elapses. - void Cancel(); + + /// Task could be cancelled before time elapses. This function is NON-blocking. + /// @return false If the task is already running. + bool Cancel(); }; |