XRootD
XrdCmsMeter Class Reference

#include <XrdCmsMeter.hh>

+ Inheritance diagram for XrdCmsMeter:
+ Collaboration diagram for XrdCmsMeter:

Public Types

enum  vType {
  manFS = 1 ,
  peerFS = 2
}
 

Public Member Functions

 XrdCmsMeter ()
 
 ~XrdCmsMeter ()
 
int calcLoad (int xload, uint32_t pdsk)
 
int calcLoad (uint32_t pcpu, uint32_t pio, uint32_t pload, uint32_t pmem, uint32_t ppag)
 
int FreeSpace (int &tutil)
 
void Init ()
 
int isOn ()
 
int Monitor (char *pgm, int itv)
 
int Monitor (int itv)
 
int numFS ()
 
void PutInfo (XrdCmsPerfMon::PerfInfo &perfInfo, bool alert=false)
 
void Record (int pcpu, int pnet, int pxeq, int pmem, int ppag, int pdsk)
 
int Report (int &pcpu, int &pnet, int &pxeq, int &pmem, int &ppag, int &pdsk)
 
void * Run ()
 
void * RunFS ()
 
void * RunPM ()
 
void setVirtual (vType vVal)
 
void setVirtUpdt ()
 
unsigned int TotalSpace (unsigned int &minfree)
 
bool Update (char *line, bool alert=false)
 
- Public Member Functions inherited from XrdCmsPerfMon
 XrdCmsPerfMon ()
 Constructor & Destructor. More...
 
virtual ~XrdCmsPerfMon ()
 
virtual bool Configure (const char *cfn, char *Parms, XrdSysLogger &Logger, XrdCmsPerfMon &cmsMon, XrdOucEnv *EnvInfo, bool isCMS)
 
virtual void GetInfo (PerfInfo &info)
 

Detailed Description

Definition at line 38 of file XrdCmsMeter.hh.

Member Enumeration Documentation

◆ vType

Enumerator
manFS 
peerFS 

Definition at line 74 of file XrdCmsMeter.hh.

74 {manFS = 1, peerFS = 2};

Constructor & Destructor Documentation

◆ XrdCmsMeter()

XrdCmsMeter::XrdCmsMeter ( )

Definition at line 86 of file XrdCmsMeter.cc.

86  : myMeter(&Say)
87 {
88  Running = 0;
89  dsk_calc = 0;
90  fs_nums = 0;
91  noSpace = 0;
92  MinFree = 0;
93  HWMFree = 0;
94  dsk_lpn = 0;
95  dsk_tot = 0;
96  dsk_free = 0;
97  dsk_maxf = 0;
98  lastFree = 0;
99  lastUtil = 0;
100  monpgm = 0;
101  monPerf = 0;
102  monint = 0;
103  montid = 0;
104  rep_tod = time(0);
105  xeq_load = 0;
106  cpu_load = 0;
107  mem_load = 0;
108  pag_load = 0;
109  net_load = 0;
110  myLoad = 0;
111  prevLoad = -1;
112  Virtual = 0;
113  VirtUpdt = 1;
114 }
XrdSysError Say

◆ ~XrdCmsMeter()

XrdCmsMeter::~XrdCmsMeter ( )

Definition at line 120 of file XrdCmsMeter.cc.

121 {
122  if (monpgm) free(monpgm);
123  if (montid) XrdSysThread::Kill(montid);
124 }
static int Kill(pthread_t tid)

References XrdSysThread::Kill().

+ Here is the call graph for this function:

Member Function Documentation

◆ calcLoad() [1/2]

int XrdCmsMeter::calcLoad ( int  xload,
uint32_t  pdsk 
)

Definition at line 148 of file XrdCmsMeter.cc.

149 {
150  if (pdsk > 100) pdsk = 100;
151  return (Config.P_dsk * pdsk /100) + nowload;
152 }
XrdCmsConfig Config

References XrdCms::Config, and XrdCmsConfig::P_dsk.

◆ calcLoad() [2/2]

int XrdCmsMeter::calcLoad ( uint32_t  pcpu,
uint32_t  pio,
uint32_t  pload,
uint32_t  pmem,
uint32_t  ppag 
)

