Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 #include <blort/ThreadObject/Thread.h>
00079 
00080 
00081 #ifndef WINDOWS
00082 extern "C"
00083 {
00084  int    usleep(useconds_t useconds);
00085 #ifdef NANO_SECOND_SLEEP
00086  int    nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
00087 #endif
00088 }
00089 
00090 void Sleep( unsigned int milli )
00091 {
00092 #ifdef NANO_SECOND_SLEEP
00093         struct timespec interval, remainder;
00094         milli = milli * 1000000;
00095         interval.tv_sec= 0;
00096         interval.tv_nsec=milli;
00097         nanosleep(&interval,&remainder);
00098 #else
00099         usleep(milli*1000);
00100 #endif  
00101 }
00102 #endif
00103 
00104 #include <iostream>
00105 using namespace std;
00106 
00114 #ifdef WINDOWS
00115 DWORD WINAPI
00116 #else
00117 LPVOID
00118 #endif
00119 _THKERNEL( LPVOID lpvData  
00120                   )
00121 {
00122         CThread *pThread = (CThread *)lpvData;
00123         ThreadType_t lastType;
00124         
00125 
00126 
00127 
00128 
00129 
00130 
00131     pThread->m_mutex.Lock();
00132                 pThread->m_state = ThreadStateWaiting;
00133                 pThread->m_bRunning = TRUE;
00134 #ifndef WINDOWS
00135                 pThread->m_dwId = CThread::ThreadId();
00136 #endif
00137         pThread->m_mutex.Unlock();
00138         
00139         while( TRUE )
00140         {
00141                 lastType = pThread->m_type;
00142 
00143                 if( lastType == ThreadTypeEventDriven )
00144                 {
00145                         if( ! pThread->m_event.Wait()  ) 
00146                                         break;
00147                 }
00148         
00149                 if( ! pThread->KernelProcess() ) 
00150                                 break;
00151 
00152 
00153                 if( lastType == ThreadTypeEventDriven )
00154                         pThread->m_event.Reset();
00155 
00156                 if( pThread->m_type == ThreadTypeIntervalDriven )
00157                         Sleep(pThread->m_dwIdle);
00158 
00159         }
00160 
00161 
00162         pThread->m_mutex.Lock();
00163                 pThread->m_state = ThreadStateDown;
00164                 pThread->m_bRunning = FALSE;
00165         pThread->m_mutex.Unlock();
00166 
00167 
00168 #ifdef WINDOWS
00169         return 0;
00170 #else
00171         return (LPVOID)0;
00172 #endif
00173 }
00174 
00182 BOOL 
00183 CThread::OnTask( LPVOID lpvData  
00184                                            )
00185 {
00186         CTask *pTask = (CTask *)lpvData;
00187 
00188         pTask->SetTaskStatus(TaskStatusBeingProcessed);
00189 
00190     BOOL bReturn = pTask->Task();
00191 
00192         pTask->SetTaskStatus(TaskStatusCompleted);
00193 
00194 
00195         return bReturn; 
00196 } 
00197 
00198 
00206 BOOL
00207 CThread::OnTask()
00208 {
00209         printf("\nthread is alive\n");
00210 
00211         return TRUE;
00212 }
00213 
00214 
00215 BOOL
00216 CThread::Event(CTask *pvTask 
00217                            )
00218 {
00219         ThreadId_t id;
00220         m_mutex.Lock();
00221         if( m_type != ThreadTypeEventDriven )
00222         {
00223                 m_mutex.Unlock();
00224                 m_dwObjectCondition |= ILLEGAL_USE_OF_EVENT;
00225                 m_state = ThreadStateFault;
00226                 return FALSE;
00227         }
00228 
00229         m_mutex.Unlock();
00230         GetId(&id);
00231         pvTask->SetId(&id);
00232         if( ! Push((LPVOID)pvTask) )
00233                 return FALSE;
00234 
00235         pvTask->SetTaskStatus(TaskStatusWaitingOnQueue);
00236         m_event.Set();
00237 
00238         return TRUE;
00239 }
00240 
00247 BOOL
00248 CThread::Event(LPVOID lpvData 
00249                            )
00250 {
00251         m_mutex.Lock();
00252         if( m_type != ThreadTypeEventDriven )
00253         {
00254                 m_mutex.Unlock();
00255                 m_dwObjectCondition |= ILLEGAL_USE_OF_EVENT;
00256                 m_state = ThreadStateFault;
00257                 return FALSE;
00258         }
00259 
00260         m_mutex.Unlock();
00261         if( ! Push(lpvData) )
00262                 return FALSE;
00263 
00264         m_event.Set();
00265 
00266         return TRUE;
00267 }
00268 
00269 
00278 void
00279 CThread::SetPriority(DWORD dwPriority)
00280 {
00281 
00282 #ifdef WINDOWS
00283         SetThreadPriority(m_thread,dwPriority);
00284 #endif
00285 }
00286 
00287           
00294 BOOL
00295 CThread::KernelProcess()
00296 {
00297 
00298         m_mutex.Lock();
00299         m_state = ThreadStateBusy;
00300         if( !m_bRunning )
00301         {
00302                 m_state = ThreadStateShuttingDown;
00303                 m_mutex.Unlock();
00304                 return FALSE;
00305         }
00306         m_mutex.Unlock();
00307 
00308         if( !Empty() )
00309         {
00310                 while( !Empty() )
00311                 {
00312                         Pop();
00313                         if( !OnTask(m_lpvProcessor) )
00314                         {
00315                                 m_mutex.Lock();
00316                                 m_lpvProcessor = NULL;
00317                                 m_state = ThreadStateShuttingDown;
00318                                 m_mutex.Unlock();
00319                                 return FALSE;
00320                         }
00321                 }
00322                 m_mutex.Lock();
00323                 m_lpvProcessor = NULL;
00324                 m_state = ThreadStateWaiting;
00325         }
00326         else {
00327                 if( !OnTask() )
00328                 {
00329                         m_mutex.Lock();
00330                         m_state = ThreadStateShuttingDown;
00331                         m_mutex.Unlock();
00332                         return FALSE;
00333                 }
00334                 m_mutex.Lock();
00335                 m_state = ThreadStateWaiting;
00336         }
00337 
00338         m_mutex.Unlock();
00339 
00340         return TRUE;
00341 }
00342 
00343 
00351 unsigned int
00352 CThread::GetEventsPending()
00353 {
00354         unsigned int chEventsWaiting;
00355 
00356         m_mutex.Lock();
00357           chEventsWaiting = m_quePos;
00358     m_mutex.Unlock();
00359 
00360         return chEventsWaiting;
00361 }
00362 
00363 
00371 CThread::CThread(void)
00372 :m_bRunning(FALSE)
00373 #ifdef WINDOWS
00374 ,m_thread(NULL)
00375 #endif
00376 ,m_dwId(0L)
00377 ,m_chQue(QUE_SIZE)
00378 ,m_quePos(0)
00379 ,m_lpvProcessor(NULL)
00380 ,m_dwIdle(100)
00381 ,m_type(ThreadTypeEventDriven)
00382 ,m_stackSize(DEFAULT_STACK_SIZE)
00383 {
00384 
00385         m_dwObjectCondition = NO_ERRORS;
00386 
00387         m_lppvQue = new LPVOID [QUE_SIZE];
00388 
00389         if( !m_lppvQue ) 
00390         {
00391                 m_dwObjectCondition |= MEMORY_FAULT;
00392                 m_state = ThreadStateFault;
00393                 return;
00394         }
00395 
00396         if( !m_mutex.m_bCreated )
00397         {
00398                 perror("mutex creation failed");
00399                 m_dwObjectCondition |= MUTEX_CREATION;
00400                 m_state = ThreadStateFault;
00401                 return;
00402         }
00403 
00404 
00405         if( !m_event.m_bCreated )
00406         {
00407                 perror("event creation failed");
00408                 m_dwObjectCondition |= EVENT_CREATION;
00409                 m_state = ThreadStateFault;
00410                 return;
00411         }
00412 
00413 
00414         Start();
00415 
00416 }
00417 
00425 BOOL
00426 CThread::Empty()
00427 {
00428         m_mutex.Lock();
00429         if( m_quePos <= 0 )
00430         {
00431                 m_mutex.Unlock();
00432                 return TRUE;
00433         }
00434         m_mutex.Unlock();
00435         return FALSE;
00436 }
00437 
00438 
00439 
00446 BOOL
00447 CThread::Push( LPVOID lpv )
00448 {
00449         if( !lpv ) return TRUE;
00450 
00451         m_mutex.Lock();
00452 
00453         if( m_quePos+1 >= m_chQue ) {
00454                 m_mutex.Unlock();
00455                 return FALSE;
00456         }
00457 
00458         m_lppvQue[m_quePos++] = lpv;
00459         m_mutex.Unlock();
00460         return TRUE;
00461 }
00462 
00463 
00470 BOOL
00471 CThread::Pop()
00472 {
00473 
00474         m_mutex.Lock();
00475         if( (int)m_quePos-1 < 0 )
00476         {
00477                 m_quePos = 0;
00478                 m_mutex.Unlock();
00479                 return FALSE;
00480         }
00481         m_quePos--;
00482         m_lpvProcessor = m_lppvQue[m_quePos];
00483         m_mutex.Unlock();
00484         return TRUE;
00485 }
00486 
00487 
00501 void
00502 CThread::SetThreadType(ThreadType_t typ,
00503               DWORD dwIdle)
00504 {
00505 
00506         m_mutex.Lock();
00507          m_dwIdle = dwIdle;
00508         
00509          if( m_type == typ ) {
00510                  m_mutex.Unlock();
00511                  return;
00512          }
00513 
00514                 m_type = typ;
00515 
00516 
00517    m_mutex.Unlock();
00518    m_event.Set();
00519 }
00520 
00521 
00528 void
00529 CThread::Stop()
00530 {
00531                 m_mutex.Lock();
00532                         m_bRunning = FALSE;
00533                 m_mutex.Unlock();
00534                 Event();
00535 
00536                 Sleep(m_dwIdle);
00537                 while(TRUE)
00538                 {
00539                         m_mutex.Lock();
00540                         if( m_state == ThreadStateDown )
00541                         {
00542                                 m_mutex.Unlock();
00543                                 return;
00544                         }
00545                         m_mutex.Unlock();
00546                         Sleep(m_dwIdle);
00547                 }
00548 }
00549 
00550 
00557 void
00558 CThread::SetIdle(DWORD dwIdle)
00559 {
00560         m_mutex.Lock();
00561                 m_dwIdle = dwIdle;
00562         m_mutex.Unlock();
00563 }
00564 
00571 BOOL
00572 CThread::Start()
00573 {
00574         m_mutex.Lock();
00575         if( m_bRunning ) 
00576         {
00577                 m_mutex.Unlock();
00578                 return TRUE;
00579         }
00580 
00581         m_mutex.Unlock();
00582 
00583 
00584         if( m_dwObjectCondition & THREAD_CREATION )
00585                 m_dwObjectCondition = m_dwObjectCondition ^ THREAD_CREATION;
00586 
00587 #ifdef WINDOWS
00588         if( m_thread ) CloseHandle(m_thread);
00589 
00590         m_thread = CreateThread(NULL,m_stackSize ,_THKERNEL,(LPVOID)this,0,&m_dwId);
00591         if( !m_thread )
00592         {
00593                 perror("thread creating failed");
00594                 m_dwObjectCondition |= THREAD_CREATION;
00595                 m_state = ThreadStateFault;
00596                 return FALSE;
00597         }
00598 #else
00599         pthread_attr_t attr;
00600         
00601         pthread_attr_init(&attr);
00602 
00603 #ifdef VMS
00604         if( m_stackSize == 0 )
00605                 pthread_attr_setstacksize(&attr,PTHREAD_STACK_MIN*10);
00606 #endif
00607         if( m_stackSize != 0 )
00608                 pthread_attr_setstacksize(&attr,m_stackSize);
00609 
00610         int error = pthread_create(&m_thread,&attr,_THKERNEL,(LPVOID)this);
00611 
00612         if( error != 0 )
00613         {
00614                 m_dwObjectCondition |= THREAD_CREATION;
00615                 m_state = ThreadStateFault;
00616 
00617 #if defined(HPUX) || defined(SUNOS) || defined(LINUX)
00618                   switch(error)
00619                   {
00620 
00621                   case EINVAL:
00622                           cerr << "error: attr in an invalid thread attributes object\n";
00623                           break;
00624                   case EAGAIN:
00625                           cerr << "error: the necessary resources to create a thread are not\n";
00626                           cerr << "available.\n";
00627                           break;
00628                   case EPERM:
00629                           cerr << "error: the caller does not have the privileges to create\n";
00630                           cerr << "the thread with the specified attr object.\n";
00631                           break;
00632 #if defined(HPUX)
00633                   case ENOSYS:
00634 
00635                           cerr << "error: pthread_create not implemented!\n";
00636                           if( __is_threadlib_linked()==0 )
00637                           {
00638                                   cerr << "error: threaded library not being used, improper linkage \"-lpthread -lc\"!\n";
00639                           }
00640                           break;
00641 #endif
00642                   default:
00643                           cerr << "error: an unknown error was encountered attempting to create\n";
00644                           cerr << "the requested thread.\n";
00645                           break;
00646                   }
00647 #else
00648                 cerr << "error: could not create thread, pthread_create failed (" << error << ")!\n";
00649 #endif
00650                  return FALSE;  
00651         }
00652 #endif
00653         return TRUE;
00654 }
00655 
00656 
00663 ThreadState_t 
00664 CThread::ThreadState()
00665 {
00666         ThreadState_t currentState;
00667         m_mutex.Lock();
00668                 currentState = m_state;
00669         m_mutex.Unlock();
00670         return currentState;
00671 }
00672 
00680 CThread::~CThread(void)
00681 {
00682 #ifdef WINDOWS
00683         if( m_bRunning )
00684         {
00685                 
00686           Stop(); 
00687           WaitForSingleObject(m_thread,INFINITE);
00688 
00689         }
00690         CloseHandle(m_thread);
00691 #else
00692         LPVOID lpv;
00693 
00694         if( m_bRunning )
00695         {
00696                 Stop();
00697                 pthread_join(m_thread,&lpv);
00698         }
00699 #endif
00700 
00701         delete [] m_lppvQue;
00702 }
00703 
00704 
00711 BOOL
00712 CThread::PingThread(DWORD dwTimeout 
00713                                  )
00714 {
00715     DWORD dwTotal = 0;
00716 
00717         while(TRUE)
00718         {
00719                 if( dwTotal > dwTimeout && dwTimeout > 0 )
00720                         return FALSE;
00721                 m_mutex.Lock();
00722                         if( m_bRunning )
00723                         {
00724                                 m_mutex.Unlock();
00725                                 return TRUE;
00726                         }
00727                 dwTotal += m_dwIdle;
00728                 m_mutex.Unlock();
00729                 Sleep(m_dwIdle);
00730         }
00731 
00732         return FALSE;
00733 }
00734 
00735 
00736 
00737 
 
blort
Author(s): Michael Zillich, 
  Thomas Mörwald, 
  Johann Prankl, 
  Andreas Richtsfeld,
  Bence Magyar (ROS version)
autogenerated on Thu Jan 2 2014 11:38:26