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;
}
}