Definition at line 130 of file XrdCmsMeter.cc.

132 {
133  if (pcpu > 100) pcpu = 100;
134  if (pio > 100) pio = 100;
135  if (pload > 100) pload = 100;
136  if (pmem > 100) pmem = 100;
137  if (ppag > 100) ppag = 100;
138 
139  return (Config.P_cpu * pcpu /100)
140  + (Config.P_io * pio /100)
141  + (Config.P_load * pload/100)
142  + (Config.P_mem * pmem /100)
143  + (Config.P_pag * ppag /100);
144 }

References XrdCms::Config, XrdCmsConfig::P_cpu, XrdCmsConfig::P_io, XrdCmsConfig::P_load, XrdCmsConfig::P_mem, and XrdCmsConfig::P_pag.

Referenced by XrdCmsNode::do_Load(), PutInfo(), and Update().

+ Here is the caller graph for this function:

◆ FreeSpace()

int XrdCmsMeter::FreeSpace ( int &  tutil)

Definition at line 158 of file XrdCmsMeter.cc.

159 {
160  long long fsavail;
161 
162 // If we are a virtual filesystem, do virtual stats
163 //
164  if (Virtual)
165  {if (Virtual == peerFS) {tot_util = 0; return 0x7fffffff;}
166  if (VirtUpdt) UpdtSpace();
167  tot_util = lastUtil;
168  return lastFree;
169  }
170 
171 // The values are calculated periodically so use the last available ones
172 //
173  cfsMutex.Lock();
174  fsavail = dsk_maxf;
175  tot_util= dsk_util;
176  cfsMutex.UnLock();
177 
178 // Now adjust the values to fit
179 //
180  if (fsavail >> 31LL) fsavail = 0x7fffffff;
181 
182 // Return amount available
183 //
184  return static_cast<int>(fsavail);
185 }

References XrdSysMutex::Lock(), peerFS, and XrdSysMutex::UnLock().

Referenced by XrdCmsNode::do_Space(), and Report().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Init()

void XrdCmsMeter::Init ( )

Definition at line 191 of file XrdCmsMeter.cc.

192 {
193  XrdOssVSInfo vsInfo;
194  pthread_t monFStid;
195  char buff[1024], sfx1, sfx2, sfx3;
196  long maxfree, totfree, totDisk;
197  int rc;
198 
199 // Get initial free space
200 //
201  if ((rc = Config.ossFS->StatVS(&vsInfo, 0, 1)))
202  {Say.Emsg("Meter", rc, "calculate file system space");
203  noSpace = 1;
204  }
205  else if (!(fs_nums = vsInfo.Extents))
206  {Say.Emsg("Meter", "Warning! No writable filesystems found.");
207  noSpace = 1;
208  }
209  else {dsk_tot = vsInfo.Total >> 20LL; // in MB
210  dsk_lpn = vsInfo.Large >> 20LL;
211  }
212 
213 // Check if we should bother to continue
214 //
215  if (noSpace)
217  Say.Emsg("Meter", "Write access and staging prohibited.");
218  return;
219  }
220 
221 // Set values (disk space values are in megabytes)
222 //
223  if (Config.DiskMinP) MinFree = dsk_lpn * Config.DiskMinP / 100;
224  if (Config.DiskMin > MinFree) MinFree = Config.DiskMin;
225  MinStype= Scale(MinFree, MinShow);
226  if (Config.DiskHWMP) HWMFree = dsk_lpn * Config.DiskHWMP / 100;
227  if (Config.DiskHWM > HWMFree) HWMFree = Config.DiskHWM;
228  HWMStype= Scale(HWMFree, HWMShow);
229  dsk_calc = (Config.DiskAsk < 5 ? 5 : Config.DiskAsk);
230 
231 // Calculate the initial free space and start the FS monitor thread
232 //
233  calcSpace();
234  if ((noSpace = (dsk_maxf < MinFree)) && !Config.asSolo())
236  if ((rc = XrdSysThread::Run(&monFStid,MeterRunFS,(void *)this,0,"FS meter")))
237  Say.Emsg("Meter", rc, "start filesystem meter.");
238 
239 // Document what we have
240 //
241  sfx1 = Scale(dsk_maxf, maxfree);
242  sfx2 = Scale(dsk_tot, totDisk);
243  sfx3 = Scale(dsk_free, totfree);
244  sprintf(buff,"Found %d filesystem(s); %ld%cB total (%d%% util);"
245  " %ld%cB free (%ld%cB max)", fs_nums, totDisk, sfx2,
246  dsk_util, totfree, sfx3, maxfree, sfx1);
247  Say.Emsg("Meter", buff);
248  if (noSpace)
249  {sprintf(buff, "%ld%cB minimum", MinShow, MinStype);
250  Say.Emsg("Meter", "Warning! Available space <", buff);
251  }
252 }
XrdOss * ossFS
void Update(StateType StateT, int ActivVal, int StageVal=0)
Definition: XrdCmsState.cc:258
long long Large
Definition: XrdOssVS.hh:92
long long Total
Definition: XrdOssVS.hh:90
virtual int StatVS(XrdOssVSInfo *vsP, const char *sname=0, int updt=0)
Definition: XrdOss.cc:117
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
XrdCmsState CmsState
Definition: XrdCmsState.cc:55

