ROOT logo
// @(#)root/thread:$Id: TMutex.cxx 26440 2008-11-25 03:06:35Z pcanal $
// Author: Fons Rademakers   26/06/97

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

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TMutex                                                               //
//                                                                      //
// This class implements mutex locks. A mutex is a mutual exclusive     //
// lock. The actual work is done via the TMutexImp class (either        //
// TPosixMutex or TWin32Mutex).                                         //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TInterpreter.h"
#include "TMutex.h"
#include "TThreadFactory.h"
#include <errno.h>


ClassImp(TMutex)

//______________________________________________________________________________
TMutex::TMutex(Bool_t recursive)
{
   // Create a mutex lock. The actual mutex implementation will be
   // provided via the TThreadFactory.

   fMutexImp = gThreadFactory->CreateMutexImp();
   fId  = -1;
   fRef = recursive ? 0 : -1;

   if (!fMutexImp)
      Error("TMutex", "could not create TMutexImp");
}

//______________________________________________________________________________
Int_t TMutex::Lock()
{
   // Lock the mutex. Returns 0 when no error, EDEADLK when mutex was already
   // locked by this thread and this mutex is not reentrant.

   Long_t id = TThread::SelfId();
#ifdef WIN32
   if ((this == gCINTMutex) || (id == fId)) {
#else
   if (id == fId) {
#endif
      // we hold the mutex
      if (fRef < 0) {
         Error("Lock", "mutex is already locked by this thread %ld", fId);
         return EDEADLK;
      } else {
         fRef++;
         return 0;
      }
   }

   // we do not hold the mutex yet
   Int_t iret = fMutexImp->Lock();
   fId = id;
   return iret;
}

//______________________________________________________________________________
Int_t TMutex::TryLock()
{
   // Try to lock mutex. Returns 0 when no error, EDEADLK when mutex was
   // already locked by this thread and this mutex is not reentrant.

   Long_t id = TThread::SelfId();
#ifdef WIN32
   if ((this == gCINTMutex) || (id == fId)) {
#else
   if (id == fId) {
#endif
      // we hold the mutex
      if (fRef < 0) {
         Error("TryLock", "mutex is already locked by this thread %ld", fId);
         return EDEADLK;
      } else {
         fRef++;
         return 0;
      }
   }

   // we do not hold the mutex yet
   Int_t iret = fMutexImp->TryLock();
   if (iret == 0) fId = id;
   return iret;
}

//______________________________________________________________________________
Int_t TMutex::UnLock()
{
   // Unlock the mutex. Returns 0 when no error, EPERM when mutex was already
   // unlocked by this thread.

   Long_t id = fId;
   Long_t myid = TThread::SelfId();

#ifdef WIN32
   if ((this != gCINTMutex) && (id != myid)) {
#else
   if (id != myid) {
#endif
      // we do not own the mutex, figure out what happened
      if (id == -1) {
         Error("UnLock", "thread %ld tries to unlock unlocked mutex", myid);
      } else {
         Error("UnLock", "thread %ld tries to unlock mutex locked by thread %ld", myid, id);
      }
      return EPERM;
   }

   // we own the mutex
   if (fRef > 0) {
      fRef--;
      return 0;
   }
   fId = -1;
   return fMutexImp->UnLock();
}

//______________________________________________________________________________
Int_t TMutex::CleanUp()
{
   // Clean up of mutex if it belongs to thread.

   if (TThread::SelfId() != fId) return 0;
   if (fRef > 0) fRef = 0;
   return UnLock();
}

//______________________________________________________________________________
TVirtualMutex *TMutex::Factory(Bool_t recursive)
{
   // Create mutex and return pointer to it. Calling function must care
   // about proper deletion. The function is intended to be used in connection
   // with the R__LOCKGUARD2 macro for local thread protection. Since "new" is
   // used the TStorage class has to be protected by gGlobalMutex.

   TVirtualMutex *ret = new TMutex(recursive);
   return ret;
}
 TMutex.cxx:1
 TMutex.cxx:2
 TMutex.cxx:3
 TMutex.cxx:4
 TMutex.cxx:5
 TMutex.cxx:6
 TMutex.cxx:7
 TMutex.cxx:8
 TMutex.cxx:9
 TMutex.cxx:10
 TMutex.cxx:11
 TMutex.cxx:12
 TMutex.cxx:13
 TMutex.cxx:14
 TMutex.cxx:15
 TMutex.cxx:16
 TMutex.cxx:17
 TMutex.cxx:18
 TMutex.cxx:19
 TMutex.cxx:20
 TMutex.cxx:21
 TMutex.cxx:22
 TMutex.cxx:23
 TMutex.cxx:24
 TMutex.cxx:25
 TMutex.cxx:26
 TMutex.cxx:27
 TMutex.cxx:28
 TMutex.cxx:29
 TMutex.cxx:30
 TMutex.cxx:31
 TMutex.cxx:32
 TMutex.cxx:33
 TMutex.cxx:34
 TMutex.cxx:35
 TMutex.cxx:36
 TMutex.cxx:37
 TMutex.cxx:38
 TMutex.cxx:39
 TMutex.cxx:40
 TMutex.cxx:41
 TMutex.cxx:42
 TMutex.cxx:43
 TMutex.cxx:44
 TMutex.cxx:45
 TMutex.cxx:46
 TMutex.cxx:47
 TMutex.cxx:48
 TMutex.cxx:49
 TMutex.cxx:50
 TMutex.cxx:51
 TMutex.cxx:52
 TMutex.cxx:53
 TMutex.cxx:54
 TMutex.cxx:55
 TMutex.cxx:56
 TMutex.cxx:57
 TMutex.cxx:58
 TMutex.cxx:59
 TMutex.cxx:60
 TMutex.cxx:61
 TMutex.cxx:62
 TMutex.cxx:63
 TMutex.cxx:64
 TMutex.cxx:65
 TMutex.cxx:66
 TMutex.cxx:67
 TMutex.cxx:68
 TMutex.cxx:69
 TMutex.cxx:70
 TMutex.cxx:71
 TMutex.cxx:72
 TMutex.cxx:73
 TMutex.cxx:74
 TMutex.cxx:75
 TMutex.cxx:76
 TMutex.cxx:77
 TMutex.cxx:78
 TMutex.cxx:79
 TMutex.cxx:80
 TMutex.cxx:81
 TMutex.cxx:82
 TMutex.cxx:83
 TMutex.cxx:84
 TMutex.cxx:85
 TMutex.cxx:86
 TMutex.cxx:87
 TMutex.cxx:88
 TMutex.cxx:89
 TMutex.cxx:90
 TMutex.cxx:91
 TMutex.cxx:92
 TMutex.cxx:93
 TMutex.cxx:94
 TMutex.cxx:95
 TMutex.cxx:96
 TMutex.cxx:97
 TMutex.cxx:98
 TMutex.cxx:99
 TMutex.cxx:100
 TMutex.cxx:101
 TMutex.cxx:102
 TMutex.cxx:103
 TMutex.cxx:104
 TMutex.cxx:105
 TMutex.cxx:106
 TMutex.cxx:107
 TMutex.cxx:108
 TMutex.cxx:109
 TMutex.cxx:110
 TMutex.cxx:111
 TMutex.cxx:112
 TMutex.cxx:113
 TMutex.cxx:114
 TMutex.cxx:115
 TMutex.cxx:116
 TMutex.cxx:117
 TMutex.cxx:118
 TMutex.cxx:119
 TMutex.cxx:120
 TMutex.cxx:121
 TMutex.cxx:122
 TMutex.cxx:123
 TMutex.cxx:124
 TMutex.cxx:125
 TMutex.cxx:126
 TMutex.cxx:127
 TMutex.cxx:128
 TMutex.cxx:129
 TMutex.cxx:130
 TMutex.cxx:131
 TMutex.cxx:132
 TMutex.cxx:133
 TMutex.cxx:134
 TMutex.cxx:135
 TMutex.cxx:136
 TMutex.cxx:137
 TMutex.cxx:138
 TMutex.cxx:139
 TMutex.cxx:140
 TMutex.cxx:141
 TMutex.cxx:142
 TMutex.cxx:143
 TMutex.cxx:144
 TMutex.cxx:145
 TMutex.cxx:146
 TMutex.cxx:147
 TMutex.cxx:148
 TMutex.cxx:149
 TMutex.cxx:150
 TMutex.cxx:151
 TMutex.cxx:152