/******************************************************************************/
/* */
/* X r d X r o o t d F i l e L o c k 1 . c c */
/* */
/* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */
/* Produced by Andrew Hanushevsky for Stanford University under contract */
/* DE-AC02-76-SFO0515 with the Department of Energy */
/* */
/* This file is part of the XRootD software suite. */
/* */
/* XRootD is free software: you can redistribute it and/or modify it under */
/* the terms of the GNU Lesser General Public License as published by the */
/* Free Software Foundation, either version 3 of the License, or (at your */
/* option) any later version. */
/* */
/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
/* License for more details. */
/* */
/* You should have received a copy of the GNU Lesser General Public License */
/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
/* COPYING (GPL license). If not, see . */
/* */
/* The copyright holder's institutional names and contributor's names may not */
/* be used to endorse or promote products derived from this software without */
/* specific prior written permission of the institution or contributor. */
/******************************************************************************/
#include
#include "XrdOuc/XrdOucHash.hh"
#include "XrdXrootd/XrdXrootdFileLock1.hh"
/******************************************************************************/
/* L o c a l C l a s s e s */
/******************************************************************************/
class XrdXrootdFileLockInfo
{
public:
int numReaders;
int numWriters;
XrdXrootdFileLockInfo(char mode)
{if (mode == 'r') {numReaders = 1; numWriters = 0;}
else {numReaders = 0; numWriters = 1;}
}
~XrdXrootdFileLockInfo() {}
};
class XrdXrootdLockFileLock
{
public:
XrdXrootdLockFileLock(XrdSysMutex *mutex)
{mp = mutex; mp->Lock();}
~XrdXrootdLockFileLock()
{mp->UnLock();}
private:
XrdSysMutex *mp;
};
/******************************************************************************/
/* G l o b a l s */
/******************************************************************************/
XrdOucHash XrdXrootdLockTable;
XrdSysMutex XrdXrootdFileLock1::LTMutex;
const char *XrdXrootdFileLock1::TraceID = "FileLock1";
/******************************************************************************/
/* L o c k */
/******************************************************************************/
int XrdXrootdFileLock1::Lock(const char *path, char mode, bool force)
{
XrdXrootdLockFileLock locker(<Mutex);
XrdXrootdFileLockInfo *lp;
// See if we already have a lock on this file
//
if ((lp = XrdXrootdLockTable.Find(path)))
{if (mode == 'r')
{if (lp->numWriters && !force)
return -lp->numWriters;
lp->numReaders++;
} else {
if ((lp->numReaders || lp->numWriters) && !force)
return (lp->numWriters ? -lp->numWriters : lp->numReaders);
lp->numWriters++;
}
return 0;
}
// Item does not exist, add it to the table
//
XrdXrootdLockTable.Add(path, new XrdXrootdFileLockInfo(mode));
return 0;
}
/******************************************************************************/
/* */
/* n u m L o c k s */
/* */
/******************************************************************************/
void XrdXrootdFileLock1::numLocks(const char *path, int &rcnt, int &wcnt)
{
XrdXrootdLockFileLock locker(<Mutex);
XrdXrootdFileLockInfo *lp;
if (!(lp = XrdXrootdLockTable.Find(path))) rcnt = wcnt = 0;
else {rcnt = lp->numReaders; wcnt = lp->numWriters;}
}
/******************************************************************************/
/* U n l o c k */
/******************************************************************************/
int XrdXrootdFileLock1::Unlock(const char *path, char mode)
{
XrdXrootdLockFileLock locker(<Mutex);
XrdXrootdFileLockInfo *lp;
// See if we already have a lock on this file
//
if (!(lp = XrdXrootdLockTable.Find(path))) return 1;
// Adjust the lock information
//
if (mode == 'r')
{if (lp->numReaders == 0) return 1;
lp->numReaders--;
} else {
if (lp->numWriters == 0) return 1;
lp->numWriters--;
}
// Delete the entry if we no longer need it
//
if (lp->numReaders == 0 && lp->numWriters == 0)
XrdXrootdLockTable.Del(path);
return 0;
}