References XrdCmsConfig::asSolo(), XrdCms::CmsState, XrdCms::Config, XrdCmsConfig::DiskAsk, XrdCmsConfig::DiskHWM, XrdCmsConfig::DiskHWMP, XrdCmsConfig::DiskMin, XrdCmsConfig::DiskMinP, XrdSysError::Emsg(), XrdOssVSInfo::Extents, XrdOssVSInfo::Large, XrdCmsConfig::ossFS, XrdSysThread::Run(), XrdCms::Say, XrdCmsState::Space, XrdOss::StatVS(), XrdOssVSInfo::Total, and XrdCmsState::Update().

+ Here is the call graph for this function:

◆ isOn()

int XrdCmsMeter::isOn ( )
inline

Definition at line 51 of file XrdCmsMeter.hh.

51 {return Running;}

◆ Monitor() [1/2]

int XrdCmsMeter::Monitor ( char *  pgm,
int  itv 
)

Definition at line 258 of file XrdCmsMeter.cc.

259 {
260  char *mp, pp;
261  int rc;
262 
263 // Isolate the program name
264 //
265  mp = monpgm = strdup(pgm);
266  while(*mp && *mp != ' ') mp++;
267  pp = *mp; *mp ='\0';
268 
269 // Make sure the program is executable by us
270 //
271  if (access(monpgm, X_OK))
272  {Say.Emsg("Meter", errno, "find executable", monpgm);
273  return -1;
274  }
275 
276 // Start up the program. We don't really need to serialize Restart() because
277 // Monitor() is a one-time call (otherwise unpredictable results may occur).
278 //
279  *mp = pp; monint = itv;
280  if ((rc = XrdSysThread::Run(&montid,MeterRun,(void *)this,0,"Perf meter")))
281  Say.Emsg("Meter", rc, "start performance meter.");
282  Running = 1;
283  return 0;
284 }
int access(const char *path, int amode)

References access(), XrdSysError::Emsg(), XrdSysThread::Run(), and XrdCms::Say.

+ Here is the call graph for this function:

◆ Monitor() [2/2]

int XrdCmsMeter::Monitor ( int  itv)

Definition at line 288 of file XrdCmsMeter.cc.

289 {
290  XrdCmsPerfMon *monPerf;
291  int rc;
292 
293 // Load the plugin
294 //
296 
297 // Configure it if loaded.
298 //
299  if (!monPerf || !monPerf->Configure(Config.ConfigFN, Config.prfParms,
300  *(Say.logger()), *this, 0, true))
301  {Say.Emsg("Meter", "Unable to configure performance monitor plugin.");
302  return -1;
303  }
304 
305 // Start the monitor thread for this plugin unless strictly async
306 // reporting is wanted (i.e. the interval is zero).
307 //
308  if (monint)
309  {if ((rc = XrdSysThread::Run(&montid,MeterRunPM,(void *)this,0,"Perf monitor")))
310  {Say.Emsg("Meter", rc, "start performance meter.");
311  return -1;
312  }
313  }
314 
315  montid = 0;
316  Running = 1;
317  return 0;
318 }
XrdVersionInfo * myVInfo
virtual bool Configure(const char *cfn, char *Parms, XrdSysLogger &Logger, XrdCmsPerfMon &cmsMon, XrdOucEnv *EnvInfo, bool isCMS)
static XrdCmsPerfMon * loadPerfMon(XrdSysError *eDest, const char *libPath, XrdVersionInfo &urVer)
Load the performance monitor plugin.
Definition: XrdCmsUtils.cc:108
XrdSysLogger * logger(XrdSysLogger *lp=0)
Definition: XrdSysError.hh:141

