summaryrefslogtreecommitdiff
path: root/src/stable/thread.h
blob: f0456f36abbaccc2e0fd9ed0ab5661f5512b094f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
 * Copyright (C) 2007-2012 Xagasoft, All rights reserved.
 *
 * This file is part of the libbu++ library and is released under the
 * terms of the license contained in the file LICENSE.
 */

#ifndef BU_THREAD_H
#define BU_THREAD_H

#include <pthread.h>

#include "bu/exceptionbase.h"

namespace Bu
{
	subExceptionDecl( ThreadException );
	class ThreadId
	{
	friend class Thread;
	private:
		ThreadId( pthread_t tId );

	public:
		ThreadId();

		bool operator==( const ThreadId &rhs );
		bool operator!=( const ThreadId &rhs );

	private:
		pthread_t tId;
	};

	/**
	 * Simple thread class.  This wraps the basic pthread (posix threads)
	 * system in an object oriented sort of way.  It allows you to create a
	 * class with standard member variables and callable functions that can be
	 * run in it's own thread, one per class instance.
	 *@ingroup Threading
	 */
	class Thread
	{
	public:
		/**
		 * Construct an Thread thread.
		 */
		Thread();

		/**
		 * Destroy an Thread thread.
		 */
		virtual ~Thread();

		static ThreadId currentThread();
		ThreadId getId() { return ThreadId( ptHandle ); }

		/**
		 * Begin thread execution.  This will call the overridden run function,
		 * which will simply execute in it's own thread until the function
		 * exits, the thread is killed, or the thread is cancelled (optionally).
		 * The thread started in this manner has access to all of it's class
		 * variables, but be sure to protect possible multiple-access with
		 * ThreadMutex objects.
		 * @returns True if starting the thread was successful.  False if
		 * something went wrong and the thread has not started.
		 */
		bool start();

		/**
		 * Forcibly kill a thread.  This is not generally considered a good
		 * thing to do, but in those rare cases you need it, it's invaluable.
		 * The problem with stopping (or killing) a thread is that it stops it
		 * the moment you call stop, no matter what it's doing.  The object
		 * oriented approach to this will help clean up any class variables
		 * that were used, but anything not managed as a member variable will
		 * probably create a memory leak type of situation.  Instead of stop,
		 * consider using cancel, which can be handled by the running thread in
		 * a graceful manner.
		 *@returns True if the thread was stopped, false otherwise.  When this
		 * function returns the thread may not have stopped, to ensure that the
		 * thread has really stopped, call join.
		 */
		bool stop();

		/**
		 * Join the thread in action.  This function performs what is commonly
		 * called a thread join.  That is that it effectively makes the calling
		 * thread an the Thread thread contained in the called object one in the
		 * same, and pauses the calling thread until the called thread exits.
		 * That is, when called from, say, your main(), mythread.join() will
		 * not return until the thread mythread has exited.  This is very handy
		 * at the end of programs to ensure all of your data was cleaned up.
		 *@returns True if the thread was joined, false if the thread couldn't
		 * be joined, usually because it isn't running to begin with.
		 */
		bool join();

	private:
		pthread_t ptHandle;	/**< Internal handle to the posix thread. */

	protected:
		/**
		 * The workhorse of the Thread class.  This is the function that will
		 * run in the thread, when this function exits the thread dies and is
		 * cleaned up by the system.  Make sure to read up on ThreadMutex,
		 * ThreadCondition, and cancel to see how to control and protect
		 * everything you do in a safe way within this function.
		 *@returns I'm not sure right now, but this is the posix standard form.
		 */
		virtual void run()=0;

		/**
		 * This is the hidden-heard of the thread system.  While run is what the
		 * user gets to override, and everything said about it is true, this is
		 * the function that actually makes up the thread, it simply calls the
		 * run member function in an OO-friendly way.  This is what allows us to
		 * use member variables from within the thread itself.
		 *@param pThread Should always be this.
		 *@returns This is specified by posix, I'm not sure yet.
		 */
		static void *threadRunner( void *pThread );

		void yield();
	};
}

#endif