Belle II Software development
FileSystem::Lock Class Reference

Helper class for locking a file. More...

#include <FileSystem.h>

Public Member Functions

 Lock (const std::string &fileName, bool readonly=false)
 Construct a Lock object for the given file.
 
 ~Lock ()
 Destructor.
 
bool lock (int timeout=300, bool ignoreErrors=false)
 Try to lock the file.
 

Private Attributes

int m_file
 File descriptor of file to be locked.
 
bool m_readOnly
 if this is a read-only lock (multiple processes can hold one).
 

Detailed Description

Helper class for locking a file.

Definition at line 97 of file FileSystem.h.

Constructor & Destructor Documentation

◆ Lock()

Lock ( const std::string & fileName,
bool readonly = false )
explicit

Construct a Lock object for the given file.

Parameters
fileNameName of the file to be locked (if it does not exist, it will be created)
readonlycreate a read-only lock (multiple processes can hold one)

Definition at line 178 of file FileSystem.cc.

178 :
179 m_readOnly(readonly)
180{
181 const int mode = readonly ? O_RDONLY : O_RDWR;
182 m_file = open(fileName.c_str(), mode | O_CREAT, 0640);
183}
bool m_readOnly
if this is a read-only lock (multiple processes can hold one).
Definition FileSystem.h:124
int m_file
File descriptor of file to be locked.
Definition FileSystem.h:123

◆ ~Lock()

~Lock ( )

Destructor.

Releases the lock

Definition at line 185 of file FileSystem.cc.

186{
187 if (m_file >= 0) close(m_file);
188}

Member Function Documentation

◆ lock()

bool lock ( int timeout = 300,
bool ignoreErrors = false )

Try to lock the file.

Note
Locks are not exclusive inside the same process, i.e. lock() will succeed even if a lock is already held by the current process.
Parameters
timeoutTime in seconds to wait for a lock (default is rather high to deal with slow FS at KEKCC)
ignoreErrorsif true just return if locking was unsuccessful but don't print an error
Returns
True if the lock could be obtained, false if file could not be opened or timeout is reached

Definition at line 190 of file FileSystem.cc.

191{
192 if (m_file < 0) return false;
193
194 auto const maxtime = std::chrono::steady_clock::now() + std::chrono::seconds(timeout);
195 std::default_random_engine random;
196 std::uniform_int_distribution<int> uniform(1, 100);
197
198 /* Note:
199 * Previously, this used flock(), which doesn't work with GPFS.
200 * fcntl() does, and also should be more likely to work on NFS.
201 * If you use the 'nolock' mount option to NFS, you are on your own.
202 */
203 struct flock fl;
204 memset(&fl, '\0', sizeof(fl));
205 fl.l_type = m_readOnly ? F_RDLCK : F_WRLCK;
206 //lock entire file
207 fl.l_whence = SEEK_SET;
208 fl.l_start = 0;
209 fl.l_len = 0;
210
211 while (true) {
212 int lock = fcntl(m_file, F_SETLK, &fl);
213 if (lock == 0)
214 return true;
215 else if (std::chrono::steady_clock::now() > maxtime)
216 break;
217 if (errno != EAGAIN && errno != EACCES && errno != EINTR) break;
218 usleep(uniform(random) * 1000);
219 }
220 if (!ignoreErrors) B2ERROR("Locking failed: " << strerror(errno));
221 return false;
222}
bool lock(int timeout=300, bool ignoreErrors=false)
Try to lock the file.

Member Data Documentation

◆ m_file

int m_file
private

File descriptor of file to be locked.

Definition at line 123 of file FileSystem.h.

◆ m_readOnly

bool m_readOnly
private

if this is a read-only lock (multiple processes can hold one).

Definition at line 124 of file FileSystem.h.


The documentation for this class was generated from the following files: