kodi
Thread.h
1 /*
2  * Copyright (C) 2005-2018 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 // Thread.h: interface for the CThread class.
12 //
14 
15 #include "Event.h"
16 
17 #include <atomic>
18 #include <future>
19 #ifdef TARGET_DARWIN
20 #include <mach/mach.h>
21 #endif
22 #include <stdint.h>
23 #include <string>
24 #include <thread>
25 
26 enum class ThreadPriority
27 {
28  LOWEST,
29  BELOW_NORMAL,
30  NORMAL,
31  ABOVE_NORMAL,
32  HIGHEST,
33 
39  PRIORITY_COUNT,
40 };
41 
42 class IRunnable;
43 class IThreadImpl;
44 class CThread
45 {
46 protected:
47  explicit CThread(const char* ThreadName);
48 
49 public:
50  CThread(IRunnable* pRunnable, const char* ThreadName);
51  virtual ~CThread();
52  void Create(bool bAutoDelete = false);
53 
54  template<typename Rep, typename Period>
55  void Sleep(std::chrono::duration<Rep, Period> duration)
56  {
57  if (duration > std::chrono::milliseconds(10) && IsCurrentThread())
58  m_StopEvent.Wait(duration);
59  else
60  std::this_thread::sleep_for(duration);
61  }
62 
63  bool IsAutoDelete() const;
64  virtual void StopThread(bool bWait = true);
65  bool IsRunning() const;
66 
67  bool IsCurrentThread() const;
68  bool Join(std::chrono::milliseconds duration);
69 
70  inline static const std::thread::id GetCurrentThreadId()
71  {
72  return std::this_thread::get_id();
73  }
74 
80  bool SetPriority(const ThreadPriority& priority);
81 
82  static CThread* GetCurrentThread();
83 
84  virtual void OnException(){} // signal termination handler
85 
86 protected:
87  virtual void OnStartup() {}
88  virtual void OnExit() {}
89  virtual void Process();
90 
91  std::atomic<bool> m_bStop;
92 
93  enum WaitResponse { WAIT_INTERRUPTED = -1, WAIT_SIGNALED = 0, WAIT_TIMEDOUT = 1 };
94 
100  inline WaitResponse AbortableWait(CEvent& event,
101  std::chrono::milliseconds duration =
102  std::chrono::milliseconds(-1) /* indicates wait forever*/)
103  {
104  XbmcThreads::CEventGroup group{&event, &m_StopEvent};
105  const CEvent* result =
106  duration < std::chrono::milliseconds::zero() ? group.wait() : group.wait(duration);
107  return result == &event ? WAIT_SIGNALED :
108  (result == NULL ? WAIT_TIMEDOUT : WAIT_INTERRUPTED);
109  }
110 
111 private:
112  void Action();
113 
114  bool m_bAutoDelete = false;
115  CEvent m_StopEvent;
116  CEvent m_StartEvent;
117  CCriticalSection m_CriticalSection;
118  IRunnable* m_pRunnable;
119 
120  std::string m_ThreadName;
121  std::thread* m_thread = nullptr;
122  std::future<bool> m_future;
123 
124  std::unique_ptr<IThreadImpl> m_impl;
125 };
This is an Event class built from a ConditionVariable.
Definition: Event.h:35
Definition: Thread.h:44
WaitResponse AbortableWait(CEvent &event, std::chrono::milliseconds duration=std::chrono::milliseconds(-1))
This call will wait on a CEvent in an interruptible way such that if stop is called on the thread the...
Definition: Thread.h:100
CEventGroup is a means of grouping CEvents to wait on them together.
Definition: Event.h:138
Definition: IThreadImpl.h:17
Definition: IRunnable.h:11
Definition: SmartPlayList.cpp:137