casa
$Rev:20696$
|
00001 //# LatticeLocker.h: Class to hold a (user) lock on a lattice 00002 //# Copyright (C) 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: LatticeLocker.h 18093 2004-11-30 17:51:10Z ddebonis $ 00027 00028 #ifndef LATTICES_LATTICELOCKER_H 00029 #define LATTICES_LATTICELOCKER_H 00030 00031 00032 //# Includes 00033 #include <lattices/Lattices/LatticeBase.h> 00034 #include <tables/Tables/TableLock.h> 00035 00036 00037 namespace casa { //# NAMESPACE CASA - BEGIN 00038 00039 // <summary> 00040 // Class to hold a (user) lock on a lattice. 00041 // </summary> 00042 00043 // <use visibility=export> 00044 00045 // <reviewed reviewer="" date="" tests="tTableLockSync.cc"> 00046 // </reviewed> 00047 00048 // <prerequisite> 00049 //# Classes you should understand before using this one. 00050 // <li> <linkto class=Lattice>Lattice</linkto> 00051 // <li> <linkto class=TableLock>TableLock</linkto> 00052 // </prerequisite> 00053 00054 // <synopsis> 00055 // Class LatticeLocker can be used to acquire a (user) lock on a lattice. 00056 // The lock can be a read or write lock. 00057 // The destructor releases the lock when needed. 00058 // <p> 00059 // LatticeLocker simply uses the <src>lock</src> and <src>unlock</src> 00060 // function of class Lattice. 00061 // The advantage of LatticeLocker over these functions is that the 00062 // destructor of LatticeLocker is called automatically by the system, 00063 // so unlocking the lattice does not need to be done explicitly and 00064 // cannot be forgotten. Especially in case of exception handling this 00065 // can be quite an adavantage. 00066 // <p> 00067 // This class is meant to be used with the UserLocking option. 00068 // It can, however, also be used with the other locking options. 00069 // In case of PermanentLocking(Wait) it won't do anything at all. 00070 // In case of AutoLocking it will acquire and release the lock when 00071 // needed. However, it is possible that the system releases an 00072 // auto lock before the LatticeLocker destructor is called. 00073 // <p> 00074 // The constructor of LatticeLocker will look if the lattice is 00075 // already appropriately locked. If so, it will set a flag to 00076 // prevent the destructor from unlocking the lattice. In this way 00077 // nested locks can be used. I.e. one can safely use LatticeLocker 00078 // in a function without having to be afraid that its destructor 00079 // would undo a lock set in a higher function. 00080 // <br>Similarly LatticeLocker will remember if a lattice was 00081 // already read-locked, when a write-lock is acquired. In such a 00082 // case the destructor will try to ensure that the lattice remains 00083 // read-locked. 00084 // </synopsis> 00085 00086 // <example> 00087 // <srcblock> 00088 // // Open a lattice to be updated. 00089 // PagedArray<Float> myLattice (Table ("theLattice", 00090 // LatticeLock::UserLocking, 00091 // Lattice::Update); 00092 // // Start of some critical section requiring a lock. 00093 // { 00094 // LatticeLocker lock1 (myLattice, FileLocker::Write); 00095 // ... write the data 00096 // } 00097 // // The LatticeLocker destructor invoked by } unlocks the table. 00098 // </srcblock> 00099 // </example> 00100 00101 // <motivation> 00102 // LatticeLocker makes it easier to unlock a lattice. 00103 // It also makes it easier to use locking in a nested way. 00104 // </motivation> 00105 00106 //# <todo asof="$DATE:$"> 00107 //# A List of bugs, limitations, extensions or planned refinements. 00108 //# </todo> 00109 00110 00111 class LatticeLocker 00112 { 00113 public: 00114 // The constructor acquires a read or write lock on a lattice. 00115 // If the lattice was already locked, the destructor will 00116 // not unlock the lattice. This means that the class can be used in 00117 // a nested way. 00118 // <br> 00119 // The number of attempts (default = forever) can be specified when 00120 // acquiring the lock does not succeed immediately. When nattempts>1, 00121 // the system waits 1 second between each attempt, so nattempts 00122 // is more or less equal to a wait period in seconds. 00123 // An exception is thrown when the lock cannot be acquired. 00124 explicit LatticeLocker (LatticeBase& lattice, 00125 FileLocker::LockType, 00126 uInt nattempts = 0); 00127 00128 // If the constructor acquired the lock, the destructor releases 00129 // the lock and flushes the data if changed. 00130 ~LatticeLocker(); 00131 00132 // Has this process the read or write lock, thus can the table 00133 // be read or written safely? 00134 Bool hasLock (FileLocker::LockType) const; 00135 00136 private: 00137 // The copy constructor and assignment are not possible. 00138 // Note that only one lock can be held on a lattice, so copying a 00139 // TableLocker object imposes great difficulties which object should 00140 // release the lock. 00141 // It can be solved by turning LatticeLocker into a handle class 00142 // with a reference counted body class. 00143 // However, that will only be done when the need arises. 00144 // <group> 00145 LatticeLocker (const LatticeLocker&); 00146 LatticeLocker& operator= (const LatticeLocker&); 00147 // </group> 00148 00149 //# Variables. 00150 LatticeBase* itsLatticePtr; 00151 Bool itsOwnLock; 00152 Bool itsHadReadLock; 00153 }; 00154 00155 00156 inline Bool LatticeLocker::hasLock (FileLocker::LockType type) const 00157 { 00158 return itsLatticePtr->hasLock (type); 00159 } 00160 00161 00162 00163 } //# NAMESPACE CASA - END 00164 00165 #endif