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 
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
Definition: XrdSysXSLock.hh:38
@ xs_Shared
Definition: XrdSysXSLock.hh:38
void Lock(const XrdSysXS_Type usage)
Definition: XrdSysXSLock.cc:55
void UnLock(const XrdSysXS_Type usage=xs_None)
Definition: XrdSysXSLock.cc:95