Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/base
diff options
context:
space:
mode:
authorvng <viktor.govako@gmail.com>2013-07-05 16:44:03 +0400
committerAlex Zolotarev <alex@maps.me>2015-09-23 01:58:12 +0300
commitd39d7542f3a45ada3907506a6880053634e35274 (patch)
tree620ea9ef74d4927aa56712027715ba28147c69ee /base
parent19d314d1fa1d61e651ebe78af25eaae0a064ba2b (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.cpp26
-rw-r--r--base/scheduled_task.hpp25
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();
};