Audacity  2.2.0
ODTaskThread.h
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4 
5  ODTaskThread.h
6 
7  Created by Michael Chinen (mchinen) on 6/8/08
8  Audacity(R) is copyright (c) 1999-2008 Audacity Team.
9  License: GPL v2. See License.txt.
10 
11 ******************************************************************//*******************************************************************/
17 
18 
19 
20 
21 
22 #ifndef __AUDACITY_ODTASKTHREAD__
23 #define __AUDACITY_ODTASKTHREAD__
24 #include <wx/thread.h>
25 
26 #include "../Audacity.h" // contains the set-up of AUDACITY_DLL_API
27 #include "../MemoryX.h"
28 
29 class ODTask;
30 
31 #ifdef __WXMAC__
32 
33 // On Mac OS X, it's better not to use the wxThread class.
34 // We use our own implementation based on pthreads instead.
35 
36 #include <pthread.h>
37 #include <time.h>
38 
39 class ODTaskThread {
40  public:
41  typedef int ExitCode;
42  ODTaskThread(ODTask* task);
43  /*ExitCode*/ void Entry();
44  void Create() {}
45  void Delete() {
46  mDestroy = true;
47  pthread_join(mThread, NULL);
48  }
49  bool TestDestroy() { return mDestroy; }
50  void Sleep(int ms) {
51  struct timespec spec;
52  spec.tv_sec = 0;
53  spec.tv_nsec = ms * 1000 * 1000;
54  nanosleep(&spec, NULL);
55  }
56  static void *callback(void *p) {
57  ODTaskThread *th = (ODTaskThread *)p;
58 #if defined(__WXMAC__)
59  /*return (void *)*/ th->Entry();
60  return NULL;
61 #else
62  return (void *) th->Entry();
63 #endif
64  }
65  void Run() {
66  pthread_create(&mThread, NULL, callback, this);
67  }
68 
71  void SetPriority(int priority)
72  {
73  mPriority=priority;
74  }
75 
76  private:
77  int mPriority;
78  bool mDestroy;
79  pthread_t mThread;
80 
81  ODTask* mTask;
82 };
83 
84 class ODLock {
85  public:
86  ODLock(){
87  pthread_mutex_init (&mutex, NULL);
88  }
89 
90  void Lock()
91  {
92  pthread_mutex_lock (&mutex);
93  }
94 
95  // Returns 0 iff the lock was acquired.
96  bool TryLock()
97  {
98  return pthread_mutex_trylock (&mutex);
99  }
100 
101  void Unlock()
102  {
103  pthread_mutex_unlock (&mutex);
104  }
105 
106  virtual ~ODLock()
107  {
108  pthread_mutex_destroy (&mutex);
109  }
110 
111 private:
112  friend class ODCondition; //needs friendship for wait()
113  pthread_mutex_t mutex;
114 };
115 
116 class ODCondition
117 {
118 public:
119  ODCondition(ODLock *lock);
120  virtual ~ODCondition();
121  void Signal();
122  void Broadcast();
123  void Wait();
124 
125 protected:
126  pthread_cond_t condition;
127  ODLock* m_lock;
128 };
129 
130 #else
131 
132 
133 class ODTaskThread final : public wxThread
134 {
135 public:
138  ODTaskThread(ODTask* task);
139 
140 
141 protected:
143  void* Entry() override;
145 
146 };
147 
148 
149 //a wrapper for wxMutex.
150 class AUDACITY_DLL_API ODLock final : public wxMutex
151 {
152 public:
155  ODLock(){}
156  virtual ~ODLock(){}
157 };
158 
159 class ODCondition final : public wxCondition
160 {
161 public:
162  ODCondition(ODLock *lock):wxCondition(*lock){}
163  virtual ~ODCondition(){}
164  //these calls are implemented in wxCondition:
165  //void Signal();
166  //void Broadcast();
167  //void Wait();
168 
169 protected:
170 };
171 
172 #endif // __WXMAC__
173 
174 // class ODLocker
175 // So you can use the RAII idiom with ODLock, on whatever platform
176 // Construct with pointer to the lock, or default-construct and later
177 // reset()
178 // If constructed with only a try-lock, and the lock was not acquired,
179 // then it returns false when cast to bool
180 struct ODUnlocker { void operator () (ODLock *p) const { if(p) p->Unlock(); } };
181 using ODLockerBase = std::unique_ptr<ODLock, ODUnlocker>;
182 class ODLocker : public ODLockerBase {
183 public:
184  // Lock any bare pointer to ODLock at construction time or when resetting.
185  explicit ODLocker(ODLock *p = nullptr, bool tryOnly = false)
186  {
187  reset(p, tryOnly);
188  }
189 
190  void reset(ODLock *p = nullptr, bool tryOnly = false)
191  {
192  ODLockerBase::reset(p);
193  if(p) {
194  if (tryOnly) {
195  if (p->TryLock() != 0)
196  ODLockerBase::reset(nullptr);
197  }
198  else
199  p->Lock();
200  }
201  }
202 
203  // Assume already locked when moving ODLocker. Don't lock again.
204  ODLocker(ODLocker&& that) : ODLockerBase { std::move(that) } {}
206  ODLockerBase::operator= ( std::move(that) );
207  return *this;
208  }
209 
210  ODLocker(const ODLocker &that) PROHIBITED;
211  ODLocker &operator= (const ODLocker &that) PROHIBITED;
212 };
213 
214 #endif //__AUDACITY_ODTASKTHREAD__
215 
#define PROHIBITED
Definition: Audacity.h:224
ODLocker(ODLocker &&that)
Definition: ODTaskThread.h:204
void operator()(ODLock *p) const
Definition: ODTaskThread.h:180
Definition: ODTaskThread.h:159
ODLocker(ODLock *p=nullptr, bool tryOnly=false)
Definition: ODTaskThread.h:185
Definition: ODTaskThread.h:180
void * Entry() override
Executes a part of the task.
Definition: ODTaskThread.cpp:41
A class representing a modular task to be used with the On-Demand structures.
Definition: ODTask.h:39
A thread that executes a part of the task specfied by an ODTask.
Definition: ODTaskThread.h:133
virtual ~ODLock()
Definition: ODTaskThread.h:156
void reset(ODLock *p=nullptr, bool tryOnly=false)
Definition: ODTaskThread.h:190
Definition: ODTaskThread.h:182
ODLocker & operator=(ODLocker &&that)
Definition: ODTaskThread.h:205
Definition: ODTaskThread.h:150
std::unique_ptr< ODLock, ODUnlocker > ODLockerBase
Definition: ODTaskThread.h:181
virtual ~ODCondition()
Definition: ODTaskThread.h:163
ODCondition(ODLock *lock)
Definition: ODTaskThread.h:162
ODTask * mTask
Definition: ODTaskThread.h:144
ODLock()
Definition: ODTaskThread.h:155
ODTaskThread(ODTask *task)
Definition: ODTaskThread.cpp:24