References XrdCms::Config, XrdCmsConfig::ConfigFN, XrdCmsPerfMon::Configure(), XrdSysError::Emsg(), XrdCmsUtils::loadPerfMon(), XrdSysError::logger(), XrdCmsConfig::myVInfo, XrdCmsConfig::prfLib, XrdCmsConfig::prfParms, XrdSysThread::Run(), and XrdCms::Say.

+ Here is the call graph for this function:

◆ numFS()

int XrdCmsMeter::numFS ( )
inline

Definition at line 70 of file XrdCmsMeter.hh.

70 {return fs_nums;}

◆ PutInfo()

void XrdCmsMeter::PutInfo ( XrdCmsPerfMon::PerfInfo info,
bool  alert = false 
)
virtual

Report performance statistics as load values from 0 to 100. The performance monitor plugin may call this method to asynchronously report performance via the passed XrdCmsPerfMon object during configuration.

Parameters
infoReference to the structure that should be filled out with load values. See the PerfInfo structure.
alertWhen true, load information is forcibly sent to the cluster's manager. Otherwise, it is only sent if it significantly changes. See the cms.sched directive fuzz parameter.

Reimplemented from XrdCmsPerfMon.

Definition at line 324 of file XrdCmsMeter.cc.

325 {
326 
327  repMutex.Lock();
328  cpu_load = (perfInfo.cpu_load <= 100 ? perfInfo.cpu_load : 100);
329  mem_load = (perfInfo.mem_load <= 100 ? perfInfo.mem_load : 100);
330  net_load = (perfInfo.net_load <= 100 ? perfInfo.net_load : 100);
331  pag_load = (perfInfo.pag_load <= 100 ? perfInfo.pag_load : 100);
332  xeq_load = (perfInfo.xeq_load <= 100 ? perfInfo.xeq_load : 100);
333 
334  myLoad = calcLoad(cpu_load,net_load,xeq_load,mem_load,pag_load);
335 
336  if (prevLoad >= 0)
337  {prevLoad = prevLoad - myLoad;
338  if (prevLoad < 0) prevLoad = -prevLoad;
339  if (prevLoad > Config.P_fuzz) alert = true;
340  }
341  prevLoad = myLoad;
342  repMutex.UnLock();
343 
344  if (alert) XrdCmsNode::Report_Usage(0);
345 }
int calcLoad(uint32_t pcpu, uint32_t pio, uint32_t pload, uint32_t pmem, uint32_t ppag)
Definition: XrdCmsMeter.cc:130
static void Report_Usage(XrdLink *lp)
Definition: XrdCmsNode.cc:1752

References calcLoad(), XrdCms::Config, XrdCmsPerfMon::PerfInfo::cpu_load, XrdSysMutex::Lock(), XrdCmsPerfMon::PerfInfo::mem_load, XrdCmsPerfMon::PerfInfo::net_load, XrdCmsConfig::P_fuzz, XrdCmsPerfMon::PerfInfo::pag_load, XrdCmsNode::Report_Usage(), XrdSysMutex::UnLock(), and XrdCmsPerfMon::PerfInfo::xeq_load.

Referenced by RunPM().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Record()

void XrdCmsMeter::Record ( int  pcpu,
int  pnet,
int  pxeq,
int  pmem,
int  ppag,
int  pdsk 
)

Definition at line 351 of file XrdCmsMeter.cc.

