// @(#)root/base:$Id$
// Author: Fons Rademakers   14/07/2002

/*************************************************************************
 * Copyright (C) 1995-2002, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#ifndef ROOT_TVirtualMutex
#define ROOT_TVirtualMutex


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TVirtualMutex                                                        //
//                                                                      //
// This class implements a mutex interface. The actual work is done via //
// TMutex which is available as soon as the thread library is loaded.   //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifndef ROOT_TObject
#include "TObject.h"
#endif

class TVirtualMutex;

// Global mutex set in TThread::Init
R__EXTERN TVirtualMutex *gGlobalMutex;

class TVirtualMutex : public TObject {

public:
   TVirtualMutex(Bool_t /* recursive */ = kFALSE) { }
   virtual ~TVirtualMutex() { }

   virtual Int_t Lock() = 0;
   virtual Int_t TryLock() = 0;
   virtual Int_t UnLock() = 0;
   virtual Int_t CleanUp() = 0;
   Int_t Acquire() { return Lock(); }
   Int_t Release() { return UnLock(); }

   virtual TVirtualMutex *Factory(Bool_t /*recursive*/ = kFALSE) = 0;

   ClassDef(TVirtualMutex,0)  // Virtual mutex lock class
};


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TLockGuard                                                           //
//                                                                      //
// This class provides mutex resource management in a guaranteed and    //
// exception safe way. Use like this:                                   //
// {                                                                    //
//    TLockGuard guard(mutex);                                          //
//    ... // do something                                               //
// }                                                                    //
// when guard goes out of scope the mutex is unlocked in the TLockGuard //
// destructor. The exception mechanism takes care of calling the dtors  //
// of local objects so it is exception safe.                            //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

class TLockGuard {

private:
   TVirtualMutex *fMutex;

   TLockGuard(const TLockGuard&);             // not implemented
   TLockGuard& operator=(const TLockGuard&);  // not implemented

public:
   TLockGuard(TVirtualMutex *mutex)
     : fMutex(mutex) { if (fMutex) fMutex->Lock(); }
   Int_t UnLock() {
      if (!fMutex) return 0;
      auto tmp = fMutex;
      fMutex = 0;
      return tmp->UnLock();
   }
   ~TLockGuard() { if (fMutex) fMutex->UnLock(); }

   ClassDefNV(TLockGuard,0)  // Exception safe locking/unlocking of mutex
};

// Zero overhead macros in case not compiled with thread support
#if defined (_REENTRANT) || defined (WIN32)

#define R__LOCKGUARD(mutex) TLockGuard _R__UNIQUE_(R__guard)(mutex)
#define R__LOCKGUARD2(mutex)                             \
   if (gGlobalMutex && !mutex) {                         \
      gGlobalMutex->Lock();                              \
      if (!mutex)                                        \
         mutex = gGlobalMutex->Factory(kTRUE);           \
      gGlobalMutex->UnLock();                            \
   }                                                     \
   R__LOCKGUARD(mutex)
#define R__LOCKGUARD_NAMED(name,mutex) TLockGuard _NAME2_(R__guard,name)(mutex)
#define R__LOCKGUARD_UNLOCK(name) _NAME2_(R__guard,name).UnLock()
#else
#define R__LOCKGUARD(mutex)  if (mutex) { }
#define R__LOCKGUARD_NAMED(name,mutex) if (mutex) { }
#define R__LOCKGUARD2(mutex) if (mutex) { }
#define R__LOCKGUARD_UNLOCK(name) { }
#endif

#endif
 TVirtualMutex.h:1
 TVirtualMutex.h:2
 TVirtualMutex.h:3
 TVirtualMutex.h:4
 TVirtualMutex.h:5
 TVirtualMutex.h:6
 TVirtualMutex.h:7
 TVirtualMutex.h:8
 TVirtualMutex.h:9
 TVirtualMutex.h:10
 TVirtualMutex.h:11
 TVirtualMutex.h:12
 TVirtualMutex.h:13
 TVirtualMutex.h:14
 TVirtualMutex.h:15
 TVirtualMutex.h:16
 TVirtualMutex.h:17
 TVirtualMutex.h:18
 TVirtualMutex.h:19
 TVirtualMutex.h:20
 TVirtualMutex.h:21
 TVirtualMutex.h:22
 TVirtualMutex.h:23
 TVirtualMutex.h:24
 TVirtualMutex.h:25
 TVirtualMutex.h:26
 TVirtualMutex.h:27
 TVirtualMutex.h:28
 TVirtualMutex.h:29
 TVirtualMutex.h:30
 TVirtualMutex.h:31
 TVirtualMutex.h:32
 TVirtualMutex.h:33
 TVirtualMutex.h:34
 TVirtualMutex.h:35
 TVirtualMutex.h:36
 TVirtualMutex.h:37
 TVirtualMutex.h:38
 TVirtualMutex.h:39
 TVirtualMutex.h:40
 TVirtualMutex.h:41
 TVirtualMutex.h:42
 TVirtualMutex.h:43
 TVirtualMutex.h:44
 TVirtualMutex.h:45
 TVirtualMutex.h:46
 TVirtualMutex.h:47
 TVirtualMutex.h:48
 TVirtualMutex.h:49
 TVirtualMutex.h:50
 TVirtualMutex.h:51
 TVirtualMutex.h:52
 TVirtualMutex.h:53
 TVirtualMutex.h:54
 TVirtualMutex.h:55
 TVirtualMutex.h:56
 TVirtualMutex.h:57
 TVirtualMutex.h:58
 TVirtualMutex.h:59
 TVirtualMutex.h:60
 TVirtualMutex.h:61
 TVirtualMutex.h:62
 TVirtualMutex.h:63
 TVirtualMutex.h:64
 TVirtualMutex.h:65
 TVirtualMutex.h:66
 TVirtualMutex.h:67
 TVirtualMutex.h:68
 TVirtualMutex.h:69
 TVirtualMutex.h:70
 TVirtualMutex.h:71
 TVirtualMutex.h:72
 TVirtualMutex.h:73
 TVirtualMutex.h:74
 TVirtualMutex.h:75
 TVirtualMutex.h:76
 TVirtualMutex.h:77
 TVirtualMutex.h:78
 TVirtualMutex.h:79
 TVirtualMutex.h:80
 TVirtualMutex.h:81
 TVirtualMutex.h:82
 TVirtualMutex.h:83
 TVirtualMutex.h:84
 TVirtualMutex.h:85
 TVirtualMutex.h:86
 TVirtualMutex.h:87
 TVirtualMutex.h:88
 TVirtualMutex.h:89
 TVirtualMutex.h:90
 TVirtualMutex.h:91
 TVirtualMutex.h:92
 TVirtualMutex.h:93
 TVirtualMutex.h:94
 TVirtualMutex.h:95
 TVirtualMutex.h:96
 TVirtualMutex.h:97
 TVirtualMutex.h:98
 TVirtualMutex.h:99
 TVirtualMutex.h:100
 TVirtualMutex.h:101
 TVirtualMutex.h:102
 TVirtualMutex.h:103
 TVirtualMutex.h:104
 TVirtualMutex.h:105
 TVirtualMutex.h:106
 TVirtualMutex.h:107
 TVirtualMutex.h:108
 TVirtualMutex.h:109
 TVirtualMutex.h:110
 TVirtualMutex.h:111
 TVirtualMutex.h:112