// @(#)root/thread:$Id$
// Author: Fons Rademakers   04/01/2000

/*************************************************************************
 * 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.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TRWLock                                                              //
//                                                                      //
// This class implements a reader/writer lock. A rwlock allows          //
// a resource to be accessed by multiple reader threads but only        //
// one writer thread.                                                   //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TRWLock.h"

ClassImp(TRWLock)

//______________________________________________________________________________
TRWLock::TRWLock() : fLockFree(&fMutex)
{
   // Create reader/write lock.

   fReaders = 0;
   fWriters = 0;
}

//______________________________________________________________________________
Int_t TRWLock::ReadLock()
{
   // Obtain a reader lock. Returns always 0.

   fMutex.Lock();

   while (fWriters)
      fLockFree.Wait();

   fReaders++;

   fMutex.UnLock();

   return 0;
}

//______________________________________________________________________________
Int_t TRWLock::ReadUnLock()
{
   // Unlock reader lock. Returns -1 if thread was not locked,
   // 0 if everything ok.

   fMutex.Lock();

   if (fReaders == 0) {
      fMutex.UnLock();
      return -1;
   } else {
      fReaders--;
      if (fReaders == 0)
         fLockFree.Signal();
      fMutex.UnLock();
      return 0;
   }
}

//______________________________________________________________________________
Int_t TRWLock::WriteLock()
{
   // Obtain a writer lock. Returns always 0.

   fMutex.Lock();

   while (fWriters || fReaders)
      fLockFree.Wait();

   fWriters++;

   fMutex.UnLock();

   return 0;
}

//______________________________________________________________________________
Int_t TRWLock::WriteUnLock()
{
   // Unlock writer lock. Returns -1 if thread was not locked,
   // 0 if everything ok.

   fMutex.Lock();

   if (fWriters == 0) {
      fMutex.UnLock();
      return -1;
   } else {
      fWriters = 0;
      fLockFree.Broadcast();
      fMutex.UnLock();
      return 0;
   }
}
 TRWLock.cxx:1
 TRWLock.cxx:2
 TRWLock.cxx:3
 TRWLock.cxx:4
 TRWLock.cxx:5
 TRWLock.cxx:6
 TRWLock.cxx:7
 TRWLock.cxx:8
 TRWLock.cxx:9
 TRWLock.cxx:10
 TRWLock.cxx:11
 TRWLock.cxx:12
 TRWLock.cxx:13
 TRWLock.cxx:14
 TRWLock.cxx:15
 TRWLock.cxx:16
 TRWLock.cxx:17
 TRWLock.cxx:18
 TRWLock.cxx:19
 TRWLock.cxx:20
 TRWLock.cxx:21
 TRWLock.cxx:22
 TRWLock.cxx:23
 TRWLock.cxx:24
 TRWLock.cxx:25
 TRWLock.cxx:26
 TRWLock.cxx:27
 TRWLock.cxx:28
 TRWLock.cxx:29
 TRWLock.cxx:30
 TRWLock.cxx:31
 TRWLock.cxx:32
 TRWLock.cxx:33
 TRWLock.cxx:34
 TRWLock.cxx:35
 TRWLock.cxx:36
 TRWLock.cxx:37
 TRWLock.cxx:38
 TRWLock.cxx:39
 TRWLock.cxx:40
 TRWLock.cxx:41
 TRWLock.cxx:42
 TRWLock.cxx:43
 TRWLock.cxx:44
 TRWLock.cxx:45
 TRWLock.cxx:46
 TRWLock.cxx:47
 TRWLock.cxx:48
 TRWLock.cxx:49
 TRWLock.cxx:50
 TRWLock.cxx:51
 TRWLock.cxx:52
 TRWLock.cxx:53
 TRWLock.cxx:54
 TRWLock.cxx:55
 TRWLock.cxx:56
 TRWLock.cxx:57
 TRWLock.cxx:58
 TRWLock.cxx:59
 TRWLock.cxx:60
 TRWLock.cxx:61
 TRWLock.cxx:62
 TRWLock.cxx:63
 TRWLock.cxx:64
 TRWLock.cxx:65
 TRWLock.cxx:66
 TRWLock.cxx:67
 TRWLock.cxx:68
 TRWLock.cxx:69
 TRWLock.cxx:70
 TRWLock.cxx:71
 TRWLock.cxx:72
 TRWLock.cxx:73
 TRWLock.cxx:74
 TRWLock.cxx:75
 TRWLock.cxx:76
 TRWLock.cxx:77
 TRWLock.cxx:78
 TRWLock.cxx:79
 TRWLock.cxx:80
 TRWLock.cxx:81
 TRWLock.cxx:82
 TRWLock.cxx:83
 TRWLock.cxx:84
 TRWLock.cxx:85
 TRWLock.cxx:86
 TRWLock.cxx:87
 TRWLock.cxx:88
 TRWLock.cxx:89
 TRWLock.cxx:90
 TRWLock.cxx:91
 TRWLock.cxx:92
 TRWLock.cxx:93
 TRWLock.cxx:94
 TRWLock.cxx:95
 TRWLock.cxx:96
 TRWLock.cxx:97
 TRWLock.cxx:98
 TRWLock.cxx:99
 TRWLock.cxx:100
 TRWLock.cxx:101
 TRWLock.cxx:102
 TRWLock.cxx:103
 TRWLock.cxx:104
 TRWLock.cxx:105
 TRWLock.cxx:106