source: nrEngine/src/IThread.cpp @ 32

Revision 32, 5.3 KB checked in by art, 12 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//----------------------------------------------------------------------------------
15// Includes
16//----------------------------------------------------------------------------------
17#include "IThread.h"
18#include "EventManager.h"
19#include "Log.h"
20#include <boost/bind.hpp>
21
22namespace nrEngine{
23
24        //--------------------------------------------------------------------
25        IThread::IThread()// : EventActor(std::string("Thread_") + boost::lexical_cast<std::string>(id))
26        {
27                //mThread = NULL;
28                mThreadState = THREAD_STOP;
29        }
30
31        //--------------------------------------------------------------------
32        IThread::~IThread()
33        {
34                // delete the thread object if it is not empty
35                //if (mThread)
36                //{
37                //      delete mThread;
38                //}
39        }
40
41        //--------------------------------------------------------------------
42        void IThread::threadStart()
43        {
44                // Check if we have already a thread created
45                if (mThread)
46                {
47                        NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "IThread: the appropriate thread is already running!");
48                        return;
49                }
50                NR_Log(Log::LOG_KERNEL, "IThread: Create thread and start it");
51
52                // initialise the attribute
53                /*pthread_attr_init(&mThreadAttr);
54
55                // create the joinable attribute for thsi thread
56                pthread_attr_setdetachstate(&mThreadAttr, PTHREAD_CREATE_JOINABLE);
57
58                // setup thread scheduling attribute
59                pthread_attr_setschedpolicy(&mThreadAttr, SCHED_RR);
60               
61                // now create a thread and let it run
62                int res = pthread_create(&mThread, &mThreadAttr, IThread::run, (void *)this);
63                if (res){
64                        NR_Log(Log::LOG_KERNEL, Log::LL_ERROR, "IThread: creation of a thread failed with error code %d", res);
65                        return;
66                }*/
67   
68                mThreadState = THREAD_RUNNING;
69                mThread.reset(new boost::thread(boost::bind(IThread::run, this)));
70               
71        }
72
73        //--------------------------------------------------------------------
74        void IThread::threadStop()
75        {
76                // change state
77                changeState(THREAD_STOP);
78
79                // join the thread to the main process
80                /*pthread_attr_destroy(&mThreadAttr);
81                int res = pthread_join(mThread, NULL);
82                if (res){
83                        NR_Log(Log::LOG_KERNEL, Log::LL_ERROR, "IThread: can not join running thread (error code %d)", res);
84                        return;
85                }*/
86                mThread->join();
87        }
88
89        //--------------------------------------------------------------------
90        void IThread::threadSuspend()
91        {
92                changeState(THREAD_NEXT_SUSPEND);
93        }
94
95        //--------------------------------------------------------------------
96        void IThread::threadResume()
97        {
98                changeState(THREAD_NEXT_RESUME);
99        }
100
101        //--------------------------------------------------------------------
102        void IThread::changeState(ThreadState newState)
103        {
104                // first lock the mutex and then change the state
105                /*try{
106                        boost::mutex::scoped_lock lock(mMutex);
107                        mThreadState = newState;
108                }catch (boost::lock_error err) {}
109                */
110
111                // lock the mutex change status and unlock it again
112                //pthread_mutex_lock(&mMutex);
113                mThreadState = newState;
114                //pthread_mutex_unlock(&mMutex);
115               
116        }
117
118        //--------------------------------------------------------------------
119        void IThread::yield(IThread* mythread)
120        {
121                // use pthread to yield the timeslice
122                //pthread_yield();
123                boost::thread::yield();
124        }
125
126        //--------------------------------------------------------------------
127        void IThread::run(void* _mythread)
128        {
129                // try to cast the given parameter to IThread pointer
130                IThread* mythread = static_cast<IThread*>(_mythread);
131                if (mythread == NULL)
132                {
133                        NR_Log(Log::LOG_KERNEL, Log::LL_ERROR, "IThread: not valid parameter was specified for IThread::run(void*) method");
134                        return;
135                }
136               
137                // now loop the thread until some messages occurs
138                bool run = true;
139                while (run){
140
141                        // kernel requested to suspend the thread
142                        if (mythread->mThreadState == THREAD_NEXT_SUSPEND)
143                        {
144                                // notice about suspending and go into sleep mode
145                                mythread->changeState(THREAD_SLEEPING);
146                                mythread->_noticeSuspend();
147
148                        // kernel requested to resume the execution
149                        }else if (mythread->mThreadState == THREAD_NEXT_RESUME)
150                        {
151                                // notice about resuming the work and start it again
152                                mythread->changeState(THREAD_RUNNING);
153                                mythread->_noticeResume();
154
155                        // kernel does not requested anything, so run the task
156                        }else if (mythread->mThreadState == THREAD_RUNNING)
157                        {
158                                mythread->_noticeUpdate();
159                        }
160
161                        // check for the stop message, then stop the thread
162                        // this is a reading mutex, so do not have to lock it
163                        run = mythread->mThreadState != THREAD_STOP;
164
165                        // we now yield the used timeslice for another threads
166                        yield(mythread);
167                }
168               
169                // notice to stop the underlying task
170                mythread->_noticeStop();
171
172                // exit the thread
173                //return NULL;
174        }
175
176}; // end namespace
177
Note: See TracBrowser for help on using the repository browser.