home *** CD-ROM | disk | FTP | other *** search
/ PC Format (South-Africa) 2001 May / PCFMay2001.iso / Xenon / C++ / FreeCommandLineTools.exe / Include / Rw / stdmutex.h < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-31  |  7.6 KB  |  267 lines

  1. #ifndef __STDMUTEX_H
  2. #define __STDMUTEX_H
  3. #pragma option push -b -a8 -pc -Vx- -Ve- -w-inl -w-aus -w-sig
  4. #ifndef __RWSTD_MUTEX_H__
  5. #define __RWSTD_MUTEX_H__
  6.  
  7. /*
  8.  * Declarations for class _RWSTDMutex and _RWSTDGuard.
  9.  *
  10.  * $Id: stdmutex.h,v 1.14 1996/08/28 01:30:38 smithey Exp $
  11.  *
  12.  ***************************************************************************
  13.  *
  14.  * Copyright (c) 1994-1999 Rogue Wave Software, Inc.  All Rights Reserved.
  15.  *
  16.  * This computer software is owned by Rogue Wave Software, Inc. and is
  17.  * protected by U.S. copyright laws and other laws and by international
  18.  * treaties.  This computer software is furnished by Rogue Wave Software,
  19.  * Inc. pursuant to a written license agreement and may be used, copied,
  20.  * transmitted, and stored only in accordance with the terms of such
  21.  * license and with the inclusion of the above copyright notice.  This
  22.  * computer software or any other copies thereof may not be provided or
  23.  * otherwise made available to any other person.
  24.  *
  25.  * U.S. Government Restricted Rights.  This computer software is provided
  26.  * with Restricted Rights.  Use, duplication, or disclosure by the
  27.  * Government is subject to restrictions as set forth in subparagraph (c)
  28.  * (1) (ii) of The Rights in Technical Data and Computer Software clause
  29.  * at DFARS 252.227-7013 or subparagraphs (c) (1) and (2) of the
  30.  * Commercial Computer Software รป Restricted Rights at 48 CFR 52.227-19,
  31.  * as applicable.  Manufacturer is Rogue Wave Software, Inc., 5500
  32.  * Flatiron Parkway, Boulder, Colorado 80301 USA.
  33.  *
  34.  ***************************************************************************
  35.  *
  36.  * This class is a portable implementation of a simple mutex lock
  37.  * to be used for synchronizing multiple threads within a single process.
  38.  * It is not suitable for use among threads of different processes.
  39.  * This code was taken from the tools mutex.h.
  40.  * 
  41.  ***************************************************************************/
  42.  
  43. #include <stdcomp.h>
  44.  
  45. #ifndef __RWSTDDEFS_H__
  46. #include <rw/stddefs.h> 
  47. #endif
  48.  
  49. #ifdef _RWSTD_MULTI_THREAD /* This class only relevant in MT situation */
  50.  
  51. #if defined(_RWSTD_SOLARIS_THREADS)  /* assuming Solaris 2.1 or greater */
  52. #  include <synch.h>
  53. #  include <thread.h>
  54.    typedef mutex_t _RWSTDMutexType;
  55.  
  56. #elif defined(_RWSTD_POSIX_D10_THREADS)
  57. #  include <pthread.h>
  58.    typedef pthread_mutex_t _RWSTDMutexType;
  59.  
  60. #elif defined(_RWSTD_DCE_THREADS)
  61. #  if defined(_RWSTD_NO_DCE_PTHREAD_H)
  62. #    include <pthread.h>
  63. #  else
  64. #    include <dce/pthread.h>
  65. #  endif
  66.    typedef pthread_mutex_t _RWSTDMutexType;
  67. #  define _RWSTD_NEEDS_SEM_INIT
  68.     
  69. #elif defined(__WIN32__)
  70. #  include <windows.h>
  71.    typedef CRITICAL_SECTION _RWSTDMutexType;
  72. #  define _RWSTD_NEEDS_SEM_INIT
  73.  
  74. #elif defined(__OS2__)
  75. #  include <exception>
  76. #  define INCL_DOSSEMAPHORES
  77. #  define _RWSTD_NEEDS_SEM_INIT
  78. #  include <os2.h>
  79.   typedef HMTX _RWSTDMutexType;
  80.   extern const char* __rw_mutex_exception;
  81.  
  82.   class _RWSTDExport thread_error : public exception
  83.   {
  84.     public:
  85.       thread_error () _RWSTD_THROW_SPEC_NULL : exception( )
  86.       { ; }
  87.       virtual const char * what () const  _RWSTD_THROW_SPEC_NULL
  88.       {
  89.         return __rw_mutex_exception;
  90.       }
  91.   };                            
  92.  
  93. #else
  94. #  error Class _RWSTDMutex is not yet supported in this environment
  95. #endif
  96.  
  97. class _RWSTDMutex
  98. {
  99.   private:
  100.  
  101.     _RWSTDMutexType mutex;
  102. #if defined(_RWSTD_NEEDS_SEM_INIT)
  103.     int initFlag;
  104. #endif
  105.  
  106.     void init ();
  107.     //
  108.     // Disallow assignment.
  109.     //
  110.     _RWSTDMutex& operator= (const _RWSTDMutex&);
  111.  
  112. public:
  113.  
  114.   enum StaticCtor { staticCtor };
  115.  
  116.   _RWSTDMutex ();             // Construct the mutex.
  117.   _RWSTDMutex (const _RWSTDMutex&); // Construct the mutex
  118.   _RWSTDMutex (StaticCtor);   // Some statics need special handling.
  119.   ~_RWSTDMutex ();            // Destroy the mutex.
  120.  
  121.   void acquire ();           // Acquire the mutex.
  122.   void release ();           // Release the mutex.
  123. };
  124.  
  125. class _RWSTDGuard
  126. {
  127.   private:
  128.  
  129.     _RWSTDMutex& rwmutex;
  130.  
  131.   public:
  132.  
  133.     _RWSTDGuard  (_RWSTDMutex& m);  // Acquire the mutex.
  134.     ~_RWSTDGuard ();               // Release the mutex.
  135. };
  136.  
  137. /*
  138. ** For those OSs that require a non-zero mutex, we must treat static 
  139. ** mutexes specially; they may not be initialized when we need them.
  140. ** For efficiency, we do conditional compilation in several methods
  141. ** based on that need.
  142. */
  143.  
  144. inline _RWSTDMutex::_RWSTDMutex (_RWSTDMutex::StaticCtor)
  145. {
  146.     //
  147.     // Empty, because acquire() may already have been used.
  148.     //
  149. }
  150.  
  151. inline _RWSTDMutex::~_RWSTDMutex () 
  152. #if defined(_RWSTD_NEEDS_SEM_INIT)
  153.     if (0 == initFlag)
  154.         return;
  155.     else
  156.         initFlag = 0;
  157. #endif
  158. #if defined(_RWSTD_SOLARIS_THREADS)
  159.     mutex_destroy(&mutex); 
  160. #elif defined(_RWSTD_POSIX_D10_THREADS) || defined(_RWSTD_DCE_THREADS)
  161.     pthread_mutex_destroy(&mutex); 
  162. #elif defined(__WIN32__)
  163.     DeleteCriticalSection(&mutex);
  164. #elif defined(__OS2__)
  165.     APIRET rv;
  166.     _RWSTD_THROW_NO_MSG(0 != (rv = DosCloseMutexSem(mutex)),
  167.                 thread_error);
  168. #endif
  169. }
  170. void inline _RWSTDMutex::init ()
  171. #if defined(_RWSTD_SOLARIS_THREADS)
  172.     mutex_init(&mutex, USYNC_THREAD, NULL); 
  173. #elif defined(_RWSTD_POSIX_D10_THREADS)
  174.     pthread_mutex_init(&mutex, 0);
  175. #elif defined(_RWSTD_DCE_THREADS)
  176.     pthread_mutex_init(&mutex, pthread_mutexattr_default);
  177. #elif defined(__WIN32__)
  178.     InitializeCriticalSection(&mutex);
  179. #elif defined(__OS2__)
  180.     APIRET rv;
  181.     _RWSTD_THROW_NO_MSG(0 != (rv = DosCreateMutexSem(0,&mutex,DC_SEM_SHARED,FALSE)),
  182.                 thread_error);
  183. #endif
  184. #if defined(_RWSTD_NEEDS_SEM_INIT)
  185.     initFlag = 1;
  186. #endif
  187. }  
  188.  
  189. inline _RWSTDMutex::_RWSTDMutex () 
  190.   init(); 
  191. }  // Initialize the mutex.   
  192.  
  193. inline _RWSTDMutex::_RWSTDMutex (const _RWSTDMutex&)
  194.   init(); 
  195. }  // Initialize the mutex.   
  196.  
  197. inline void _RWSTDMutex::acquire ()
  198. #if defined(_RWSTD_NEEDS_SEM_INIT)
  199.     if(0 == initFlag)
  200.         init();
  201. #endif
  202. #if defined(_RWSTD_SOLARIS_THREADS)
  203.     mutex_lock(&mutex);    
  204. #elif defined(_RWSTD_POSIX_THREADS) || defined(_RWSTD_DCE_THREADS)
  205.     pthread_mutex_lock(&mutex);    
  206. #elif defined(__WIN32__)
  207.     EnterCriticalSection(&mutex);
  208. #elif defined(__OS2__)
  209.     APIRET rv;
  210.     _RWSTD_THROW_NO_MSG(0 != (rv = DosRequestMutexSem(mutex, SEM_INDEFINITE_WAIT)),
  211.                thread_error); 
  212. #endif
  213. }
  214.  
  215. inline void _RWSTDMutex::release ()
  216. #if defined(_RWSTD_SOLARIS_THREADS)
  217.     mutex_unlock(&mutex);  
  218. #elif defined(_RWSTD_POSIX_D10_THREADS) || defined(_RWSTD_DCE_THREADS)
  219.     pthread_mutex_unlock(&mutex);  
  220. #elif defined(__WIN32__)
  221.     LeaveCriticalSection(&mutex);
  222. #elif defined(__OS2__)
  223.     APIRET rv;
  224.     _RWSTD_THROW_NO_MSG(0 != (rv = DosReleaseMutexSem(mutex)),
  225.                 thread_error);
  226. #endif
  227. }
  228.  
  229. inline _RWSTDGuard::_RWSTDGuard (_RWSTDMutex& m) : rwmutex(m)
  230. {
  231.     rwmutex.acquire();
  232. }
  233.  
  234. inline _RWSTDGuard::~_RWSTDGuard () { rwmutex.release(); }
  235.  
  236. #define STDGUARD(a) _RWSTDGuard(a)
  237. #else
  238. #define STDGUARD(a) 
  239. #endif  /*_RWSTD_MULTI_THREAD*/
  240.  
  241. #if defined(_RWSTD_MULTI_THREAD) && !defined(_RWSTD_NO_TEST_AND_SET)
  242. #ifdef __WIN32__
  243. #define _RWSTD_MT_INCREMENT(v) InterlockedIncrement(&v)
  244. #define _RWSTD_MT_DECREMENT(v) InterlockedDecrement(&v)
  245. #define _RWSTD_MT_SET(v,new) InterlockedExchange(&v,new)
  246. #else
  247. #define _RWSTD_MT_INCREMENT(v) v++
  248. #define _RWSTD_MT_DECREMENT(v) v--
  249. #define _RWSTD_MT_SET(v,new) v = new
  250. #endif // __WIN32__
  251. #else
  252. #define _RWSTD_MT_INCREMENT(v) v++
  253. #define _RWSTD_MT_DECREMENT(v) v--
  254. #define _RWSTD_MT_SET(v,new) v = new
  255. #endif // _RWSTD_MULTI_THREAD
  256.  
  257. #endif  /*__RWSTD_MUTEX_H__*/
  258.  
  259. #pragma option pop
  260. #endif /* __STDMUTEX_H */
  261.