1    	// @(#)root/base:$Id$
2    	// Author: Fons Rademakers   14/07/2002
3    	
4    	/*************************************************************************
5    	 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
6    	 * All rights reserved.                                                  *
7    	 *                                                                       *
8    	 * For the licensing terms see $ROOTSYS/LICENSE.                         *
9    	 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
10   	 *************************************************************************/
11   	
12   	#ifndef ROOT_TVirtualMutex
13   	#define ROOT_TVirtualMutex
14   	
15   	
16   	//////////////////////////////////////////////////////////////////////////
17   	//                                                                      //
18   	// TVirtualMutex                                                        //
19   	//                                                                      //
20   	// This class implements a mutex interface. The actual work is done via //
21   	// TMutex which is available as soon as the thread library is loaded.   //
22   	//                                                                      //
23   	//////////////////////////////////////////////////////////////////////////
24   	
25   	#ifndef ROOT_TObject
26   	#include "TObject.h"
27   	#endif
28   	
29   	class TVirtualMutex;
30   	
31   	// Global mutex set in TThread::Init
32   	R__EXTERN TVirtualMutex *gGlobalMutex;
33   	
34   	class TVirtualMutex : public TObject {
35   	
36   	public:
37   	   TVirtualMutex(Bool_t /* recursive */ = kFALSE) { }
38   	   virtual ~TVirtualMutex() { }
39   	
40   	   virtual Int_t Lock() = 0;
41   	   virtual Int_t TryLock() = 0;
42   	   virtual Int_t UnLock() = 0;
43   	   virtual Int_t CleanUp() = 0;
44   	   Int_t Acquire() { return Lock(); }
45   	   Int_t Release() { return UnLock(); }
46   	
47   	   virtual TVirtualMutex *Factory(Bool_t /*recursive*/ = kFALSE) = 0;
48   	
49   	   ClassDef(TVirtualMutex,0)  // Virtual mutex lock class
50   	};
51   	
52   	
53   	//////////////////////////////////////////////////////////////////////////
54   	//                                                                      //
55   	// TLockGuard                                                           //
56   	//                                                                      //
57   	// This class provides mutex resource management in a guaranteed and    //
58   	// exception safe way. Use like this:                                   //
59   	// {                                                                    //
60   	//    TLockGuard guard(mutex);                                          //
61   	//    ... // do something                                               //
62   	// }                                                                    //
63   	// when guard goes out of scope the mutex is unlocked in the TLockGuard //
64   	// destructor. The exception mechanism takes care of calling the dtors  //
65   	// of local objects so it is exception safe.                            //
66   	//                                                                      //
67   	//////////////////////////////////////////////////////////////////////////
68   	
69   	class TLockGuard {
70   	
71   	private:
72   	   TVirtualMutex *fMutex;
73   	
74   	   TLockGuard(const TLockGuard&);             // not implemented
75   	   TLockGuard& operator=(const TLockGuard&);  // not implemented
76   	
77   	public:
78   	   TLockGuard(TVirtualMutex *mutex)
79   	     : fMutex(mutex) { if (fMutex) fMutex->Lock(); }
80   	   virtual ~TLockGuard() { if (fMutex) fMutex->UnLock(); }
81   	
82   	   ClassDef(TLockGuard,0)  // Exception safe locking/unlocking of mutex
83   	};
84   	
85   	// Zero overhead macros in case not compiled with thread support
86   	#if defined (_REENTRANT) || defined (WIN32)
87   	#define R__LOCKGUARD(mutex) TLockGuard _R__UNIQUE_(R__guard)(mutex)
88   	#define R__LOCKGUARD2(mutex)                             \
89   	   if (gGlobalMutex && !mutex) {                         \
90   	      gGlobalMutex->Lock();                              \
91   	      if (!mutex)                                        \
92   	         mutex = gGlobalMutex->Factory(kTRUE);           \
93   	      gGlobalMutex->UnLock();                            \
94   	   }                                                     \
95   	   R__LOCKGUARD(mutex)
96   	#else
97   	#define R__LOCKGUARD(mutex)  if (mutex) { }
98   	#define R__LOCKGUARD2(mutex) if (mutex) { }
99   	#endif
100  	
101  	#endif
102