00001 /* 00002 * 00003 * Copyright (C) 1997-2011, 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: onken $ 00025 * Update Date: $Date: 2011-01-04 14:47:09 $ 00026 * CVS/RCS Revision: $Revision: 1.12 $ 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 00262 /* Mac OS X only permits named Semaphores. The code below compiles on Mac OS X 00263 but does not work. This will be corrected in the next snapshot. For now, the 00264 semaphore code is completely disabled for that OS (it is not used in other 00265 parts of the toolkit so far. 00266 */ 00267 #ifndef _DARWIN_C_SOURCE 00268 00277 class OFSemaphore 00278 { 00279 public: 00280 00284 OFSemaphore(unsigned int numResources); 00285 00287 ~OFSemaphore(); 00288 00292 OFBool initialized() const; 00293 00298 int wait(); 00299 00305 int trywait(); 00306 00311 int post(); 00312 00318 static void errorstr(OFString& description, int code); 00319 00325 static const int busy; 00326 00327 private: 00329 #ifdef HAVE_CXX_VOLATILE 00330 volatile 00331 #endif 00332 void * theSemaphore; 00333 00335 OFSemaphore(const OFSemaphore& arg); 00336 00338 OFSemaphore& operator=(const OFSemaphore& arg); 00339 }; 00340 00341 00342 #endif // _DARWIN_C_SOURCE 00343 00352 class OFMutex 00353 { 00354 public: 00355 00357 OFMutex(); 00358 00360 ~OFMutex(); 00361 00365 OFBool initialized() const; 00366 00373 int lock(); 00374 00380 int trylock(); 00381 00389 int unlock(); 00390 00396 static void errorstr(OFString& description, int code); 00397 00403 static const int busy; 00404 00405 private: 00407 #ifdef HAVE_CXX_VOLATILE 00408 volatile 00409 #endif 00410 void * theMutex; 00411 00413 OFMutex(const OFMutex& arg); 00414 00416 OFMutex& operator=(const OFMutex& arg); 00417 }; 00418 00419 00427 class OFReadWriteLock 00428 { 00429 public: 00430 00432 OFReadWriteLock(); 00433 00435 ~OFReadWriteLock(); 00436 00440 OFBool initialized() const; 00441 00448 int rdlock(); 00449 00456 int wrlock(); 00457 00463 int tryrdlock(); 00464 00470 int trywrlock(); 00471 00479 int unlock(); 00480 00486 static void errorstr(OFString& description, int code); 00487 00493 static const int busy; 00494 00495 private: 00497 #ifdef HAVE_CXX_VOLATILE 00498 volatile 00499 #endif 00500 void * theLock; 00501 00503 OFReadWriteLock(const OFReadWriteLock& arg); 00504 00506 OFReadWriteLock& operator=(const OFReadWriteLock& arg); 00507 }; 00508 00514 class OFReadWriteLocker { 00515 public: 00519 OFReadWriteLocker(OFReadWriteLock& lock); 00520 00522 ~OFReadWriteLocker(); 00523 00528 int rdlock(); 00529 00534 int wrlock(); 00535 00541 int tryrdlock(); 00542 00548 int trywrlock(); 00549 00554 int unlock(); 00555 00556 private: 00558 OFReadWriteLock& theLock; 00559 00561 OFBool locked; 00562 00564 OFReadWriteLocker(const OFReadWriteLocker& arg); 00565 00567 OFReadWriteLocker& operator=(const OFReadWriteLocker& arg); 00568 }; 00569 00570 #endif 00571 00572 /* 00573 * 00574 * CVS/RCS Log: 00575 * $Log: ofthread.h,v $ 00576 * Revision 1.12 2011-01-04 14:47:09 onken 00577 * Disable and hide OFSemaphore class on Mac OS X since implementation is 00578 * broken on that OS (needs named semaphores instead). 00579 * 00580 * Revision 1.11 2010-10-14 13:15:50 joergr 00581 * Updated copyright header. Added reference to COPYRIGHT file. 00582 * 00583 * Revision 1.10 2010-06-04 13:58:42 uli 00584 * Added class OFReadWriteLocker which simplifies unlocking OFReadWriteLocks. 00585 * 00586 * Revision 1.9 2005-12-08 16:06:08 meichel 00587 * Changed include path schema for all DCMTK header files 00588 * 00589 * Revision 1.8 2004/08/03 16:44:16 meichel 00590 * Updated code to correctly handle pthread_t both as an integral integer type 00591 * (e.g. Linux, Solaris) and as a pointer type (e.g. BSD, OSF/1). 00592 * 00593 * Revision 1.7 2003/12/05 10:37:41 joergr 00594 * Removed leading underscore characters from preprocessor symbols (reserved 00595 * symbols). Updated copyright date where appropriate. 00596 * 00597 * Revision 1.6 2003/07/04 13:29:51 meichel 00598 * Replaced forward declarations for OFString with explicit includes, 00599 * needed when compiling with HAVE_STD_STRING 00600 * 00601 * Revision 1.5 2003/06/06 10:31:04 meichel 00602 * Added volatile keyword to data pointers in multi-thread wrapper classes 00603 * 00604 * Revision 1.4 2002/02/27 14:13:19 meichel 00605 * Changed initialized() methods to const. Fixed some return values when 00606 * compiled without thread support. 00607 * 00608 * Revision 1.3 2001/06/01 15:51:36 meichel 00609 * Updated copyright header 00610 * 00611 * Revision 1.2 2000/06/26 09:27:26 joergr 00612 * Replaced _WIN32 by HAVE_WINDOWS_H to avoid compiler errors using CygWin-32. 00613 * 00614 * Revision 1.1 2000/03/29 16:41:23 meichel 00615 * Added new classes providing an operating system independent abstraction 00616 * for threads, thread specific data, semaphores, mutexes and read/write locks. 00617 * 00618 * 00619 */