]> git.saurik.com Git - wxWidgets.git/blob - include/wx/thread.h
assignment operators/copy ctors are private for classes which can't be copied
[wxWidgets.git] / include / wx / thread.h
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: thread.h
3 // Purpose: Thread API
4 // Author: Guilhem Lavaux
5 // Modified by:
6 // Created: 04/13/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Guilhem Lavaux
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifndef __THREADH__
13 #define __THREADH__
14
15 #ifdef __GNUG__
16 #pragma interface "thread.h"
17 #endif
18
19 // ----------------------------------------------------------------------------
20 // headers
21 // ----------------------------------------------------------------------------
22 #include "wx/setup.h"
23
24 #if wxUSE_THREADS
25 #include "wx/module.h"
26
27 // ----------------------------------------------------------------------------
28 // constants
29 // ----------------------------------------------------------------------------
30
31 typedef enum
32 {
33 wxMUTEX_NO_ERROR = 0,
34 wxMUTEX_DEAD_LOCK, // Mutex has been already locked by THE CALLING thread
35 wxMUTEX_BUSY, // Mutex has been already locked by ONE thread
36 wxMUTEX_UNLOCKED,
37 wxMUTEX_MISC_ERROR
38 } wxMutexError;
39
40 typedef enum
41 {
42 wxTHREAD_NO_ERROR = 0, // No error
43 wxTHREAD_NO_RESOURCE, // No resource left to create a new thread
44 wxTHREAD_RUNNING, // The thread is already running
45 wxTHREAD_NOT_RUNNING, // The thread isn't running
46 wxTHREAD_MISC_ERROR // Some other error
47 } wxThreadError;
48
49 /* defines the interval of priority. */
50 #define WXTHREAD_MIN_PRIORITY 0
51 #define WXTHREAD_DEFAULT_PRIORITY 50
52 #define WXTHREAD_MAX_PRIORITY 100
53
54 // ----------------------------------------------------------------------------
55 // A mutex object is a synchronization object whose state is set to signaled
56 // when it is not owned by any thread, and nonsignaled when it is owned. Its
57 // name comes from its usefulness in coordinating mutually-exclusive access to
58 // a shared resource. Only one thread at a time can own a mutex object.
59 // ----------------------------------------------------------------------------
60
61 // you should consider wxMutexLocker whenever possible instead of directly
62 // working with wxMutex class - it is safer
63 class WXDLLEXPORT wxMutexInternal;
64 class WXDLLEXPORT wxMutex
65 {
66 public:
67 // constructor & destructor
68 wxMutex();
69 ~wxMutex();
70
71 // Lock the mutex.
72 wxMutexError Lock();
73 // Try to lock the mutex: if it can't, returns immediately with an error.
74 wxMutexError TryLock();
75 // Unlock the mutex.
76 wxMutexError Unlock();
77
78 // Returns true if the mutex is locked.
79 bool IsLocked() const { return (m_locked > 0); }
80
81 protected:
82 friend class wxCondition;
83
84 // no assignment operator nor copy ctor
85 wxMutex(const wxMutex&);
86 wxMutex& operator=(const wxMutex&);
87
88 int m_locked;
89 wxMutexInternal *p_internal;
90 };
91
92 // a helper class which locks the mutex in the ctor and unlocks it in the dtor:
93 // this ensures that mutex is always unlocked, even if the function returns or
94 // throws an exception before it reaches the end
95 class WXDLLEXPORT wxMutexLocker
96 {
97 public:
98 // lock the mutex in the ctor
99 wxMutexLocker(wxMutex *mutex)
100 { m_isOk = mutex && ((m_mutex = mutex)->Lock() == wxMUTEX_NO_ERROR); }
101
102 // returns TRUE if mutex was successfully locked in ctor
103 bool IsOk() const { return m_isOk; }
104
105 // unlock the mutex in dtor
106 ~wxMutexLocker() { if ( IsOk() ) m_mutex->Unlock(); }
107
108 private:
109 // no assignment operator nor copy ctor
110 wxMutexLocker(const wxMutexLocker&);
111 wxMutexLocker& operator=(const wxMutexLocker&);
112
113 bool m_isOk;
114 wxMutex *m_mutex;
115 };
116
117 #ifdef __WXMSW__
118
119 // ----------------------------------------------------------------------------
120 // Critical section: this is the same as mutex but is only visible to the
121 // threads of the same process. For the platforms which don't have native
122 // support for critical sections, they're implemented entirely in terms of
123 // mutexes
124 // ----------------------------------------------------------------------------
125
126 // you should consider wxCriticalSectionLocker whenever possible instead of
127 // directly working with wxCriticalSection class - it is safer
128 class WXDLLEXPORT wxCriticalSectionInternal;
129 class WXDLLEXPORT wxCriticalSection
130 {
131 public:
132 // ctor & dtor
133 wxCriticalSection();
134 ~wxCriticalSection();
135
136 // enter the section (the same as locking a mutex)
137 void Enter();
138 // leave the critical section (same as unlocking a mutex)
139 void Leave();
140
141 private:
142 // no assignment operator nor copy ctor
143 wxCriticalSection(const wxCriticalSection&);
144 wxCriticalSection& operator=(const wxCriticalSection&);
145
146 wxCriticalSectionInternal *m_critsect;
147 };
148
149 // wxCriticalSectionLocker is the same to critical sections as wxMutexLocker is
150 // to th mutexes
151 class WXDLLEXPORT wxCriticalSectionLocker
152 {
153 public:
154 wxCriticalSectionLocker(wxCriticalSection& critsect) : m_critsect(critsect)
155 { m_critsect.Enter(); }
156 ~wxCriticalSectionLocker()
157 { m_critsect.Leave(); }
158
159 private:
160 // no assignment operator nor copy ctor
161 wxCriticalSectionLocker(const wxCriticalSectionLocker&);
162 wxCriticalSectionLocker& operator=(const wxCriticalSectionLocker&);
163
164 wxCriticalSection& m_critsect;
165 };
166
167 #endif
168
169 // ----------------------------------------------------------------------------
170 // Condition handler.
171 // ----------------------------------------------------------------------------
172
173 class wxConditionInternal;
174 class WXDLLEXPORT wxCondition
175 {
176 public:
177 // constructor & destructor
178 wxCondition();
179 ~wxCondition();
180
181 // Waits indefinitely.
182 void Wait(wxMutex& mutex);
183 // Waits until a signal is raised or the timeout is elapsed.
184 bool Wait(wxMutex& mutex, unsigned long sec, unsigned long nsec);
185 // Raises a signal: only one "Waiter" is released.
186 void Signal();
187 // Broadcasts to all "Waiters".
188 void Broadcast();
189
190 private:
191 wxConditionInternal *p_internal;
192 };
193
194 // ----------------------------------------------------------------------------
195 // Thread management class
196 // ----------------------------------------------------------------------------
197
198 class wxThreadInternal;
199 class WXDLLEXPORT wxThread
200 {
201 public:
202 // constructor & destructor.
203 wxThread();
204 virtual ~wxThread();
205
206 // Create a new thread, this method should check there is only one thread
207 // running by object.
208 wxThreadError Create();
209
210 // Destroys the thread immediately if the defer flag isn't true.
211 wxThreadError Destroy();
212
213 // Pause a running thread
214 wxThreadError Pause();
215
216 // Resume a paused thread
217 wxThreadError Resume();
218
219 // Switches on the defer flag.
220 void DeferDestroy(bool on);
221
222 // Waits for the termination of the thread.
223 void *Join();
224
225 // Sets the priority to "prio". (Warning: The priority can only be set before
226 // the thread is created)
227 void SetPriority(int prio);
228 // Get the current priority.
229 int GetPriority() const;
230
231 // Get the thread ID
232 unsigned long GetID() const;
233
234 // Returns true if the thread is alive.
235 bool IsAlive() const;
236 // Returns true if the thread is running (not paused, not killed).
237 bool IsRunning() const;
238 // Returns true if the thread is suspended
239 bool IsPaused() const { return IsAlive() && !IsRunning(); }
240
241 // Returns true if current thread is the main thread (aka the GUI thread)
242 static bool IsMain();
243
244 // Called when thread exits.
245 virtual void OnExit();
246
247 protected:
248 // Returns TRUE if the thread was asked to terminate
249 bool TestDestroy();
250
251 // Exits from the current thread.
252 void Exit(void *status = NULL);
253
254 private:
255 // Entry point for the thread.
256 virtual void *Entry() = 0;
257
258 private:
259 friend class wxThreadInternal;
260
261 wxThreadInternal *p_internal;
262 };
263
264 // ----------------------------------------------------------------------------
265 // Automatic initialization
266 // ----------------------------------------------------------------------------
267
268 // GUI mutex handling.
269 void WXDLLEXPORT wxMutexGuiEnter();
270 void WXDLLEXPORT wxMutexGuiLeave();
271
272 // implementation only
273 #ifdef __WXMSW__
274 // unlock GUI if there are threads waiting for and lock it back when
275 // there are no more of them - should be called periodically by the main
276 // thread
277 void WXDLLEXPORT wxMutexGuiLeaveOrEnter();
278
279 // returns TRUE if the main thread has GUI lock
280 inline bool WXDLLEXPORT wxGuiOwnedByMainThread();
281
282 // wakes up the main thread if it's sleeping inside ::GetMessage()
283 inline void WXDLLEXPORT wxWakeUpMainThread();
284 #endif // MSW
285
286 #else // !wxUSE_THREADS
287
288 // no thread support
289 inline void WXDLLEXPORT wxMutexGuiEnter() { }
290 inline void WXDLLEXPORT wxMutexGuiLeave() { }
291
292 #endif // wxUSE_THREADS
293
294 // automatically unlock GUI mutex in dtor
295 class WXDLLEXPORT wxMutexGuiLocker
296 {
297 public:
298 wxMutexGuiLocker() { wxMutexGuiEnter(); }
299 ~wxMutexGuiLocker() { wxMutexGuiLeave(); }
300 };
301
302 #endif // __THREADH__