casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
FileLocker.h
Go to the documentation of this file.
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