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:
authorConstantin Shalnev <c.shalnev@corp.mail.ru>2015-08-05 14:30:30 +0300
committerAlex Zolotarev <alex@maps.me>2015-09-23 02:59:17 +0300
commit230224bf82ad8f65051476f7331f181f85f8f1c2 (patch)
treecfe3f26032135e6ecde5bb4d793f891f1bda7bf5 /base
parent98fe42b58d3b8f09492067aced0e4d3200076377 (diff)
Implemented SimpleThread which is the same as std::thread but executes callable object in a JVM environment
Diffstat (limited to 'base')
-rw-r--r--base/base_tests/threads_test.cpp57
-rw-r--r--base/thread.cpp19
-rw-r--r--base/thread.hpp41
3 files changed, 117 insertions, 0 deletions
diff --git a/base/base_tests/threads_test.cpp b/base/base_tests/threads_test.cpp
index a72d42f9ff..6a70938b63 100644
--- a/base/base_tests/threads_test.cpp
+++ b/base/base_tests/threads_test.cpp
@@ -58,3 +58,60 @@ UNIT_TEST(Simple_Threads)
TEST_EQUAL(vec.size(), MAX_COUNT, ("vector size"));
TEST_EQUAL(summ, checkSumm, ("check summ"));
}
+
+class SomeClass
+{
+public:
+ void Increment(int * a, int b)
+ {
+ *a = *a + b;
+ }
+};
+
+static void Increment(int * a, int b)
+{
+ *a = *a + b;
+}
+
+UNIT_TEST(SimpleThreadTest1)
+{
+ int a = 0;
+
+ auto fn = [&a](){ a = 1; };
+
+ threads::SimpleThread t(fn);
+ t.join();
+
+ TEST_EQUAL(a, 1, ("test a"));
+}
+
+UNIT_TEST(SimpleThreadTest2)
+{
+ int a = 0;
+
+ threads::SimpleThread t([&a](){ a = 1; });
+ t.join();
+
+ TEST_EQUAL(a, 1, ("test a"));
+}
+
+UNIT_TEST(SimpleThreadTest3)
+{
+ int a = 0;
+
+ SomeClass instance;
+ threads::SimpleThread t(&SomeClass::Increment, &instance, &a, 1);
+ t.join();
+
+ TEST_EQUAL(a, 1, ("test a"));
+}
+
+UNIT_TEST(SimpleThreadTest4)
+{
+ int a = 0;
+
+ threads::SimpleThread t(&Increment, &a, 1);
+ t.join();
+
+ TEST_EQUAL(a, 1, ("test a"));
+}
diff --git a/base/thread.cpp b/base/thread.cpp
index 16880cdb1a..7ca97a895f 100644
--- a/base/thread.cpp
+++ b/base/thread.cpp
@@ -79,6 +79,9 @@ void Thread::Join()
IRoutine * Thread::GetRoutine() { return m_routine.get(); }
+/////////////////////////////////////////////////////////////////////
+// SimpleThreadPool implementation
+
SimpleThreadPool::SimpleThreadPool(size_t reserve) { m_pool.reserve(reserve); }
void SimpleThreadPool::Add(unique_ptr<IRoutine> && routine)
@@ -98,4 +101,20 @@ IRoutine * SimpleThreadPool::GetRoutine(size_t i) const { return m_pool[i]->GetR
void Sleep(size_t ms) { this_thread::sleep_for(milliseconds(ms)); }
ThreadID GetCurrentThreadID() { return this_thread::get_id(); }
+
+/////////////////////////////////////////////////////////////////////
+// SimpleThread implementation
+
+void SimpleThread::ThreadFunc(function<void()> fn)
+{
+#if defined(OMIM_OS_ANDROID)
+ AndroidThreadAttachToJVM();
+#endif // defined(OMIM_OS_ANDROID)
+
+ fn();
+
+#if defined(OMIM_OS_ANDROID)
+ AndroidThreadDetachFromJVM();
+#endif // defined(OMIM_OS_ANDROID)
+}
}
diff --git a/base/thread.hpp b/base/thread.hpp
index 654dea5d81..2ec7b8b835 100644
--- a/base/thread.hpp
+++ b/base/thread.hpp
@@ -4,7 +4,9 @@
#include "base/cancellable.hpp"
#include "base/macros.hpp"
+#include "std/bind.hpp"
#include "std/cstdint.hpp"
+#include "std/function.hpp"
#include "std/noncopyable.hpp"
#include "std/shared_ptr.hpp"
#include "std/target_os.hpp"
@@ -94,4 +96,43 @@ typedef thread::id ThreadID;
ThreadID GetCurrentThreadID();
+/// A wrapper around a std thread which executes callable object in android envorinment
+/// Class has the same interface as std::thread
+class SimpleThread
+{
+public:
+ using id = thread::id;
+ using native_handle_type = thread::native_handle_type;
+
+ SimpleThread() noexcept {}
+ SimpleThread(SimpleThread && x) noexcept
+ : m_thread(move(x.m_thread))
+ {}
+
+ template <class Fn, class... Args>
+ explicit SimpleThread(Fn && fn, Args &&... args)
+ : m_thread(&SimpleThread::ThreadFunc, bind(forward<Fn>(fn), forward<Args>(args)...))
+ {}
+
+ SimpleThread & operator= (SimpleThread && x) noexcept
+ {
+ m_thread = move(x.m_thread);
+ return *this;
+ }
+
+ SimpleThread(const SimpleThread &) = delete;
+ SimpleThread & operator= (const SimpleThread &) = delete;
+
+ void detach() { m_thread.detach(); }
+ id get_id() const noexcept { return m_thread.get_id(); }
+ void join() { m_thread.join(); }
+ bool joinable() const noexcept { return m_thread.joinable(); }
+ native_handle_type native_handle() { return m_thread.native_handle(); }
+ void swap(SimpleThread & x) noexcept { m_thread.swap(x.m_thread); }
+
+private:
+ static void ThreadFunc(function<void()> fn);
+
+ thread m_thread;
+};
} // namespace threads