353 {
354  int temp;
355 
356  repMutex.Lock();
357  temp = cpu_load + cpu_load/2;
358  cpu_load = (cpu_load + (pcpu > temp ? temp : pcpu))/2;
359  temp = net_load + net_load/2;
360  net_load = (net_load + (pnet > temp ? temp : pnet))/2;
361  temp = xeq_load + xeq_load/2;
362  xeq_load = (xeq_load + (pxeq > temp ? temp : pxeq))/2;
363  temp = mem_load + mem_load/2;
364  mem_load = (mem_load + (pmem > temp ? temp : pmem))/2;
365  temp = pag_load + pag_load/2;
366  pag_load = (pag_load + (ppag > temp ? temp : ppag))/2;
367  repMutex.UnLock();
368 }

References XrdSysMutex::Lock(), and XrdSysMutex::UnLock().

Referenced by XrdCmsNode::do_Load().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Report()

int XrdCmsMeter::Report ( int &  pcpu,
int &  pnet,
int &  pxeq,
int &  pmem,
int &  ppag,
int &  pdsk 
)

Definition at line 374 of file XrdCmsMeter.cc.

376 {
377  int maxfree;
378 
379 // Force restart the monitor program if it hasn't reported within 2 intervals
380 //
381  if (!Virtual && montid && (time(0) - rep_tod > monint*2)) myMeter.Drain();
382 
383 // Format a usage line
384 //
385  repMutex.Lock();
386  maxfree = FreeSpace(pdsk);
387  if (!Running && !Virtual) pcpu = pnet = pmem = ppag = pxeq = 0;
388  else {pcpu = cpu_load; pnet = net_load; pmem = mem_load;
389  ppag = pag_load; pxeq = xeq_load;
390  }
391  repMutex.UnLock();
392 
393 // All done
394 //
395  return maxfree;
396 }
int FreeSpace(int &tutil)
Definition: XrdCmsMeter.cc:158

References XrdOucStream::Drain(), FreeSpace(), XrdSysMutex::Lock(), and XrdSysMutex::UnLock().

Referenced by XrdCmsNode::Report_Usage().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Run()

void * XrdCmsMeter::Run ( )

Definition at line 402 of file XrdCmsMeter.cc.

403 {
404  static const int snoozeTime = 30;
405  char *lp = 0;
406 
407 // Execute the program (keep restarting and keep reading the output)
408 //
409  while(1)
410  {if (myMeter.Exec(monpgm) == 0)
411  while((lp = myMeter.GetLine()) && Update(lp)) {}
412  if (lp) Say.Emsg("Meter","Perf monitor returned invalid output:",lp);
413  else Say.Emsg("Meter","Perf monitor died.");
414  XrdSysTimer::Snooze(snoozeTime);
415  Say.Emsg("Meter", "Restarting monitor:", monpgm);
416  }
417  return (void *)0;
418 }
bool Update(char *line, bool alert=false)
Definition: XrdCmsMeter.cc:502
char * GetLine()
int Exec(const char *, int inrd=0, int efd=0)
static void Snooze(int seconds)
Definition: XrdSysTimer.cc:168

References XrdSysError::Emsg(), XrdOucStream::Exec(), XrdOucStream::GetLine(), XrdCms::Say, XrdSysTimer::Snooze(), and Update().

+ Here is the call graph for this function:

◆ RunFS()

void * XrdCmsMeter::RunFS ( )

Definition at line 424 of file XrdCmsMeter.cc.

425 {
426  const struct timespec rqtp = {dsk_calc, 0};
427  int noNewSpace;
428  int mlim = 60/dsk_calc, nowlim = 0;
429 
430  while(1)
431  {nanosleep(&rqtp, 0);
432  calcSpace();
433  noNewSpace = dsk_maxf < (noSpace ? HWMFree : MinFree);
434  if (noSpace != noNewSpace)
435  {SpaceMsg(noNewSpace);
436  noSpace = noNewSpace;
437  if (!Config.asSolo()) CmsState.Update(XrdCmsState::Space,!noSpace);
438  }
439  else if (noSpace && !nowlim) SpaceMsg(noNewSpace);
440  nowlim = (nowlim ? nowlim-1 : mlim);
441  }
442  return (void *)0;
443 }

References XrdCmsConfig::asSolo(), XrdCms::CmsState, XrdCms::Config, XrdCmsState::Space, and XrdCmsState::Update().

+ Here is the call graph for this function:

◆ RunPM()

void * XrdCmsMeter::RunPM ( )

Definition at line 449 of file XrdCmsMeter.cc.

