00001
00032 #include "vetDefs.h"
00033
00034 #ifndef __VETLIB_VETTHREAD_H__
00035 #define __VETLIB_VETTHREAD_H__
00036
00037 #pragma warning(disable:4065) // warning C4065 @ line 653: switch statement contains 'default' but no 'case' labels
00038
00039 #define VETTHREAD_ARRAYSIZE 24
00040
00041 #define VETTHREAD_DONE 0
00042 #define VETTHREAD_HALT1 3
00043 #define VETTHREAD_HALT2 6
00044
00045
00046 #define VETTHREAD_TIMEOUT 5000L // 5 seconds
00047 #define VETTHREAD_INFINITE INFINITE // windows definition
00048
00049
00050 #define VETRET_THREAD_WAIT_TIMEOUT 15011 //timed out
00051 #define VETRET_THREAD_ABANDONED 15012 //object abandoned (check msdn)
00052
00053 #define VETTHREAD_DEFAULT 0200L
00054
00055 #define VETTHREAD_INITIALIZED 15030
00056 #define VETTHREAD_UNINITIALIZED 15031
00057
00058
00059
00060
00061
00062
00063
00064
00065 #if defined(sun) || defined(__sun) || defined(linux) || defined(__linux) \
00066 || defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__OPENBSD__) || defined(__MACOSX__) \
00067 || defined(__APPLE__) || defined(sgi) || defined(__sgi)
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 #include <stdlib.h>
00089 #include <unistd.h>
00090 #include <pthread.h>
00091
00092 #include <signal.h>
00093
00094
00095
00096 class vetThread
00097 {
00098
00099
00100 protected:
00101
00102 pthread_t* osThread;
00103
00104 pthread_attr_t* osThreadAttr;
00105
00106 bool secureMode;
00107
00108 int status;
00109
00110 void exit() { pthread_exit(NULL); }
00111
00112
00113 public:
00114
00115 vetThread()
00116 {
00117 INFO("vetThread::vetThread() [CONSTRUCTOR]")
00118
00119 secureMode = true;
00120
00121
00122 osThreadAttr = NULL;
00123
00124 status = VETTHREAD_UNINITIALIZED;
00125 }
00126
00127
00128 vetThread( void* (*functionCall)(void*), void* ArgumentStructure = NULL)
00129 {
00130 DEBUGMSG("vetThread::vetThread(..) [CONSTRUCTOR]", functionCall)
00131
00132 secureMode = true;
00133 status = VETTHREAD_UNINITIALIZED;
00134
00135
00136 osThreadAttr = NULL;
00137
00138 if ( !pthread_create(osThread, osThreadAttr, functionCall, ArgumentStructure) )
00139 status = VETTHREAD_INITIALIZED;
00140
00141 }
00142
00143
00144
00145 ~vetThread()
00146 {
00147 INFO("vetThread::~vetThread() [DECONSTRUCTOR]")
00148
00149 if ( status == VETTHREAD_UNINITIALIZED )
00150 return;
00151
00152 if (secureMode);
00153 {
00154 if ( waitProcessEnd(true) == VETRET_OK)
00155 delete osThread;
00156 }
00157
00158
00159 }
00160
00161
00162
00163 inline pthread_t* dump_PTHREAD() { return osThread; };
00164
00165
00166 VETRESULT run( void* (*functionCall)(void*), void* ArgumentStructure = NULL)
00167 {
00168 DEBUGMSG("int vetThread::run(..)", functionCall)
00169
00170 int ret;
00171 ret = pthread_create(osThread, osThreadAttr, functionCall, ArgumentStructure);
00172
00173 if ( ret == 0 )
00174 status = VETTHREAD_INITIALIZED;
00175
00176 return ret;
00177 }
00178
00179
00180
00181 VETRESULT pause()
00182 {
00183 INFO("int vetThread::pause()")
00184
00185 INFO("int vetThread::pause() is NOT AVAILABLE!")
00186
00187 return VETRET_INTERNAL_ERR;
00188 }
00189
00190 VETRESULT resume()
00191 {
00192 INFO("int vetThread::resume()")
00193
00194 INFO("int vetThread::resume() is NOT AVAILABLE!")
00195
00196 return VETRET_INTERNAL_ERR;
00197 }
00198
00199 VETRESULT terminate(bool cancel = false)
00200 {
00201 DEBUGMSG("int vetThread::terminate(bool cancel)", cancel)
00202
00203 if ( status == VETTHREAD_UNINITIALIZED )
00204 return VETRET_ILLEGAL_USE;
00205
00206 pthread_exit(osThread);
00207
00208 if (cancel)
00209 pthread_cancel(*osThread);
00210
00211 return VETRET_OK;
00212 }
00213
00214 VETRESULT waitProcessEnd(bool closeThread = false)
00215 {
00216 DEBUGMSG("int vetThread::waitProcessEnd(bool closeThread)", closeThread)
00217
00218 if (status == VETTHREAD_UNINITIALIZED)
00219 return VETRET_ILLEGAL_USE;
00220
00221 if ( !pthread_join(*osThread, NULL) )
00222 return VETRET_INTERNAL_ERR;
00223
00224 if ( closeThread )
00225 {
00226 int status;
00227 pthread_exit(&status);
00228 return status;
00229 }
00230 else
00231 return VETRET_OK;
00232
00233 }
00234
00235
00236
00237 void sleep(int millisec)
00238 {
00239 usleep(millisec);
00240 }
00241
00242
00243
00244 int getPriority()
00245 {
00246 sched_param param;
00247 int policy;
00248
00249 pthread_getschedparam(*osThread, &policy, ¶m);
00250 return param.sched_priority;
00251 }
00252
00253 VETRESULT setPriority(int priority)
00254 {
00255 sched_param param;
00256 param.sched_priority = priority;
00257 return pthread_setschedparam(*osThread, SCHED_OTHER, ¶m);
00258 }
00259
00260
00261 bool isSameAs(vetThread* dst)
00262 {
00263 if ( pthread_equal(*osThread, *dst->dump_PTHREAD()) )
00264 return true;
00265 return false;
00266 }
00267
00268
00269
00270 void setSecureMode(bool val = true)
00271 {
00272 secureMode = val;
00273 }
00274
00275 bool getSecureMode() { return secureMode; };
00276
00277
00278
00279
00281
00282
00283 VETRESULT sendSignal(int signal = 0)
00284 {
00285 DEBUGMSG("int vetThread::sendSignal(int signal)", signal);
00286
00287 return pthread_kill(*osThread, signal);
00288 }
00289
00291
00292
00293
00294 };
00295
00296
00297
00298 static pthread_mutex_t myCounterMutex = PTHREAD_MUTEX_INITIALIZER;
00299
00300
00301 static long globalThreadCount = 0;
00302
00303
00304 class vetThreadManager
00305 {
00306
00307 protected:
00308
00309 vetThread** myThreads;
00310 int* threadsID;
00311
00312 int threadCount;
00313
00314 bool secureMode;
00315
00316
00317
00318 public:
00319
00320 vetThreadManager()
00321 {
00322 myThreads = new vetThread*[VETTHREAD_ARRAYSIZE];
00323 for (int i = 0; i < VETTHREAD_ARRAYSIZE; i++)
00324 myThreads[i] = NULL;
00325
00326 secureMode = true;
00327 threadCount = 0;
00328 }
00329
00330
00331 ~vetThreadManager()
00332 {
00333 if ( secureMode )
00334 {
00335 waitThreadCompletition();
00336 delete [] myThreads;
00337 return;
00338 }
00339 delete myThreads;
00340 }
00341
00342 vetThread* newThread(void * (* functionCall)(void *), void* ArgumentStructure = NULL)
00343 {
00344 if ( threadCount >= VETTHREAD_ARRAYSIZE )
00345 return NULL;
00346
00347 myThreads[threadCount] = new vetThread(functionCall, ArgumentStructure);
00348
00349 pthread_mutex_lock( &myCounterMutex);
00350 ++globalThreadCount;
00351 ++threadCount;
00352 pthread_mutex_unlock( &myCounterMutex);
00353
00354 return myThreads[threadCount];
00355 }
00356
00357
00358
00359
00360 VETRESULT waitThreadCompletition(int threadID = -1)
00361 {
00362 if (threadID == -1)
00363 {
00364 for (int i = 0; i < VETTHREAD_ARRAYSIZE; i++)
00365 if (myThreads[i] != NULL)
00366 pthread_join( *myThreads[i]->dump_PTHREAD(), NULL);
00367 return VETRET_OK;
00368 }
00369
00370 if ( threadID < 0 || threadID >= threadCount )
00371 return VETRET_PARAM_ERR;
00372
00373 pthread_join( *myThreads[threadID]->dump_PTHREAD(), NULL);
00374 return VETRET_OK;
00375 }
00376
00377
00378 int getCurrentThreadCount() { return threadCount; };
00379
00380 long getGlobalThreadCount() { return globalThreadCount; };
00381
00382 vetThread* getThread(int index)
00383 {
00384 if ( index < 0 || index >= threadCount )
00385 return NULL;
00386
00387 return myThreads[index];
00388 }
00389
00390
00391 };
00392
00393
00394
00395
00396 #elif defined(_WIN32) || defined(__WIN32__)
00400
00401
00402
00403 #include <windows.h>
00404 #include <process.h>
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 class vetThread
00428 {
00429
00430
00431 protected:
00432
00433 HANDLE myThread;
00434 DWORD wdID;
00435 DWORD flags;
00436
00437 int priority;
00438 int status;
00439 bool secureMode;
00440
00441 public:
00442
00443 vetThread()
00444 {
00445 INFO("vetThread::vetThread() [CONSTRUCTOR]")
00446
00447 secureMode = true;
00448 myThread = NULL;
00449 flags = CREATE_DEFAULT_ERROR_MODE;
00450 wdID = -1;
00451 status = VETTHREAD_UNINITIALIZED;
00452 };
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 ~vetThread()
00474 {
00475 INFO("vetThread::~vetThread() [DECONSTRUCTOR]")
00476
00477 if (secureMode)
00478 {
00479 if ( waitProcessEnd(VETTHREAD_TIMEOUT, true) != VETRET_OK )
00480 terminate();
00481 }
00482 };
00483
00484
00485
00486 HANDLE dump_HANDLE() { return myThread; };
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507 VETRESULT pause()
00508 {
00509 INFO("int vetThread::pause()")
00510
00511 if ( myThread== NULL )
00512 return VETRET_ILLEGAL_USE;
00513
00514 if ( SuspendThread(myThread) != (DWORD)-1 )
00515 return VETRET_OK;
00516 else
00517 return VETRET_INTERNAL_ERR;
00518 };
00519
00520 VETRESULT resume()
00521 {
00522 INFO("int vetThread::resume()")
00523
00524 if ( myThread== NULL )
00525 return VETRET_ILLEGAL_USE;
00526
00527 if ( ResumeThread(myThread) != (DWORD)-1 )
00528 return VETRET_OK;
00529 else
00530 return VETRET_INTERNAL_ERR;
00531 };
00532
00533
00534 VETRESULT terminate(bool closeThread = false)
00535 {
00536 DEBUGMSG("int vetThread::terminate(bool closeThread)", closeThread)
00537
00538 if ( myThread == NULL )
00539 return VETRET_ILLEGAL_USE;
00540
00541 if ( myThread!= NULL )
00542 {
00543 DWORD exitcode = 0;
00544
00545 if ( GetExitCodeThread(myThread, &exitcode) )
00546 if ( TerminateThread(myThread, exitcode) )
00547 return VETRET_OK;
00548
00549 return VETRET_INTERNAL_ERR;
00550 }
00551
00552 if (closeThread)
00553 if ( CloseHandle(myThread) )
00554 {
00555
00556 myThread = NULL;
00557 return VETRET_OK;
00558 }
00559
00560
00561 return VETRET_ILLEGAL_USE;
00562 };
00563
00564 VETRESULT waitProcessEnd(DWORD millisec = VETTHREAD_TIMEOUT, bool closeThread = false)
00565 {
00566 DEBUGMSG("int vetThread::waitProcessEnd(..,bool closeThread)", closeThread)
00567
00568 if ( myThread == NULL )
00569 return VETRET_ILLEGAL_USE;
00570
00571 DWORD res = WaitForSingleObject(myThread, VETTHREAD_TIMEOUT);
00572
00573 if ( res == WAIT_OBJECT_0 )
00574 if ( closeThread )
00575 {
00576 DWORD exitcode = 0;
00577
00578 if ( GetExitCodeThread(myThread, &exitcode) )
00579 ExitThread(exitcode);
00580 else
00581 return VETRET_INTERNAL_ERR;
00582
00583 return VETRET_OK;
00584 }
00585 else
00586 return VETRET_OK;
00587
00588 else if ( res == WAIT_TIMEOUT )
00589 return VETRET_THREAD_WAIT_TIMEOUT;
00590
00591 else if ( res == WAIT_ABANDONED )
00592 return VETRET_THREAD_ABANDONED;
00593
00594 return VETRET_INTERNAL_ERR;
00595 };
00596
00597
00598
00599 int getPriority()
00600 {
00601 if ( myThread== NULL )
00602 return VETRET_ILLEGAL_USE;
00603
00604 return GetThreadPriority(myThread);
00605 };
00606
00607 VETRESULT setPriority(int priority)
00608 {
00609 if ( myThread== NULL )
00610 return VETRET_ILLEGAL_USE;
00611
00612 if ( SetThreadPriority(myThread, priority) )
00613 return VETRET_OK;
00614
00615 return VETRET_INTERNAL_ERR;
00616 };
00617
00618 void sleep(int millisec)
00619 {
00620 Sleep(millisec);
00621 };
00622
00623 bool isSameAs(vetThread* dst)
00624 {
00625 if ( myThread != NULL && myThread == dst->dump_HANDLE() )
00626 return true;
00627 return false;
00628 };
00629
00630
00631
00632 void setSecureMode(bool val = true)
00633 {
00634 secureMode = val;
00635 };
00636
00637 bool getSecureMode() { return secureMode; };
00638
00639 DWORD getID() { return wdID; };
00640
00641 DWORD getFlags() { return flags; }
00642
00643 VETRESULT setFlags(int vetThreadFlags = VETTHREAD_DEFAULT)
00644 {
00645 if ( myThread != NULL )
00646 return VETRET_ILLEGAL_USE;
00647
00648 switch (vetThreadFlags)
00649 {
00650 default:
00651 flags = CREATE_DEFAULT_ERROR_MODE;
00652 break;
00653 }
00654 return VETRET_OK;
00655 };
00656
00657
00658
00660
00661
00662
00664
00665
00666 };
00667
00668
00669
00670 static HANDLE hThrd;
00671 static HANDLE hMutexCounter;
00672 static long globalThreadCount = -1;
00673
00674
00675 class vetThreadManager
00676 {
00677
00678 protected:
00679
00680 vetThread** myThreads;
00681 int* threadsID;
00682
00683 int threadCount;
00684
00685 bool secureMode;
00686
00687
00688
00689 public:
00690
00691 vetThreadManager()
00692 {
00693 myThreads = new vetThread*[VETTHREAD_ARRAYSIZE];
00694 for (int i = 0; i < VETTHREAD_ARRAYSIZE; i++)
00695 myThreads[i] = NULL;
00696
00697 hMutexCounter = NULL;
00698 hMutexCounter = CreateMutex(NULL, 0, NULL);
00699
00700 secureMode = true;
00701 threadCount = 0;
00702 }
00703
00704
00705 ~vetThreadManager()
00706 {
00707 ReleaseMutex(hMutexCounter);
00708
00709 if ( secureMode )
00710 {
00711 waitThreadCompletition();
00712 delete [] myThreads;
00713 return;
00714 }
00715 delete myThreads;
00716 }
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736 VETRESULT waitThreadCompletition(int threadID = -1)
00737 {
00738 DWORD retVal = 0;
00739
00740 if (threadID == -1)
00741 {
00742 for (int i = 0; i < VETTHREAD_ARRAYSIZE; i++)
00743 if (myThreads[i] != NULL)
00744 retVal += WaitForSingleObject(myThreads[i]->dump_HANDLE(), VETTHREAD_TIMEOUT);
00745
00746 return VETRET_OK;
00747 }
00748
00749 if ( threadID < 0 || threadID >= threadCount )
00750 return VETRET_PARAM_ERR;
00751
00752 retVal = WaitForSingleObject(myThreads[threadID]->dump_HANDLE(), VETTHREAD_TIMEOUT);
00753 return VETRET_OK;
00754 }
00755
00756
00757 int getCurrentThreadCount() { return threadCount; };
00758
00759 static long getGlobalThreadCount() { return globalThreadCount; };
00760
00761 vetThread* getThread(int index)
00762 {
00763 if ( index < 0 || index >= threadCount )
00764 return NULL;
00765
00766 return myThreads[index];
00767 }
00768
00769
00770
00771 static int getPriority(vetThread* thr)
00772 {
00773 if ( thr == NULL )
00774 return VETRET_ILLEGAL_USE;
00775
00776 return GetThreadPriority(thr->dump_HANDLE());
00777 }
00778
00779 static VETRESULT setPriority(vetThread* thr, int priority)
00780 {
00781 if ( thr== NULL )
00782 return VETRET_ILLEGAL_USE;
00783
00784 if ( SetThreadPriority(thr->dump_HANDLE(), priority) )
00785 return VETRET_OK;
00786
00787 return VETRET_INTERNAL_ERR;
00788 }
00789
00790
00791
00792 };
00793
00794
00795
00796
00797 #else
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810 #endif
00813
00814
00815
00816
00817
00818
00819 #endif //__VETLIB_VETTHREAD_H__
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909
00910