Logo ROOT   6.18/05
Reference Guide
TSemaphore.cxx
Go to the documentation of this file.
1// @(#)root/thread:$Id$
2// Author: Fons Rademakers 02/07/97 (Revised: G Ganis, Nov 2015)
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, 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//////////////////////////////////////////////////////////////////////////
13// //
14// TSemaphore //
15// //
16// This class implements a counting semaphore. Use a semaphore //
17// to synchronize threads. //
18// //
19//////////////////////////////////////////////////////////////////////////
20
21#include "TSemaphore.h"
22
23////////////////////////////////////////////////////////////////////////////////
24/// Create counting semaphore.
25
26TSemaphore::TSemaphore(Int_t initial) : fValue(initial), fWakeups(0)
27{
28}
29
30////////////////////////////////////////////////////////////////////////////////
31/// If the semaphore value is > 0 then decrement it and carry on, else block,
32/// waiting on the condition until it is signaled.
33/// Returns always 0, for backward compatibility with the first implementation.
34
36{
37 std::unique_lock<std::mutex> lk(fMutex);
38 fValue--;
39
40 if (fValue < 0) {
41 do {
42 fCond.wait(lk);
43 } while (fWakeups < 1);
44 // We have been waken-up: decrease the related counter
45 fWakeups--;
46 }
47 return 0;
48}
49
50////////////////////////////////////////////////////////////////////////////////
51/// If the semaphore value is > 0 then decrement it and carry on, else block.
52/// If millisec > 0 then a relative timeout of millisec milliseconds is applied.
53/// For backward compatibility with the first implementation, millisec == 0 means
54/// no timeout.
55/// Returns 1 if timed-out, 0 otherwise.
56
58{
59 // For backward compatibility with the first implementation
60 if (millisec <= 0) return Wait();
61
62 Int_t rc= 0;
63 std::unique_lock<std::mutex> lk(fMutex);
64 fValue--;
65
66 if (fValue < 0) {
67 std::cv_status cvs = std::cv_status::timeout;
68 do {
69 cvs = fCond.wait_for(lk,std::chrono::milliseconds(millisec));
70 } while (fWakeups < 1 && cvs != std::cv_status::timeout);
71 if (cvs == std::cv_status::timeout) {
72 // Give back the token ...
73 fValue++;
74 rc = 1;
75 } else {
76 // We have been waken-up: decrease the related counter
77 fWakeups--;
78 }
79 }
80 return rc;
81}
82
83////////////////////////////////////////////////////////////////////////////////
84/// If the semaphore value is > 0 then decrement it and return 0. If it's
85/// already 0 then return 1. This call never blocks.
86
88{
89 std::unique_lock<std::mutex> lk(fMutex);
90 if (fValue > 0) {
91 fValue--;
92 } else {
93 return 1;
94 }
95 return 0;
96}
97
98////////////////////////////////////////////////////////////////////////////////
99/// Increment the value of the semaphore. If any threads are blocked in Wait(),
100/// wakeup one of them.
101/// Returns always 0, for backward compatibility with the first implementation.
102
104{
105 std::unique_lock<std::mutex> lk(fMutex);
106 fValue++;
107
108 if (fValue <= 0) {
109 // There were threads waiting: wake up one
110 fWakeups++;
111 fCond.notify_one();
112 }
113 return 0;
114}
PyObject * fValue
int Int_t
Definition: RtypesCore.h:41
UInt_t fWakeups
Definition: TSemaphore.h:35
std::mutex fMutex
Definition: TSemaphore.h:32
Int_t TryWait()
If the semaphore value is > 0 then decrement it and return 0.
Definition: TSemaphore.cxx:87
std::condition_variable fCond
Definition: TSemaphore.h:33
Int_t Post()
Increment the value of the semaphore.
Definition: TSemaphore.cxx:103
Int_t fValue
Definition: TSemaphore.h:34
TSemaphore(const TSemaphore &s)=delete
Int_t Wait()
If the semaphore value is > 0 then decrement it and carry on, else block, waiting on the condition un...
Definition: TSemaphore.cxx:35