source: nrEngine/src/IThread.cpp @ 11

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