Found the culprit, should have used second_clock::universal_time instead of second_clock::local_time


On Mon, Jul 29, 2013 at 10:37 PM, Claudio Bantaloukas <rockdreamer@gmail.com> wrote:
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



--
Claudio Bantaloukas http://www.rdfm.org/ammuzzu/