Boost logo

Boost Users :

Subject: Re: [Boost-users] interprocess file_lock timed_lock not returning false after timeout
From: Claudio Bantaloukas (rockdreamer_at_[hidden])
Date: 2013-07-30 09:19:12


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_at_[hidden]
> 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/


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