casa
$Rev:20696$
|
00001 //# FileLocker.h: Class to handle file locking 00002 //# Copyright (C) 1997,1998,1999,2000 00003 //# Associated Universities, Inc. Washington DC, USA. 00004 //# 00005 //# This library is free software; you can redistribute it and/or modify it 00006 //# under the terms of the GNU Library General Public License as published by 00007 //# the Free Software Foundation; either version 2 of the License, or (at your 00008 //# option) any later version. 00009 //# 00010 //# This library is distributed in the hope that it will be useful, but WITHOUT 00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00012 //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00013 //# License for more details. 00014 //# 00015 //# You should have received a copy of the GNU Library General Public License 00016 //# along with this library; if not, write to the Free Software Foundation, 00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. 00018 //# 00019 //# Correspondence concerning AIPS++ should be addressed as follows: 00020 //# Internet email: aips2-request@nrao.edu. 00021 //# Postal address: AIPS++ Project Office 00022 //# National Radio Astronomy Observatory 00023 //# 520 Edgemont Road 00024 //# Charlottesville, VA 22903-2475 USA 00025 //# 00026 //# $Id: FileLocker.h 20551 2009-03-25 00:11:33Z Malte.Marquarding $ 00027 00028 #ifndef CASA_FILELOCKER_H 00029 #define CASA_FILELOCKER_H 00030 00031 00032 //# Includes 00033 #include <casa/aips.h> 00034 00035 namespace casa { //# NAMESPACE CASA - BEGIN 00036 00037 //# Forward Declarations 00038 class String; 00039 00040 00041 // <summary> 00042 // Class to handle file locking. 00043 // </summary> 00044 00045 // <use visibility=export> 00046 00047 // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="tLockFile" demos=""> 00048 // </reviewed> 00049 00050 // <prerequisite> 00051 // <li> man page of fcntl 00052 // </prerequisite> 00053 00054 // <synopsis> 00055 // This class handles file locking by means of the fcntl SETLK function. 00056 // Locking of files on NFS-mounted file systems works correctly 00057 // as long as the NFS lockd and statd deamons are configured correctly. 00058 // Otherwise lock requests may be granted incorrectly. 00059 // <p> 00060 // Acquiring a lock can be done for a read or a write lock. 00061 // Multiple locks on a file can exist as long as they are all 00062 // read locks. When a write lock is involved, no other lock can exist. 00063 // It is possible to acquire a lock in 2 ways: 00064 // <ul> 00065 // <li>Wait until the lock request is granted; i.e. until the processes 00066 // holding a lock on the file release their lock. 00067 // <li>Do several attempts; between each attempt it sleeps 1 second. 00068 // Note that nattempts=1 means it returns immediately when the 00069 // lock request could not be granted. 00070 // </ul> 00071 // </synopsis> 00072 00073 // <example> 00074 // <srcblock> 00075 // int fd = open ("file.name"); 00076 // FileLocker lock(fd); 00077 // if (lock.acquire()) { 00078 // ... do something with the file ... 00079 // lock.release(); 00080 // }else{ 00081 // cout << lock.lastMessage() << endl; 00082 // } 00083 // </srcblock> 00084 // </example> 00085 00086 // <motivation> 00087 // Make it possible to lock files in a standard way. 00088 // </motivation> 00089 00090 00091 class FileLocker 00092 { 00093 public: 00094 // Define the possible lock types. 00095 enum LockType { 00096 // Acquire a read lock. 00097 Read, 00098 // Acquire a write lock. 00099 Write 00100 }; 00101 00102 // Default constructor creates an invalid fd. 00103 FileLocker(); 00104 00105 // Construct the FileLocker object for the given file descriptor. 00106 // This can be used to lock a segment of the given file. 00107 // The segment is given by start and length. Length=0 means till the 00108 // end of the file. 00109 explicit FileLocker (int fd, uInt start=0, uInt length=0); 00110 00111 ~FileLocker(); 00112 00113 // Acquire a write or read lock. 00114 // <src>nattempts</src> defines how often it tries to acquire the lock. 00115 // A zero value indicates an infinite number of times (i.e. wait until 00116 // the lock is acquired). 00117 // A positive value means it waits 1 second between each attempt. 00118 Bool acquire (LockType = Write, uInt nattempts = 0); 00119 00120 // Release a lock. 00121 // The return status indicates if an error occurred. 00122 Bool release(); 00123 00124 // Test if the file can be locked for read or write. 00125 // Optionally the PID of the process holding the lock is returned. 00126 // <group> 00127 Bool canLock (LockType = Write); 00128 Bool canLock (uInt& pid, LockType = Write); 00129 // </group> 00130 00131 // Test if the process has a lock for read or write on the file. 00132 Bool hasLock (LockType = Write) const; 00133 00134 // Get the fd in use. 00135 int fd() const; 00136 00137 // Get the last error. 00138 int lastError() const; 00139 00140 // Get the message belonging to the last error. 00141 String lastMessage() const; 00142 00143 private: 00144 int itsFD; 00145 int itsError; 00146 int itsStart; 00147 int itsLength; 00148 Bool itsMsgShown; 00149 Bool itsReadLocked; 00150 Bool itsWriteLocked; 00151 }; 00152 00153 00154 inline Bool FileLocker::hasLock (LockType type) const 00155 { 00156 return (type == Write ? itsWriteLocked : itsReadLocked); 00157 } 00158 inline int FileLocker::fd() const 00159 { 00160 return itsFD; 00161 } 00162 inline int FileLocker::lastError() const 00163 { 00164 return itsError; 00165 } 00166 00167 00168 00169 } //# NAMESPACE CASA - END 00170 00171 #endif 00172