xrootd
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
XrdOssCsiRanges.hh
Go to the documentation of this file.
1 #ifndef _XRDOSSCSIRANGES_H
2 #define _XRDOSSCSIRANGES_H
3 /******************************************************************************/
4 /* */
5 /* X r d O s s C s i R a n g e s . h h */
6 /* */
7 /* (C) Copyright 2020 CERN. */
8 /* */
9 /* This file is part of the XRootD software suite. */
10 /* */
11 /* XRootD is free software: you can redistribute it and/or modify it under */
12 /* the terms of the GNU Lesser General Public License as published by the */
13 /* Free Software Foundation, either version 3 of the License, or (at your */
14 /* option) any later version. */
15 /* */
16 /* In applying this licence, CERN does not waive the privileges and */
17 /* immunities granted to it by virtue of its status as an Intergovernmental */
18 /* Organization or submit itself to any jurisdiction. */
19 /* */
20 /* XRootD is distributed in the hope that it will be useful, but WITHOUT */
21 /* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
22 /* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
23 /* License for more details. */
24 /* */
25 /* You should have received a copy of the GNU Lesser General Public License */
26 /* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
27 /* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
28 /* */
29 /* The copyright holder's institutional names and contributor's names may not */
30 /* be used to endorse or promote products derived from this software without */
31 /* specific prior written permission of the institution or contributor. */
32 /******************************************************************************/
33 
34 #include "XrdSys/XrdSysPthread.hh"
35 
36 #include <mutex>
37 #include <list>
38 #include <condition_variable>
39 #include <memory>
40 
41 // forward decl
42 class XrdOssCsiPages;
43 
45 {
46  off_t start;
47  off_t end;
48  bool rdonly;
50  std::mutex mtx;
51  std::condition_variable cv;
53 };
54 
55 class XrdOssCsiRanges;
56 
58 {
59 public:
60  XrdOssCsiRangeGuard() : r_(NULL), rp_(NULL), pages_(NULL), trackinglenlocked_(false) { }
62 
64  {
65  r_ = r;
66  rp_ = rp;
67  pages_ = NULL;
68  trackinglenlocked_ = false;
69  }
70 
71  const std::pair<off_t,off_t>& getTrackinglens() const
72  {
73  return trackingsizes_;
74  }
75 
76  void SetTrackingInfo(XrdOssCsiPages *p, const std::pair<off_t,off_t> &tsizes, bool locked)
77  {
78  trackingsizes_ = tsizes;
79  if (locked)
80  {
81  trackinglenlocked_ = true;
82  pages_ = p;
83  }
84  }
85 
86  void Wait();
87 
88  void unlockTrackinglen();
89  void ReleaseAll();
90 
91 private:
95  std::pair<off_t,off_t> trackingsizes_;
97 };
98 
99 
101 {
102 public:
104 
106  {
107  XrdOssCsiRange_s *p;
108  while((p = allocList_))
109  {
111  delete p;
112  }
113  }
114 
115  //
116  // AddRange: add an inclusive range lock on pages [start, end]
117  //
118  void AddRange(const off_t start, const off_t end, XrdOssCsiRangeGuard &rg, bool rdonly)
119  {
120  std::unique_lock<std::mutex> lck(rmtx_);
121 
122  int nblocking = 0;
123  for(auto itr = ranges_.begin(); itr != ranges_.end(); ++itr)
124  {
125  if ((*itr)->start <= end && start <= (*itr)->end)
126  {
127  if (!(rdonly && (*itr)->rdonly))
128  {
129  nblocking++;
130  }
131  }
132  }
133 
135  nr->start = start;
136  nr->end = end;
137  nr->rdonly = rdonly;
138  nr->nBlockedBy = nblocking;
139  ranges_.push_back(nr);
140  lck.unlock();
141 
142  rg.SetRange(this, nr);
143  }
144 
146  {
147  std::unique_lock<std::mutex> l(rp->mtx);
148  while (rp->nBlockedBy>0)
149  {
150  rp->cv.wait(l);
151  }
152  }
153 
155  {
156  std::lock_guard<std::mutex> guard(rmtx_);
157  for(auto itr=ranges_.begin();itr!=ranges_.end();++itr)
158  {
159  if (*itr == rp)
160  {
161  ranges_.erase(itr);
162  break;
163  }
164  }
165 
166  for(auto itr=ranges_.begin(); itr != ranges_.end(); ++itr)
167  {
168  if ((*itr)->start <= rp->end && rp->start <= (*itr)->end)
169  {
170  if (!(rp->rdonly && (*itr)->rdonly))
171  {
172  std::unique_lock<std::mutex> l((*itr)->mtx);
173  (*itr)->nBlockedBy--;
174  if ((*itr)->nBlockedBy == 0)
175  {
176  (*itr)->cv.notify_one();
177  }
178  }
179  }
180  }
181 
182  RecycleRange(rp);
183  rp = NULL;
184  }
185 
186 private:
187  std::mutex rmtx_;
188  std::list<XrdOssCsiRange_s *> ranges_;
190 
191  // must be called with rmtx_ locked
193  {
194  XrdOssCsiRange_s *p;
195  if ((p = allocList_)) allocList_ = p->next;
196  if (!p) p = new XrdOssCsiRange_s();
197  p->next = NULL;
198  return p;
199  }
200 
201  // must be called with rmtx_ locked
203  {
204  rp->next = allocList_;
205  allocList_ = rp;
206  }
207 };
208 
209 #endif
std::mutex mtx
Definition: XrdOssCsiRanges.hh:50
int nBlockedBy
Definition: XrdOssCsiRanges.hh:49
bool rdonly
Definition: XrdOssCsiRanges.hh:48
off_t end
Definition: XrdOssCsiRanges.hh:47
std::pair< off_t, off_t > trackingsizes_
Definition: XrdOssCsiRanges.hh:95
void SetRange(XrdOssCsiRanges *r, XrdOssCsiRange_s *rp)
Definition: XrdOssCsiRanges.hh:63
XrdOssCsiRange_s * allocList_
Definition: XrdOssCsiRanges.hh:189
Definition: XrdOssCsiRanges.hh:100
XrdOssCsiRanges * r_
Definition: XrdOssCsiRanges.hh:92
const std::pair< off_t, off_t > & getTrackinglens() const
Definition: XrdOssCsiRanges.hh:71
void AddRange(const off_t start, const off_t end, XrdOssCsiRangeGuard &rg, bool rdonly)
Definition: XrdOssCsiRanges.hh:118
std::list< XrdOssCsiRange_s * > ranges_
Definition: XrdOssCsiRanges.hh:188
Definition: XrdOssCsiRanges.hh:44
XrdOssCsiRange_s * rp_
Definition: XrdOssCsiRanges.hh:93
void RecycleRange(XrdOssCsiRange_s *rp)
Definition: XrdOssCsiRanges.hh:202
bool trackinglenlocked_
Definition: XrdOssCsiRanges.hh:96
Definition: XrdOssCsiPages.hh:45
Definition: XrdOssCsiRanges.hh:57
XrdOssCsiPages * pages_
Definition: XrdOssCsiRanges.hh:94
XrdOssCsiRangeGuard()
Definition: XrdOssCsiRanges.hh:60
XrdOssCsiRange_s * AllocRange()
Definition: XrdOssCsiRanges.hh:192
off_t start
Definition: XrdOssCsiRanges.hh:46
XrdOssCsiRanges()
Definition: XrdOssCsiRanges.hh:103
void SetTrackingInfo(XrdOssCsiPages *p, const std::pair< off_t, off_t > &tsizes, bool locked)
Definition: XrdOssCsiRanges.hh:76
std::mutex rmtx_
Definition: XrdOssCsiRanges.hh:187
~XrdOssCsiRanges()
Definition: XrdOssCsiRanges.hh:105
std::condition_variable cv
Definition: XrdOssCsiRanges.hh:51
XrdOssCsiRange_s * next
Definition: XrdOssCsiRanges.hh:52
void RemoveRange(XrdOssCsiRange_s *rp)
Definition: XrdOssCsiRanges.hh:154
void Wait(XrdOssCsiRange_s *rp)
Definition: XrdOssCsiRanges.hh:145