XRootD
Loading...
Searching...
No Matches
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
33
34/******************************************************************************/
35/* D e s t r u c t o r */
36/******************************************************************************/
37
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
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
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}
void usage()
XrdSysXS_Type
@ xs_Shared
void Lock(const XrdSysXS_Type usage)
void UnLock(const XrdSysXS_Type usage=xs_None)