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

thread.cpp « base - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 2c3bc913e865257922c4c880f6939ffa63bea1ae (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "base/thread.hpp"

#include "base/logging.hpp"

#include "std/chrono.hpp"
#include "std/exception.hpp"

#if defined(OMIM_OS_ANDROID)
void AndroidThreadAttachToJVM();
void AndroidThreadDetachFromJVM();
#endif  // defined(OMIM_OS_ANDROID)

namespace threads
{
namespace
{
/// Prepares worker thread and runs routine.
void RunRoutine(shared_ptr<IRoutine> routine)
{
#if defined(OMIM_OS_ANDROID)
  AndroidThreadAttachToJVM();
#endif  // defined(OMIM_OS_ANDROID)

  routine->Do();

#if defined(OMIM_OS_ANDROID)
  AndroidThreadDetachFromJVM();
#endif  // defined(OMIM_OS_ANDROID)
}
}  // namespace

/////////////////////////////////////////////////////////////////////
// Thread wrapper implementation

Thread::Thread()
{
}

Thread::~Thread()
{
  // @todo (ygorshenin@): in general, it's not a good practice to
  // implicitly detach thread since detached threads work in
  // background, consume system resources and make it hard to reason
  // about program. Thus, all places where Thread is instantiated
  // should be fixed to explicitly detach thread.
  if (m_thread.joinable())
    m_thread.detach();
}

bool Thread::Create(unique_ptr<IRoutine> && routine)
{
  ASSERT(!m_routine, ("Current implementation doesn't allow to reuse thread"));
  thread routineThread;
  try
  {
    m_routine.reset(routine.release());
    routineThread = thread(&RunRoutine, m_routine);
  }
  catch (exception & e)
  {
    LOG(LERROR, ("Thread creation failed with error:", e.what()));
    m_routine.reset();
    return false;
  }
  m_thread = move(routineThread);
  return true;
}

void Thread::Cancel()
{
  if (!m_routine)
    return;
  m_routine->Cancel();
  Join();
  m_routine.reset();
}

void Thread::Join()
{
  if (m_thread.joinable())
    m_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)
{
  m_pool.emplace_back(new Thread());
  m_pool.back()->Create(move(routine));
}

void SimpleThreadPool::Join()
{
  for (auto & thread : m_pool)
    thread->Join();
}

IRoutine * SimpleThreadPool::GetRoutine(size_t i) const { return m_pool[i]->GetRoutine(); }

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)
}
}  // namespace threads