450 {
451  XrdCmsPerfMon::PerfInfo perfInfo;
452 
453 // Keep asking the plugin for statistics.
454 //
455  while(1)
456  {monPerf->GetInfo(perfInfo);
457  PutInfo(perfInfo);
458  perfInfo.Clear();
459  XrdSysTimer::Snooze(monint);
460  }
461  return (void *)0;
462 }
void PutInfo(XrdCmsPerfMon::PerfInfo &perfInfo, bool alert=false)
Definition: XrdCmsMeter.cc:324
virtual void GetInfo(PerfInfo &info)
Structure used for reporting performance metrics.

References XrdCmsPerfMon::PerfInfo::Clear(), XrdCmsPerfMon::GetInfo(), PutInfo(), and XrdSysTimer::Snooze().

+ Here is the call graph for this function:

◆ setVirtual()

void XrdCmsMeter::setVirtual ( vType  vVal)
inline

Definition at line 76 of file XrdCmsMeter.hh.

76 {Virtual = vVal;}

Referenced by XrdCmsConfig::Configure2().

+ Here is the caller graph for this function:

◆ setVirtUpdt()

void XrdCmsMeter::setVirtUpdt ( )
inline

Definition at line 78 of file XrdCmsMeter.hh.

78 {cfsMutex.Lock(); VirtUpdt = 1; cfsMutex.UnLock();}

References XrdSysMutex::Lock(), and XrdSysMutex::UnLock().

Referenced by XrdCmsNode::do_Load().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ TotalSpace()

unsigned int XrdCmsMeter::TotalSpace ( unsigned int &  minfree)

Definition at line 468 of file XrdCmsMeter.cc.

469 {
470  long long fstotal, fsminfr;
471 
472 // If we are a virtual filesystem, do virtual stats
473 //
474  if (Virtual)
475  {if (Virtual == peerFS) {minfree = 0; return 0x7fffffff;}
476  if (VirtUpdt) UpdtSpace();
477  }
478 
479 // The values are calculated periodically so use the last available ones
480 //
481  cfsMutex.Lock();
482  fstotal = dsk_tot;
483  fsminfr = MinFree;
484  cfsMutex.UnLock();
485 
486 // Now adjust the values to fit
487 //
488  if (fsminfr >> 31LL) minfree = 0x7fffffff;
489  else minfree = static_cast<unsigned int>(fsminfr);
490  if (fstotal == 0) fstotal = 1;
491  else if (fstotal >> 31LL) fstotal = 0x7fffffff;
492 
493 // Return amount available
494 //
495  return static_cast<unsigned int>(fstotal);
496 }

References XrdSysMutex::Lock(), peerFS, and XrdSysMutex::UnLock().

+ Here is the call graph for this function:

◆ Update()

bool XrdCmsMeter::Update ( char *  line,
bool  alert = false 
)

Definition at line 502 of file XrdCmsMeter.cc.

503 {
504  int n;
505 
506 // Parse the information
507 //
508  repMutex.Lock();
509  n = sscanf(line, "%u %u %u %u %u",
510  &xeq_load, &cpu_load, &mem_load, &pag_load, &net_load);
511  rep_tod = time(0);
512 
513 // Make sure we have the correct number here
514 //
515  if (n != 5)
516  {repMutex.UnLock();
517  return false;
518  }
519 
520 // Calculate load and check if there has been a significant change.
521 //
522  myLoad = calcLoad(cpu_load,net_load,xeq_load,mem_load,pag_load);
523  if (prevLoad >= 0)
524  {prevLoad = prevLoad - myLoad;
525  if (prevLoad < 0) prevLoad = -prevLoad;
526  if (prevLoad > Config.P_fuzz) alert = true;
527  }
528  prevLoad = myLoad;
529  repMutex.UnLock();
530 
531 // Do an immediate performance update if needed
532 //
533  if (alert) XrdCmsNode::Report_Usage(0);
534  return true;
535 }

References calcLoad(), XrdCms::Config, XrdSysMutex::Lock(), XrdCmsConfig::P_fuzz, XrdCmsNode::Report_Usage(), and XrdSysMutex::UnLock().

Referenced by Run().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

The documentation for this class was generated from the following files: