1 | /*
|
---|
2 | * synergy -- mouse and keyboard sharing utility
|
---|
3 | * Copyright (C) 2002 Chris Schoeneman
|
---|
4 | *
|
---|
5 | * This package is free software; you can redistribute it and/or
|
---|
6 | * modify it under the terms of the GNU General Public License
|
---|
7 | * found in the file COPYING that should have accompanied this file.
|
---|
8 | *
|
---|
9 | * This package is distributed in the hope that it will be useful,
|
---|
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
---|
12 | * GNU General Public License for more details.
|
---|
13 | */
|
---|
14 |
|
---|
15 | #ifndef CTHREAD_H
|
---|
16 | #define CTHREAD_H
|
---|
17 |
|
---|
18 | #include "IArchMultithread.h"
|
---|
19 |
|
---|
20 | class IJob;
|
---|
21 |
|
---|
22 | //! Thread handle
|
---|
23 | /*!
|
---|
24 | Creating a CThread creates a new context of execution (i.e. thread) that
|
---|
25 | runs simulatenously with the calling thread. A CThread is only a handle
|
---|
26 | to a thread; deleting a CThread does not cancel or destroy the thread it
|
---|
27 | refers to and multiple CThread objects can refer to the same thread.
|
---|
28 |
|
---|
29 | Threads can terminate themselves but cannot be forced to terminate by
|
---|
30 | other threads. However, other threads can signal a thread to terminate
|
---|
31 | itself by cancelling it. And a thread can wait (block) on another thread
|
---|
32 | to terminate.
|
---|
33 |
|
---|
34 | Most functions that can block for an arbitrary time are cancellation
|
---|
35 | points. A cancellation point is a function that can be interrupted by
|
---|
36 | a request to cancel the thread. Cancellation points are noted in the
|
---|
37 | documentation.
|
---|
38 | */
|
---|
39 | // note -- do not derive from this class
|
---|
40 | class CThread {
|
---|
41 | public:
|
---|
42 | //! Run \c adoptedJob in a new thread
|
---|
43 | /*!
|
---|
44 | Create and start a new thread executing the \c adoptedJob. The
|
---|
45 | new thread takes ownership of \c adoptedJob and will delete it.
|
---|
46 | */
|
---|
47 | CThread(IJob* adoptedJob);
|
---|
48 |
|
---|
49 | //! Duplicate a thread handle
|
---|
50 | /*!
|
---|
51 | Make a new thread object that refers to an existing thread.
|
---|
52 | This does \b not start a new thread.
|
---|
53 | */
|
---|
54 | CThread(const CThread&);
|
---|
55 |
|
---|
56 | //! Release a thread handle
|
---|
57 | /*!
|
---|
58 | Release a thread handle. This does not terminate the thread. A thread
|
---|
59 | will keep running until the job completes or calls exit() or allows
|
---|
60 | itself to be cancelled.
|
---|
61 | */
|
---|
62 | ~CThread();
|
---|
63 |
|
---|
64 | //! @name manipulators
|
---|
65 | //@{
|
---|
66 |
|
---|
67 | //! Assign thread handle
|
---|
68 | /*!
|
---|
69 | Assign a thread handle. This has no effect on the threads, it simply
|
---|
70 | makes this thread object refer to another thread. It does \b not
|
---|
71 | start a new thread.
|
---|
72 | */
|
---|
73 | CThread& operator=(const CThread&);
|
---|
74 |
|
---|
75 | //! Terminate the calling thread
|
---|
76 | /*!
|
---|
77 | Terminate the calling thread. This function does not return but
|
---|
78 | the stack is unwound and automatic objects are destroyed, as if
|
---|
79 | exit() threw an exception (which is, in fact, what it does). The
|
---|
80 | argument is saved as the result returned by getResult(). If you
|
---|
81 | have \c catch(...) blocks then you should add the following before
|
---|
82 | each to avoid catching the exit:
|
---|
83 | \code
|
---|
84 | catch(CThreadExit&) { throw; }
|
---|
85 | \endcode
|
---|
86 | or add the \c RETHROW_XTHREAD macro to the \c catch(...) block.
|
---|
87 | */
|
---|
88 | static void exit(void*);
|
---|
89 |
|
---|
90 | //! Cancel thread
|
---|
91 | /*!
|
---|
92 | Cancel the thread. cancel() never waits for the thread to
|
---|
93 | terminate; it just posts the cancel and returns. A thread will
|
---|
94 | terminate when it enters a cancellation point with cancellation
|
---|
95 | enabled. If cancellation is disabled then the cancel is
|
---|
96 | remembered but not acted on until the first call to a
|
---|
97 | cancellation point after cancellation is enabled.
|
---|
98 |
|
---|
99 | A cancellation point is a function that can act on cancellation.
|
---|
100 | A cancellation point does not return if there's a cancel pending.
|
---|
101 | Instead, it unwinds the stack and destroys automatic objects, as
|
---|
102 | if cancel() threw an exception (which is, in fact, what it does).
|
---|
103 | Threads must take care to unlock and clean up any resources they
|
---|
104 | may have, especially mutexes. They can \c catch(XThreadCancel) to
|
---|
105 | do that then rethrow the exception or they can let it happen
|
---|
106 | automatically by doing clean up in the d'tors of automatic
|
---|
107 | objects (like CLock). Clients are strongly encouraged to do the latter.
|
---|
108 | During cancellation, further cancel() calls are ignored (i.e.
|
---|
109 | a thread cannot be interrupted by a cancel during cancellation).
|
---|
110 |
|
---|
111 | Clients that \c catch(XThreadCancel) must always rethrow the
|
---|
112 | exception. Clients that \c catch(...) must either rethrow the
|
---|
113 | exception or include a \c catch(XThreadCancel) handler that
|
---|
114 | rethrows. The \c RETHROW_XTHREAD macro may be useful for that.
|
---|
115 | */
|
---|
116 | void cancel();
|
---|
117 |
|
---|
118 | //! Change thread priority
|
---|
119 | /*!
|
---|
120 | Change the priority of the thread. Normal priority is 0, 1 is
|
---|
121 | the next lower, etc. -1 is the next higher, etc. but boosting
|
---|
122 | the priority may not be permitted and will be silenty ignored.
|
---|
123 | */
|
---|
124 | void setPriority(int n);
|
---|
125 |
|
---|
126 | //! Force pollSocket() to return
|
---|
127 | /*!
|
---|
128 | Forces a currently blocked pollSocket() in the thread to return
|
---|
129 | immediately.
|
---|
130 | */
|
---|
131 | void unblockPollSocket();
|
---|
132 |
|
---|
133 | //@}
|
---|
134 | //! @name accessors
|
---|
135 | //@{
|
---|
136 |
|
---|
137 | //! Get current thread's handle
|
---|
138 | /*!
|
---|
139 | Return a CThread object representing the calling thread.
|
---|
140 | */
|
---|
141 | static CThread getCurrentThread();
|
---|
142 |
|
---|
143 | //! Test for cancellation
|
---|
144 | /*!
|
---|
145 | testCancel() does nothing but is a cancellation point. Call
|
---|
146 | this to make a function itself a cancellation point. If the
|
---|
147 | thread was cancelled and cancellation is enabled this will
|
---|
148 | cause the thread to unwind the stack and terminate.
|
---|
149 |
|
---|
150 | (cancellation point)
|
---|
151 | */
|
---|
152 | static void testCancel();
|
---|
153 |
|
---|
154 | //! Wait for thread to terminate
|
---|
155 | /*!
|
---|
156 | Waits for the thread to terminate (by exit() or cancel() or
|
---|
157 | by returning from the thread job) for up to \c timeout seconds,
|
---|
158 | returning true if the thread terminated and false otherwise.
|
---|
159 | This returns immediately with false if called by a thread on
|
---|
160 | itself and immediately with true if the thread has already
|
---|
161 | terminated. This will wait forever if \c timeout < 0.0.
|
---|
162 |
|
---|
163 | (cancellation point)
|
---|
164 | */
|
---|
165 | bool wait(double timeout = -1.0) const;
|
---|
166 |
|
---|
167 | //! Get the exit result
|
---|
168 | /*!
|
---|
169 | Returns the exit result. This does an implicit wait(). It returns
|
---|
170 | NULL immediately if called by a thread on itself or on a thread that
|
---|
171 | was cancelled.
|
---|
172 |
|
---|
173 | (cancellation point)
|
---|
174 | */
|
---|
175 | void* getResult() const;
|
---|
176 |
|
---|
177 | //! Get the thread id
|
---|
178 | /*!
|
---|
179 | Returns an integer id for this thread. This id must not be used to
|
---|
180 | check if two CThread objects refer to the same thread. Use
|
---|
181 | operator==() for that.
|
---|
182 | */
|
---|
183 | IArchMultithread::ThreadID
|
---|
184 | getID() const;
|
---|
185 |
|
---|
186 | //! Compare thread handles
|
---|
187 | /*!
|
---|
188 | Returns true if two CThread objects refer to the same thread.
|
---|
189 | */
|
---|
190 | bool operator==(const CThread&) const;
|
---|
191 |
|
---|
192 | //! Compare thread handles
|
---|
193 | /*!
|
---|
194 | Returns true if two CThread objects do not refer to the same thread.
|
---|
195 | */
|
---|
196 | bool operator!=(const CThread&) const;
|
---|
197 |
|
---|
198 | //@}
|
---|
199 |
|
---|
200 | private:
|
---|
201 | CThread(CArchThread);
|
---|
202 |
|
---|
203 | static void* threadFunc(void*);
|
---|
204 |
|
---|
205 | private:
|
---|
206 | CArchThread m_thread;
|
---|
207 | };
|
---|
208 |
|
---|
209 | #endif
|
---|