source: nrEngine/include/IThread.h @ 1

Revision 1, 7.2 KB checked in by art, 13 years ago (diff)
Line 
1/***************************************************************************
2 *                                                                         *
3 *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
4 *       mailto: <tevs@mpi-sb.mpg.de>                                      *
5 *                                                                         *
6 *   This program is free software; you can redistribute it and/or modify  *
7 *   it under the terms of the GNU General Public License as published by  *
8 *   the Free Software Foundation; either version 2 of the License, or     *
9 *   (at your option) any later version.                                   *
10 *                                                                         *
11 ***************************************************************************/
12
13
14#ifndef _NR_I_THREAD_H_
15#define _NR_I_THREAD_H_
16
17//----------------------------------------------------------------------------------
18// Includes
19//----------------------------------------------------------------------------------
20#include "Prerequisities.h"
21
22#include <boost/thread/thread.hpp>
23#include <boost/thread/mutex.hpp>
24
25namespace nrEngine{
26
27        //! Abstract class to run a ITask in a thread controlled by Kernel
28        /**
29         * IThread is a base class for each kin dof tasks, allows also parallel
30         * running of a task as a thread. Kernel tasks are derived from thi class
31         * so a task has also a possibility to run in a own thread. Kernel
32         * controls the creation and managing of threads. Threads communicate
33         * through the engine's default communication protocol.
34         *
35         * Writing a task as a thread for your application is not a big issue.
36         * You have to listen on kernel messages coming on the engine's default
37         * channel to be able to react on stop/suspend/resume messages. Kernel
38         * can not simply hold on a task. Because this can corrupt data if a task was
39         * performing any important calculations. Also this is not a good style.
40         * Kernel will provide a function to force a killing of a thread-task, but
41         * prevent using of this function.
42         *
43         * Instead of killing the running threads, kernel will send a message about
44         * stopping the thread. A thread-task should react on this event to
45         * gracefully stop the execution.
46         *
47         * The thread interface does provide neccessary functions to your tasks, so
48         * you do not have to think about managing the kernel messages by yourself.
49         * Instead of this the thread will call taskStop() method to indicate the task,
50         * that kernel want to stop the thread. Suspending the task will cause the kernel
51         * to let the according thread sleeping until the task is resumed. There is
52         * no other way how you can let the task to sleep.
53         *
54         * So how the thread interface cooperate with the kernel and the task interface.
55         * You write your task in the way, like if it were a simple task running
56         * sequentially in the kernel. Each ITask itnerface is a derived class from
57         * IThread but a thread portion of the code will only be active if you use the task
58         * as a thread for the kernel. By marking the task as a thread i.e. by adding
59         * the task to the kernel as a thread, you will activate the thread interface automatic.
60         * Kernel will start the thread and will call the taskInit() and taskStart() functions
61         * at the right moment. If the task is a thread, so it will call threadStart() instead
62         * which will call thread_taskStart() method of derived ITask interface. The method
63         * will call your taskStart() method, so you will not notice if there is a difference
64         * between starting a task as a task or as a thread.
65         *
66         * In each cycly the kernel does call taskUpdate() method for sequential tasks. For
67         * parallel tasks (threads) it does not call anything, because thread interface already
68         * running and it will automaticaly call the appropritate taskUpdate() method, so
69         * the task is getting updated. Also the thread base class does check if there is
70         * any messages from the kernel (i.e. sleep or stop). If so it will call appropriate
71         * methods in ITask interface.
72         *
73         * NOTE: The IThread interaface and Kernel does do all the job for you to manage
74         * themself as a threads and to let them run in parallel. The only one thing it
75         * can not manage for you is synchronisation. You have to worry about this by yourself
76         * by using of mutex locking mechanism.
77         *
78         * \ingroup kernel
79        **/
80        class _NRExport IThread{
81                public:
82                        /**
83                         * Virtual destructor so we are able to derive classes
84                         * with overloaded methods.
85                         **/
86                        virtual ~IThread();
87
88                protected:
89
90                        /**
91                         * Protected constructor, so only the ITask-Interface
92                         * and friends are able to create an instance of this class.
93                         * In this way we protect wrong usage of this interface.
94                         **/
95                        IThread();
96
97                        /**
98                         * Call this method if a thread goes into sleep mode. The derived
99                         * task should reimplement this method to call the appropriate suspend
100                         * method
101                         **/
102                        virtual void _noticeSuspend() = 0;
103
104                        /**
105                         * Call this method by waking up a thread. The derived task interface
106                         * should call the appropritate resume method
107                         **/
108                        virtual void _noticeResume() = 0;
109
110                        /**
111                         * Thread does call this method in a main loop. The method
112                         * should call the appropritate update method in ITask interface
113                         **/
114                        virtual void _noticeUpdate() = 0;
115
116                        /**
117                         * Call this method by stopping the execution of a thread. The underlying
118                         * task has to remove all used data, because after calling of this method
119                         * it will be destroyed
120                         **/
121                        virtual void _noticeStop() = 0;
122
123                private:
124
125                        //! Store here the thread instance
126                        boost::thread*  mThread;
127
128                        /**
129                         * This is a entry point for a thread. The method is
130                         * static because it do not have to access any data
131                         * of the objec titself. The given thread instance as a parameter
132                         * will be updated and managed as a thread.
133                         **/
134                        static void run(IThread* mythread);
135
136                        //! Kernel is a friend class
137                        friend class Kernel;
138
139                        /**
140                         * Kernel does call this method if the appropriate task is running
141                         * as a thread in the kernel. This method manage the derived class by calling appropriate
142                         * virtual methods, which has to be reimplemented in the ITask interface.
143                         **/
144                        void threadStart();
145
146                        /**
147                         * Kernel does call this method, if a thread should stop.
148                         **/
149                        void threadStop();
150
151                        /**
152                         * Kernel call this method if a thread is going into sleep mode
153                         **/
154                        void threadSuspend();
155
156                        /**
157                         * Kernel call this method if a thread is goind to resume
158                         **/
159                        void threadResume();
160
161                        //! Define thread states
162                        enum ThreadState{
163                                //! Thread is not running it is stopped
164                                THREAD_STOP,
165
166                                //! Thread does running
167                                THREAD_RUNNING,
168
169                                //! Thread is in sleep state (no action, but ready to wakeup)
170                                THREAD_SLEEPING,
171
172                                //! Wakeup the thread as soon as possible
173                                THREAD_NEXT_RESUME,
174
175                                //! Suspend the thread as soon as possible
176                                THREAD_NEXT_SUSPEND
177                        };
178
179                        //! This is a variable which will manage the thread state
180                        volatile ThreadState    mThreadState;
181
182                        //! Mutex to lock the data before use
183                        boost::mutex mMutex;
184
185                        //! Change a thread to new state, use mutex to lock the state
186                        void changeState(ThreadState newState);
187
188        };
189
190}; // end namespace
191#endif  //_NR...
Note: See TracBrowser for help on using the repository browser.