source: nrEngine/src/IThread.cpp @ 40

Revision 40, 5.4 KB checked in by art, 12 years ago (diff)

Bindings changed to Packages

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