root/trunk/dep/include/zthread/Thread.h @ 242

Revision 2, 10.6 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
1/*
2 * Copyright (c) 2005, Eric Crahen
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is furnished
9 * to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in all
12 * copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 *
21 */
22
23#ifndef __ZTTHREAD_H__
24#define __ZTTHREAD_H__
25
26#include "zthread/Cancelable.h"
27#include "zthread/Priority.h"
28#include "zthread/NonCopyable.h"
29#include "zthread/Task.h"
30#include "zthread/Waitable.h"
31
32namespace ZThread {
33 
34  class ThreadImpl;
35 
36  /**
37   * @class Thread
38   * @author Eric Crahen <http://www.code-foo.com>
39   * @date <2003-07-27T11:17:59-0400>
40   * @version 2.3.0
41   *
42   *
43   * @see Task
44   * @see Executor
45   *
46   * <h2>Examples</h2>
47   * - <a href="#ex1">Launching a task</a>
48   * - <a href="#ex2">Waiting for a task</a>
49   * - <a href="#ex3">Sharing a task</a>
50   *
51   * <h2><a name="ex1">Launching a task</a></h2>
52   *
53   * A thread is started simply by constructing a thread object and giving
54   * it a task to perform. The thread will continue to run its task, even
55   * after the Thread object used to launch the thread has gone out of scope.
56   *
57   * @code
58   * #include "zthread/Thread.h"
59   * #include <iostream>
60   *
61   * using namespace ZThread;
62   *
63   * class aRunnable : public Runnable {
64   *
65   *   void run() {
66   *
67   *     Thread::sleep(1000);
68   *     std::cout << "Hello from another thread" << std::endl;
69   *
70   *   }
71   *
72   * };
73   *
74   * int main() {
75   *
76   *   try {
77   *     
78   *     // Implictly constructs a Task
79   *     Thread t(new aRunnable);
80   *
81   *   } catch(Synchronization_Exception& e) {
82   *     std::cerr << e.what() << std::endl;
83   *   }
84   *
85   *   std::cout << "Hello from the main thread" << std::endl;
86   *
87   *   // Output:
88   *
89   *   // Hello from the main thread
90   *   // Hello from another thread
91   *
92   *   return 0;
93   *
94   * }
95   *
96   * @endcode
97   *
98   * <h2><a name="ex2">Waiting for a task</a></h2>
99   *
100   * A user can exercise some simple synchronization by waiting for a thread
101   * to complete running its task.
102   *
103   * @code
104   * #include "zthread/Thread.h"
105   * #include <iostream>
106   *
107   * using namespace ZThread;
108   *
109   * class aRunnable : public Runnable {
110   * public:
111   *
112   *   void run() {
113   *
114   *     Thread::sleep(1000);
115   *     std::cout << "Hello from another thread" << std::endl;
116   *
117   *   }
118   *
119   * };
120   *
121   * int main() {
122   *
123   *   try {
124   *     
125   *     // Implictly constructs a Task
126   *     Thread t(new aRunnable);
127   *     t.wait();
128   *
129   *   } catch(Synchronization_Exception& e) {
130   *     std::cerr << e.what() << std::endl;
131   *   }
132   *
133   *   std::cout << "Hello from the main thread" << std::endl;
134   *
135   *   // Output:
136   *
137   *   // Hello from another thread
138   *   // Hello from the main thread
139   *
140   *   return 0;
141   *
142   * }
143   *
144   * @endcode
145   *
146   * <h2><a name="ex3">Sharing a task</a></h2>
147   *
148   * The same task can be shared by more than one thread. A Task is constructed
149   * from a Runnable, and that Task object is copied by value and handed off to
150   * each thread.
151   *
152   * @code
153   * #include "zthread/Thread.h"
154   * #include <iostream>
155   *
156   * using namespace ZThread;
157   *
158   * class aRunnable : public Runnable {
159   *
160   *   void run() {
161   *
162   *     Thread::sleep(1000);
163   *     std::cout << "Hello from another thread" << std::endl;
164   *
165   *   }
166   *
167   * };
168   *
169   * int main() {
170   *
171   *   try {
172   *     
173   *     // Explictly constructs a Task
174   *     Task task(new aRunnable);
175   *
176   *     // Two threads created to run the same Task
177   *     Thread t1(task);
178   *     Thread t2(task);
179   *
180   *   } catch(Synchronization_Exception& e) {
181   *     std::cerr << e.what() << std::endl;
182   *   }
183   *
184   *   std::cout << "Hello from the main thread" << std::endl;
185   *
186   *   // Output:
187   *
188   *   // Hello from the main thread
189   *   // Hello from another thread
190   *   // Hello from another thread
191   *
192   *   return 0;
193   *
194   * }
195   *
196   * @endcode
197   */
198  class ZTHREAD_API Thread
199    : public Cancelable, public Waitable, public NonCopyable {
200
201    //! Delegate
202    ThreadImpl* _impl;
203
204  public:
205
206    /**
207     * Create a Thread that represents the current thread.
208     * <em>Using the static members of Thread should be preferred over using this constructor</em>
209     */
210    Thread();
211
212    /**
213     * Create a Thread that spawns a new thread to run the given task.
214     *
215     * @param task Task to be run by a thread managed by this executor
216     * @param autoCancel flag to requestion automatic cancellation
217     *
218     * @post if the <i>autoCancel</i> flag was true, this thread will
219     *       automatically be canceled when main() goes out of scope.
220     */
221    Thread(const Task&, bool autoCancel = false);
222
223    //! Destroy the Thread
224    ~Thread();
225
226    //! Comparison operator
227    bool operator==(const Thread& t) const;
228
229    //! Comparison operator
230    inline bool operator!=(const Thread& t) const {
231      return !(*this == t);
232    }
233
234    /**
235     * Wait for the thread represented by this object to complete its task.
236     * The calling thread is blocked until the thread represented by this
237     * object exits.
238     *
239     * @exception Deadlock_Exception thrown if thread attempts to join itself
240     * @exception InvalidOp_Exception thrown if the thread cannot be joined
241     * @exception Interrupted_Exception thrown if the joining thread has been interrupt()ed
242     */
243    void wait();
244 
245    /**
246     * Wait for the thread represented by this object to complete its task.
247     * The calling thread is blocked until the thread represented by this
248     * object exits, or until the timeout expires.
249     *
250     * @param timeout maximum amount of time (milliseconds) this method
251     *        could block the calling thread.
252     *
253     * @return
254     *   - <em>true</em> if the thread task complete before <i>timeout</i>
255     *     milliseconds elapse.
256     *   - <em>false</em> othewise.
257     *
258     * @exception Deadlock_Exception thrown if thread attempts to join itself
259     * @exception InvalidOp_Exception thrown if the thread cannot be joined
260     * @exception Interrupted_Exception thrown if the joining thread has been interrupt()ed
261     */
262    bool wait(unsigned long timeout);
263 
264    /**
265     * Change the priority of this Thread. This will change the actual
266     * priority of the thread when the OS supports it.
267     *
268     * If there is no real priority support, it's simulated.
269     *
270     * @param p - new Priority
271     */
272    void setPriority(Priority p);
273
274    /**
275     * Get the priority of this Thread.
276     *
277     * @return Priority
278     */
279    Priority getPriority();
280
281    /**
282     * Interrupts this thread, setting the <i>interrupted</i> status of the thread.
283     * This status is cleared by one of three methods.
284     *
285     * If this thread is blocked when this method is called, the thread will
286     * abort that blocking operation with an Interrupted_Exception.
287     *
288     *  - The first is by attempting an operation on a synchronization object that
289     *    would normally block the calling thread; Instead of blocking the calling
290     *    the calling thread, the function that would normally block will thrown an
291     *    Interrupted_Exception and clear the <i>interrupted</i> status of the thread.
292     *
293     *  - The second is by calling Thread::interrupted().
294     *
295     *  - The third is by calling Thread::canceled().
296     *
297     * Threads already blocked by an operation on a synchronization object will abort
298     * that operation with an Interrupted_Exception, clearing the threads <i>interrupted</i>
299     * status as in the first case described above.
300     *
301     * Interrupting a thread that is no longer running will have no effect.
302     *
303     * @return
304     *   - <em>true</em> if the thread was interrupted while not blocked by a wait
305     *     on a synchronization object.
306     *   - <em>false</em> othewise.
307     */
308    bool interrupt();
309
310    /**
311     * Tests whether the current Thread has been interrupt()ed, clearing
312     * its interruption status.
313     *
314     * @return
315     *   - <em>true</em> if the Thread was interrupted.
316     *   - <em>false</em> otherwise.
317     *
318     * @post The <i>interrupted</i> status of the current thread will be cleared,
319     *       allowing it to perform a blocking operation on a synchronization
320     *       object without throwing an exception.
321     */
322    static bool interrupted();
323
324    /**
325     * Tests whether the current Thread has been canceled, and clears the
326     * interrupted status.
327     *
328     * @return bool true only if the Thread::cancel() has been invoked.
329     */
330    static bool canceled();
331
332    /**
333     * Tests whether this thread has been canceled. If called from the context
334     * of this thread, the interrupted status is cleared.
335     *
336     * @return
337     *   - <em>true</em> if the Thread was canceled.
338     *   - <em>false</em> otherwise.
339     *
340     * @see Cancelable::isCanceled()
341     */
342    virtual bool isCanceled();
343
344    /**
345     * Interrupt and cancel this thread in a single operation. The thread will
346     * return <em>true</em> whenever its cancelation status is tested in the future.
347     *
348     * @exception InvalidOp_Exception thrown if a thread attempts to cancel itself
349     *
350     * @see Thread::interrupt()
351     * @see Cancelable::cancel()
352     */
353    virtual void cancel();
354
355    /**
356     * Put the currently executing thread to sleep for a given amount of
357     * time.
358     *
359     * @param timeout maximum amount of time (milliseconds) this method could block
360     *
361     * @exception Interrupted_Exception thrown if the threads sleep is interrupted
362     *            before <i>timeout</i> milliseconds expire.
363     */
364    static void sleep(unsigned long timeout);
365
366    /**
367     * Cause the currently executing thread to yield, allowing the scheduler
368     * to assign some execution time to another thread.
369     */
370    static void yield();
371
372
373  }; /* Thread */
374
375
376} // namespace ZThread
377
378#endif // __ZTTHREAD_H__
379
380
381
Note: See TracBrowser for help on using the browser.