00001 /******************************************************************************/ 00002 /* */ 00003 /* X r d X r o o t d F i l e L o c k 1 . c c */ 00004 /* */ 00005 /* (c) 2004 by the Board of Trustees of the Leland Stanford, Jr., University */ 00006 /* All Rights Reserved. See XrdInfo.cc for complete License Terms */ 00007 /* Produced by Andrew Hanushevsky for Stanford University under contract */ 00008 /* DE-AC03-76-SFO0515 with the Department of Energy */ 00009 /******************************************************************************/ 00010 00011 // $Id: XrdXrootdFileLock1.cc 22437 2008-03-04 14:35:16Z rdm $ 00012 00013 const char *XrdXrootdFileLock1CVSID = "$Id: XrdXrootdFileLock1.cc 22437 2008-03-04 14:35:16Z rdm $"; 00014 00015 #include <stdlib.h> 00016 00017 #include "XrdOuc/XrdOucHash.hh" 00018 00019 #include "XrdXrootd/XrdXrootdFileLock1.hh" 00020 00021 /******************************************************************************/ 00022 /* L o c a l C l a s s e s */ 00023 /******************************************************************************/ 00024 00025 class XrdXrootdFileLockInfo 00026 { 00027 public: 00028 00029 int numReaders; 00030 int numWriters; 00031 00032 XrdXrootdFileLockInfo(char mode) 00033 {if ('r' == mode) {numReaders = 1; numWriters = 0;} 00034 else {numReaders = 0; numWriters = 1;} 00035 } 00036 ~XrdXrootdFileLockInfo() {} 00037 }; 00038 00039 class XrdXrootdLockFileLock 00040 { 00041 public: 00042 00043 XrdXrootdLockFileLock(XrdSysMutex *mutex) 00044 {mp = mutex; mp->Lock();} 00045 ~XrdXrootdLockFileLock() 00046 {mp->UnLock();} 00047 private: 00048 XrdSysMutex *mp; 00049 }; 00050 00051 /******************************************************************************/ 00052 /* G l o b a l s */ 00053 /******************************************************************************/ 00054 00055 XrdOucHash<XrdXrootdFileLockInfo> XrdXrootdLockTable; 00056 00057 XrdSysMutex XrdXrootdFileLock1::LTMutex; 00058 00059 const char *XrdXrootdFileLock1::TraceID = "FileLock1"; 00060 00061 /******************************************************************************/ 00062 /* L o c k */ 00063 /******************************************************************************/ 00064 00065 int XrdXrootdFileLock1::Lock(XrdXrootdFile *fp, int force) 00066 { 00067 XrdXrootdLockFileLock locker(<Mutex); 00068 XrdXrootdFileLockInfo *lp; 00069 00070 // See if we already have a lock on this file 00071 // 00072 if ((lp = XrdXrootdLockTable.Find(fp->FileKey))) 00073 {if (fp->FileMode == 'r') 00074 {if (lp->numWriters && !force) 00075 return -lp->numWriters; 00076 lp->numReaders++; 00077 } else { 00078 if ((lp->numReaders || lp->numWriters) && !force) 00079 return (lp->numWriters ? -lp->numWriters : lp->numReaders); 00080 lp->numWriters++; 00081 } 00082 return 0; 00083 } 00084 00085 // Item does not exist, add it to the table 00086 // 00087 XrdXrootdLockTable.Add(fp->FileKey, new XrdXrootdFileLockInfo(fp->FileMode)); 00088 return 0; 00089 } 00090 00091 /******************************************************************************/ 00092 /* */ 00093 /* n u m L o c k s */ 00094 /* */ 00095 /******************************************************************************/ 00096 00097 void XrdXrootdFileLock1::numLocks(XrdXrootdFile *fp, int &rcnt, int &wcnt) 00098 { 00099 XrdXrootdLockFileLock locker(<Mutex); 00100 XrdXrootdFileLockInfo *lp; 00101 00102 if (!(lp = XrdXrootdLockTable.Find(fp->FileKey))) rcnt = wcnt = 0; 00103 else {rcnt = lp->numReaders; wcnt = lp->numWriters;} 00104 } 00105 00106 /******************************************************************************/ 00107 /* U n l o c k */ 00108 /******************************************************************************/ 00109 00110 int XrdXrootdFileLock1::Unlock(XrdXrootdFile *fp) 00111 { 00112 XrdXrootdLockFileLock locker(<Mutex); 00113 XrdXrootdFileLockInfo *lp; 00114 00115 // See if we already have a lock on this file 00116 // 00117 if (!(lp = XrdXrootdLockTable.Find(fp->FileKey))) return 1; 00118 00119 // Adjust the lock information 00120 // 00121 if (fp->FileMode == 'r') 00122 {if (lp->numReaders == 0) return 1; 00123 lp->numReaders--; 00124 } else { 00125 if (lp->numWriters == 0) return 1; 00126 lp->numWriters--; 00127 } 00128 00129 // Delete the entry if we no longer need it 00130 // 00131 if (lp->numReaders == 0 && lp->numWriters == 0) 00132 XrdXrootdLockTable.Del(fp->FileKey); 00133 return 0; 00134 }