XRootD
XrdSysXSLock.cc
Go to the documentation of this file.
1
/******************************************************************************/
2
/* */
3
/* X r d S y s X S L o c k . c c */
4
/* */
5
/* (c) 2003 by the Board of Trustees of the Leland Stanford, Jr., University */
6
/* All Rights Reserved */
7
/* Produced by Andrew Hanushevsky for Stanford University under contract */
8
/* DE-AC02-76-SFO0515 with the Department of Energy */
9
/* */
10
/* This file is part of the XRootD software suite. */
11
/* */
12
/* XRootD is free software: you can redistribute it and/or modify it under */
13
/* the terms of the GNU Lesser General Public License as published by the */
14
/* Free Software Foundation, either version 3 of the License, or (at your */
15
/* option) any later version. */
16
/* */
17
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20
/* License for more details. */
21
/* */
22
/* You should have received a copy of the GNU Lesser General Public License */
23
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24
/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25
/* */
26
/* The copyright holder's institutional names and contributor's names may not */
27
/* be used to endorse or promote products derived from this software without */
28
/* specific prior written permission of the institution or contributor. */
29
/******************************************************************************/
30
31
#include "
XrdSys/XrdSysHeaders.hh
"
32
#include "
XrdSys/XrdSysXSLock.hh
"
33
34
/******************************************************************************/
35
/* D e s t r u c t o r */
36
/******************************************************************************/
37
38
XrdSysXSLock::~XrdSysXSLock
()
39
{
40
41
// Prevent usage while destroying object but make sure no one else is using it
42
//
43
LockContext.
Lock
();
44
if
(cur_count || shr_wait || exc_wait)
45
{LockContext.
UnLock
();
46
abort();
47
}
48
LockContext.
UnLock
();
49
}
50
51
/******************************************************************************/
52
/* L o c k */
53
/******************************************************************************/
54
55
void
XrdSysXSLock::Lock
(
const
XrdSysXS_Type
usage
)
56
{
57
58
// Serialize access to this object
59
//
60
LockContext.
Lock
();
61
62
// This loop continues until we can acquire the resource. We are gauranteed
63
// to eventually acquire it regardless of the unblocking order.
64
//
65
while
(cur_count)
66
{
67
// If usage is compatible with current usage get the lock right away
68
//
69
if
(
usage
==
xs_Shared
&& cur_usage ==
xs_Shared
&& !exc_wait)
break
;
70
71
// Indicate that we are waiting
72
//
73
if
(
usage
==
xs_Shared
) shr_wait++;
74
else
exc_wait++;
75
76
// Usage is not compatible. We must wait for current lock mode to end
77
//
78
LockContext.
UnLock
();
79
if
(
usage
==
xs_Shared
) WantShr.
Wait
();
80
else
WantExc.
Wait
();
81
LockContext.
Lock
();
82
}
83
84
// We obtained the right to use this object
85
//
86
cur_usage =
usage
;
87
cur_count++;
88
LockContext.
UnLock
();
89
}
90
91
/******************************************************************************/
92
/* U n L o c k */
93
/******************************************************************************/
94
95
void
XrdSysXSLock::UnLock
(
const
XrdSysXS_Type
usage
)
96
{
97
98
// Serialize access to our data
99
//
100
LockContext.
Lock
();
101
102
// Make sure that the lock is currently being used
103
//
104
if
(!cur_count)
105
{LockContext.
UnLock
();
106
std::cerr <<
"XSLock: Attempt to unlock inactive lock."
<<std::endl;
107
throw
"XSLock: unlocking inactive lock."
;
108
}
109
110
// Verify that usage is correct
111
//
112
if
(
usage
&& cur_usage !=
usage
)
113
{LockContext.
UnLock
();
114
std::cerr <<
"XSLock: Incorrect unlock usage - "
115
<< (cur_usage ==
xs_Shared
?
"shr"
:
"exc"
) <<
"!="
116
<< (
usage
==
xs_Shared
?
"shr"
:
"exc"
) << std::endl;
117
throw
"XSLock: invalid unlock usage specified."
;
118
}
119
120
// Unlock the current object. If no locks exist then check if we can let another
121
// thread use this object. The logic is tricky but we are trying to avoid
122
// starvation in an environment that has no thread ordering.
123
//
124
cur_count--;
125
if
(!cur_count)
126
if
(exc_wait && (toggle || !shr_wait))
127
{toggle = 0; WantExc.
Post
(); exc_wait--;}
128
else
{
while
(shr_wait) {WantShr.
Post
(); shr_wait--;}
129
toggle = 1;}
130
else
if
(!toggle) {
while
(shr_wait) {WantShr.
Post
(); shr_wait--;}
131
toggle = 1;}
132
133
LockContext.
UnLock
();
134
}
usage
void usage()
Definition:
XrdClReplay.cc:1072
XrdSysHeaders.hh
XrdSysXSLock.hh
XrdSysXS_Type
XrdSysXS_Type
Definition:
XrdSysXSLock.hh:38
xs_Shared
@ xs_Shared
Definition:
XrdSysXSLock.hh:38
XrdSysMutex::Lock
void Lock()
Definition:
XrdSysPthread.hh:222
XrdSysMutex::UnLock
void UnLock()
Definition:
XrdSysPthread.hh:224
XrdSysSemaphore::Wait
void Wait()
Definition:
XrdSysPthread.hh:509
XrdSysSemaphore::Post
void Post()
Definition:
XrdSysPthread.hh:505
XrdSysXSLock::Lock
void Lock(const XrdSysXS_Type usage)
Definition:
XrdSysXSLock.cc:55
XrdSysXSLock::UnLock
void UnLock(const XrdSysXS_Type usage=xs_None)
Definition:
XrdSysXSLock.cc:95
XrdSysXSLock::~XrdSysXSLock
~XrdSysXSLock()
Definition:
XrdSysXSLock.cc:38
XrdSys
XrdSysXSLock.cc
Generated by
1.9.1