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

thread.hpp « base - github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 157426b1b6f09dc69b1f9a967794dff41d088a1c (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
125
126
#pragma once

#include "base/assert.hpp"
#include "base/cancellable.hpp"
#include "base/macros.hpp"

#include "std/target_os.hpp"

#include <cstdint>
#include <functional>
#include <memory>
#include <thread>
#include <utility>
#include <vector>

#include <boost/noncopyable.hpp>

#ifdef OMIM_OS_WINDOWS
#include "std/windows.hpp"  // for DWORD
#endif

namespace threads
{
class IRoutine : public base::Cancellable
{
public:
  /// Perform the main task.
  virtual void Do() = 0;
};

/// A wrapper for system threads API.
///
/// Thread class manages lifetime of a running IRoutine and guarantees
/// that it will be possible to access the IRoutine after
/// Thread::Create() call until cancellation or destruction.  In the
/// latter case, system thread will be responsible for deletion of a
/// IRoutine.
class Thread
{
  std::thread m_thread;
  std::shared_ptr<IRoutine> m_routine;

  DISALLOW_COPY(Thread);

public:
  Thread();
  ~Thread();

  /// Run thread immediately.
  ///
  /// @param routine Routine that will be executed on m_thread and
  ///                destroyed by the current Thread instance or by
  ///                the m_thread, if it is detached during the
  ///                execution of routine.
  bool Create(std::unique_ptr<IRoutine> && routine);

  /// Calling the IRoutine::Cancel method, and Join'ing with the task
  /// execution.  After that, routine is deleted.
  void Cancel();

  /// Wait for thread ending.
  void Join();

  /// \return Pointer to the routine.
  IRoutine * GetRoutine();

  /// \return Pointer to the routine converted to T *.  When it's not
  ///         possible to convert routine to the T *, release version
  ///         returns nullptr, debug version fails.
  template <typename T>
  T * GetRoutineAs()
  {
    ASSERT(m_routine.get(), ("Routine is not set"));
    T * ptr = dynamic_cast<T *>(m_routine.get());
    ASSERT(ptr, ("Can't convert IRoutine* to", TO_STRING(T) "*"));
    return ptr;
  }
};

/// Suspends the execution of the current thread until the time-out interval elapses.
/// @param[in] ms time-out interval in milliseconds
void Sleep(size_t ms);

using ThreadID = std::thread::id;

ThreadID GetCurrentThreadID();

/// A wrapper around a std thread which executes callable object in thread which is attached to JVM
/// Class has the same interface as std::thread
class SimpleThread
{
public:
  using id = std::thread::id;
  using native_handle_type = std::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, std::bind(std::forward<Fn>(fn), std::forward<Args>(args)...))
  {}

  SimpleThread & operator= (SimpleThread && x) noexcept
  {
    m_thread = move(x.m_thread);
    return *this;
  }

  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(std::function<void()> && fn);

  DISALLOW_COPY(SimpleThread);

  std::thread m_thread;
};
}  // namespace threads