// @(#)root/thread:$Id$
// Author: Fons Rademakers   01/07/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.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TCondition                                                           //
//                                                                      //
// This class implements a condition variable. Use a condition variable //
// to signal threads. The actual work is done via the TConditionImp     //
// class (either TPosixCondition or TWin32Condition).                   //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include "TCondition.h"
#include "TMutex.h"
#include "TThreadFactory.h"


ClassImp(TCondition)

//______________________________________________________________________________
TCondition::TCondition(TMutex *m)
{
   // Create a condition variable. The actual condition implementation
   // will be provided via the TThreadFactory. If no external mutex is
   // provided one will be created. Use GetMutex() to get this mutex
   // and use it before calling Signal() or Broadcast().

   fPrivateMutex = (m == 0);
   if (fPrivateMutex) {
      fMutex = new TMutex();
   } else {
      fMutex = m;
   }

   fConditionImp = gThreadFactory->CreateConditionImp(fMutex->fMutexImp);

   if (!fConditionImp)
      Error("TCondition", "could not create TConditionImp");
}

//______________________________________________________________________________
TCondition::~TCondition()
{
   // Clean up condition variable.

   delete fConditionImp;
   if (fPrivateMutex) delete fMutex;
}

//______________________________________________________________________________
TMutex *TCondition::GetMutex() const
{
   // Get internally created mutex. Use it to lock resources
   // before calling Signal() or Broadcast(). Returns 0 if
   // external mutex was provided in TCondition ctor.

   if (fPrivateMutex)
      return fMutex;
   return 0;
}

//______________________________________________________________________________
Int_t TCondition::Wait()
{
   // Wait to be signaled.

   if (!fConditionImp) return -1;

   Int_t iret;
   if (fPrivateMutex) fMutex->Lock();
   iret = fConditionImp->Wait();
   if (fPrivateMutex) fMutex->UnLock();
   return iret;
}

//______________________________________________________________________________
Int_t TCondition::TimedWait(ULong_t secs, ULong_t nanoSec)
{
   // Wait to be signaled or till the timer times out.
   // This method is given an absolute time since the beginning of
   // the EPOCH (use TThread::GetTime() to get this absolute time).
   // To wait for a relative time from now, use
   // TCondition::TimedWaitRelative(ULong_t ms).
   // Returns 0 if successfully signalled, 1 if time expired and -1 in
   // case of error.

   if (!fConditionImp) return -1;

   Int_t iret;
   if (fPrivateMutex) fMutex->Lock();
   iret = fConditionImp->TimedWait(secs, nanoSec);
   if (fPrivateMutex) fMutex->UnLock();
   return iret;
}

//______________________________________________________________________________
Int_t TCondition::TimedWaitRelative(ULong_t ms)
{
   // Wait to be signaled or till the timer times out.
   // This method is given a relative time from now.
   // To wait for an absolute time since the beginning of the EPOCH, use
   // TCondition::TimedWait(ULong_t secs, ULong_t nanoSec).
   // Returns 0 if successfully signalled, 1 if time expired and -1 in
   // case of error.

   if (!fConditionImp) return -1;

   ULong_t absSec, absNanoSec;
   TThread::GetTime(&absSec, &absNanoSec);

   ULong_t dsec = ms/1000;
   absSec += dsec;
   absNanoSec += (ms - dsec*1000) * 1000000;
   if (absNanoSec > 999999999) {
      absSec += 1;
      absNanoSec -= 1000000000;
   }

   return TimedWait(absSec, absNanoSec);
}
 TCondition.cxx:1
 TCondition.cxx:2
 TCondition.cxx:3
 TCondition.cxx:4
 TCondition.cxx:5
 TCondition.cxx:6
 TCondition.cxx:7
 TCondition.cxx:8
 TCondition.cxx:9
 TCondition.cxx:10
 TCondition.cxx:11
 TCondition.cxx:12
 TCondition.cxx:13
 TCondition.cxx:14
 TCondition.cxx:15
 TCondition.cxx:16
 TCondition.cxx:17
 TCondition.cxx:18
 TCondition.cxx:19
 TCondition.cxx:20
 TCondition.cxx:21
 TCondition.cxx:22
 TCondition.cxx:23
 TCondition.cxx:24
 TCondition.cxx:25
 TCondition.cxx:26
 TCondition.cxx:27
 TCondition.cxx:28
 TCondition.cxx:29
 TCondition.cxx:30
 TCondition.cxx:31
 TCondition.cxx:32
 TCondition.cxx:33
 TCondition.cxx:34
 TCondition.cxx:35
 TCondition.cxx:36
 TCondition.cxx:37
 TCondition.cxx:38
 TCondition.cxx:39
 TCondition.cxx:40
 TCondition.cxx:41
 TCondition.cxx:42
 TCondition.cxx:43
 TCondition.cxx:44
 TCondition.cxx:45
 TCondition.cxx:46
 TCondition.cxx:47
 TCondition.cxx:48
 TCondition.cxx:49
 TCondition.cxx:50
 TCondition.cxx:51
 TCondition.cxx:52
 TCondition.cxx:53
 TCondition.cxx:54
 TCondition.cxx:55
 TCondition.cxx:56
 TCondition.cxx:57
 TCondition.cxx:58
 TCondition.cxx:59
 TCondition.cxx:60
 TCondition.cxx:61
 TCondition.cxx:62
 TCondition.cxx:63
 TCondition.cxx:64
 TCondition.cxx:65
 TCondition.cxx:66
 TCondition.cxx:67
 TCondition.cxx:68
 TCondition.cxx:69
 TCondition.cxx:70
 TCondition.cxx:71
 TCondition.cxx:72
 TCondition.cxx:73
 TCondition.cxx:74
 TCondition.cxx:75
 TCondition.cxx:76
 TCondition.cxx:77
 TCondition.cxx:78
 TCondition.cxx:79
 TCondition.cxx:80
 TCondition.cxx:81
 TCondition.cxx:82
 TCondition.cxx:83
 TCondition.cxx:84
 TCondition.cxx:85
 TCondition.cxx:86
 TCondition.cxx:87
 TCondition.cxx:88
 TCondition.cxx:89
 TCondition.cxx:90
 TCondition.cxx:91
 TCondition.cxx:92
 TCondition.cxx:93
 TCondition.cxx:94
 TCondition.cxx:95
 TCondition.cxx:96
 TCondition.cxx:97
 TCondition.cxx:98
 TCondition.cxx:99
 TCondition.cxx:100
 TCondition.cxx:101
 TCondition.cxx:102
 TCondition.cxx:103
 TCondition.cxx:104
 TCondition.cxx:105
 TCondition.cxx:106
 TCondition.cxx:107
 TCondition.cxx:108
 TCondition.cxx:109
 TCondition.cxx:110
 TCondition.cxx:111
 TCondition.cxx:112
 TCondition.cxx:113
 TCondition.cxx:114
 TCondition.cxx:115
 TCondition.cxx:116
 TCondition.cxx:117
 TCondition.cxx:118
 TCondition.cxx:119
 TCondition.cxx:120
 TCondition.cxx:121
 TCondition.cxx:122
 TCondition.cxx:123
 TCondition.cxx:124
 TCondition.cxx:125
 TCondition.cxx:126
 TCondition.cxx:127
 TCondition.cxx:128
 TCondition.cxx:129