Boost logo

Boost Users :

Subject: [Boost-users] interprocess file_lock timed_lock not returning false after timeout
From: Claudio Bantaloukas (rockdreamer_at_[hidden])
Date: 2013-07-29 16:37:07


Hi all!
I think there are two issues, one is a documentation issue, the other might
be a bug with boost::interprocess file_lock.

The documentation issue is that it was not clear to me by reading the
documentation on file_lock that it is a RAII-style class. By reading that
it has process lifetime, I assumed that once acquired, the lock would be
held even after the file_lock object is destroyed.

Once I figured this out, I changed the file_lock to a static method
variable and ran into the following issue.

I have two processes that use the following class method that I wrote.
They both try to acquire a lock on the same file and the lock must be held
until the process exits.

When I start the first process, it acquires the lock correctly.
When I start up the second process, I would expect the following code to
return false after 10 seconds
////
static boost::interprocess::file_lock
process_flock(processLockFile.string().c_str());
if (!process_flock.timed_lock(wait_until)){
////

However, when I read through the logs, I see that the process reaches the
timed_lock call and gets stuck there. Can you please help me diagnose this?

I'm attaching the entire method with log lines treated for brevity.
Boost version is 1.53, running on Centos 6.

Thanks!
------------------------8<--------------
ReturnStatus ProcessLocker::lockViaFile()
{
L_CONTEXT("ProcessLocker::lockViaFile()");
path lockDirectory(lockFileDirectoryName);
if (!exists(lockDirectory)){
L_ERROR("missing lock directory");
return r_error;
}
if (!is_directory(lockDirectory)){
L_ERROR("lock path is not a directory");
return r_error;
}

path globalLockFile = lockDirectory / "general-locking.lock";

// make sure file exists
boost::filesystem::ofstream globalfile(globalLockFile, std::ios::out);
// we do nothing with it...
globalfile.close();

std::string filename;
// class member, this is the process identifier, and is the same between
invocations
filename.append(identifier);

filename.append(".lock");

path processLockFile = lockDirectory / filename;
// make sure file exists
boost::filesystem::ofstream processfile(processLockFile, std::ios::out);
// we do nothing with it...
processfile.close();

try {
ptime now(second_clock::local_time());
ptime wait_until = now +seconds(10);
L_DEBUG("Waiting for global lock until " << wait_until);
boost::interprocess::file_lock
global_flock(globalLockFile.string().c_str());
if (!global_flock.timed_lock(wait_until)){
L_ERROR("Cannot create global lock");
return r_error;
}

try {
L_DEBUG("Waiting for process lock until " << wait_until);
static boost::interprocess::file_lock
process_flock(processLockFile.string().c_str());
if (!process_flock.timed_lock(wait_until)){
global_flock.unlock();
// this point is never reached!?
L_ERROR("Cannot create process lock");
return r_error;
}
global_flock.unlock();
L_DEBUG("Obtained process lock, freeing global lock");
return r_ok;
} catch (std::exception& e){
global_flock.unlock();
L_ERROR("Cannot create process lock, freeing global lock");
return r_error;
}

} catch (std::exception& e){
L_ERROR("Cannot create global lock");
return r_error;
}
}

-- 
Claudio Bantaloukas


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net