00001 /* 00002 * 00003 * Copyright (C) 1997-2010, OFFIS e.V. 00004 * All rights reserved. See COPYRIGHT file for details. 00005 * 00006 * This software and supporting documentation were developed by 00007 * 00008 * OFFIS e.V. 00009 * R&D Division Health 00010 * Escherweg 2 00011 * D-26121 Oldenburg, Germany 00012 * 00013 * 00014 * Module: ofstd 00015 * 00016 * Author: Marco Eichelberg 00017 * 00018 * Purpose: Provides operating system independent abstractions for basic 00019 * multi-thread concepts: threads, thread specific data, 00020 * semaphores, mutexes and read/write locks. The implementation 00021 * of these classes supports the Solaris, POSIX and Win32 00022 * multi-thread APIs. 00023 * 00024 * Last Update: $Author: joergr $ 00025 * Update Date: $Date: 2010-10-14 13:15:50 $ 00026 * CVS/RCS Revision: $Revision: 1.11 $ 00027 * Status: $State: Exp $ 00028 * 00029 * CVS/RCS Log at end of file 00030 * 00031 */ 00032 00033 00034 #ifndef OFTHREAD_H 00035 #define OFTHREAD_H 00036 00037 #include "dcmtk/config/osconfig.h" 00038 #include "dcmtk/ofstd/oftypes.h" /* for class OFBool */ 00039 #include "dcmtk/ofstd/ofstring.h" /* for class OFString */ 00040 00045 extern "C" 00046 { 00047 #ifdef HAVE_WINDOWS_H 00048 unsigned int __stdcall thread_stub(void *arg); 00049 #else 00050 void *thread_stub(void *arg); 00051 #endif 00052 } 00053 00054 00062 class OFThread 00063 { 00064 public: 00065 00070 OFThread(); 00071 00079 virtual ~OFThread(); 00080 00096 int start(); 00097 00107 int join(); 00108 00117 unsigned long threadID(); 00118 00124 OFBool equal(unsigned long tID); 00125 00131 static void errorstr(OFString& description, int code); 00132 00139 static const int busy; 00140 00141 protected: 00142 00146 static void thread_exit(); 00147 00157 static unsigned long self(); 00158 00159 private: 00160 00168 virtual void run() = 0; 00169 00170 #ifdef HAVE_WINDOWS_H 00171 00172 unsigned long theThreadHandle; 00173 #endif 00174 00176 #ifdef HAVE_POINTER_TYPE_PTHREAD_T 00177 void *theThread; 00178 #else 00179 unsigned long theThread; 00180 #endif 00181 00183 OFThread(const OFThread& arg); 00184 00186 OFThread& operator=(const OFThread& arg); 00187 00189 #ifdef HAVE_WINDOWS_H 00190 friend unsigned int __stdcall thread_stub(void *arg); 00191 #else 00192 friend void *thread_stub(void *arg); 00193 #endif 00194 }; 00195 00196 00206 class OFThreadSpecificData 00207 { 00208 public: 00209 00211 OFThreadSpecificData(); 00212 00216 ~OFThreadSpecificData(); 00217 00221 OFBool initialized() const; 00222 00229 int set(void *value); 00230 00237 int get(void *&value); 00238 00244 static void errorstr(OFString& description, int code); 00245 00246 private: 00247 00249 #ifdef HAVE_CXX_VOLATILE 00250 volatile 00251 #endif 00252 void *theKey; 00253 00255 OFThreadSpecificData(const OFThreadSpecificData& arg); 00256 00258 OFThreadSpecificData& operator=(const OFThreadSpecificData& arg); 00259 }; 00260 00261 00270 class OFSemaphore 00271 { 00272 public: 00273 00277 OFSemaphore(unsigned int numResources); 00278 00280 ~OFSemaphore(); 00281 00285 OFBool initialized() const; 00286 00291 int wait(); 00292 00298 int trywait(); 00299 00304 int post(); 00305 00311 static void errorstr(OFString& description, int code); 00312 00318 static const int busy; 00319 00320 private: 00322 #ifdef HAVE_CXX_VOLATILE 00323 volatile 00324 #endif 00325 void * theSemaphore; 00326 00328 OFSemaphore(const OFSemaphore& arg); 00329 00331 OFSemaphore& operator=(const OFSemaphore& arg); 00332 }; 00333 00334 00343 class OFMutex 00344 { 00345 public: 00346 00348 OFMutex(); 00349 00351 ~OFMutex(); 00352 00356 OFBool initialized() const; 00357 00364 int lock(); 00365 00371 int trylock(); 00372 00380 int unlock(); 00381 00387 static void errorstr(OFString& description, int code); 00388 00394 static const int busy; 00395 00396 private: 00398 #ifdef HAVE_CXX_VOLATILE 00399 volatile 00400 #endif 00401 void * theMutex; 00402 00404 OFMutex(const OFMutex& arg); 00405 00407 OFMutex& operator=(const OFMutex& arg); 00408 }; 00409 00410 00418 class OFReadWriteLock 00419 { 00420 public: 00421 00423 OFReadWriteLock(); 00424 00426 ~OFReadWriteLock(); 00427 00431 OFBool initialized() const; 00432 00439 int rdlock(); 00440 00447 int wrlock(); 00448 00454 int tryrdlock(); 00455 00461 int trywrlock(); 00462 00470 int unlock(); 00471 00477 static void errorstr(OFString& description, int code); 00478 00484 static const int busy; 00485 00486 private: 00488 #ifdef HAVE_CXX_VOLATILE 00489 volatile 00490 #endif 00491 void * theLock; 00492 00494 OFReadWriteLock(const OFReadWriteLock& arg); 00495 00497 OFReadWriteLock& operator=(const OFReadWriteLock& arg); 00498 }; 00499 00505 class OFReadWriteLocker { 00506 public: 00510 OFReadWriteLocker(OFReadWriteLock& lock); 00511 00513 ~OFReadWriteLocker(); 00514 00519 int rdlock(); 00520 00525 int wrlock(); 00526 00532 int tryrdlock(); 00533 00539 int trywrlock(); 00540 00545 int unlock(); 00546 00547 private: 00549 OFReadWriteLock& theLock; 00550 00552 OFBool locked; 00553 00555 OFReadWriteLocker(const OFReadWriteLocker& arg); 00556 00558 OFReadWriteLocker& operator=(const OFReadWriteLocker& arg); 00559 }; 00560 00561 #endif 00562 00563 /* 00564 * 00565 * CVS/RCS Log: 00566 * $Log: ofthread.h,v $ 00567 * Revision 1.11 2010-10-14 13:15:50 joergr 00568 * Updated copyright header. Added reference to COPYRIGHT file. 00569 * 00570 * Revision 1.10 2010-06-04 13:58:42 uli 00571 * Added class OFReadWriteLocker which simplifies unlocking OFReadWriteLocks. 00572 * 00573 * Revision 1.9 2005-12-08 16:06:08 meichel 00574 * Changed include path schema for all DCMTK header files 00575 * 00576 * Revision 1.8 2004/08/03 16:44:16 meichel 00577 * Updated code to correctly handle pthread_t both as an integral integer type 00578 * (e.g. Linux, Solaris) and as a pointer type (e.g. BSD, OSF/1). 00579 * 00580 * Revision 1.7 2003/12/05 10:37:41 joergr 00581 * Removed leading underscore characters from preprocessor symbols (reserved 00582 * symbols). Updated copyright date where appropriate. 00583 * 00584 * Revision 1.6 2003/07/04 13:29:51 meichel 00585 * Replaced forward declarations for OFString with explicit includes, 00586 * needed when compiling with HAVE_STD_STRING 00587 * 00588 * Revision 1.5 2003/06/06 10:31:04 meichel 00589 * Added volatile keyword to data pointers in multi-thread wrapper classes 00590 * 00591 * Revision 1.4 2002/02/27 14:13:19 meichel 00592 * Changed initialized() methods to const. Fixed some return values when 00593 * compiled without thread support. 00594 * 00595 * Revision 1.3 2001/06/01 15:51:36 meichel 00596 * Updated copyright header 00597 * 00598 * Revision 1.2 2000/06/26 09:27:26 joergr 00599 * Replaced _WIN32 by HAVE_WINDOWS_H to avoid compiler errors using CygWin-32. 00600 * 00601 * Revision 1.1 2000/03/29 16:41:23 meichel 00602 * Added new classes providing an operating system independent abstraction 00603 * for threads, thread specific data, semaphores, mutexes and read/write locks. 00604 * 00605 * 00606 */