bool CInterProcessLock::TryLock() { try { Lock(CTimeout(0,0)); } catch (CInterProcessLockException&) { return false; } return true; }
static int Test_MultiProcess_Child(int test, string lockname) { LOG_CHILD("started"); CInterProcessLock lock(lockname); switch (test) { case 1: // The lock already set in the parent process LOG_CHILD("try lock"); assert( !lock.TryLock() ); // Error acquire lock return IPCL_SUCCESS; case 2: // The lock already set in the parent process LOG_CHILD("try lock"); assert( !lock.TryLock() ); // It should be released soon, wait LOG_CHILD("lock in 3 sec"); lock.Lock(CTimeout(3,0)); LOG_CHILD("locked"); // Parent process should try to set lock in the next 3 seconds // (without success) SleepSec(3); // The lock should be removed automatically on normal termination return IPCL_SUCCESS; case 3: LOG_CHILD("lock"); lock.Lock(); LOG_CHILD("locked"); SleepSec(3); return IPCL_SUCCESS; case 4: LOG_CHILD("lock"); lock.Lock(/*infinite*/); LOG_CHILD("locked"); SleepSec(20); // Child process should be killed on this moment and lock released return 1; } // Unsuccessful exit code return 1; }
void CWaiter::ResetTimeout(const uint32 timeoutInMilliseconds) { m_timeout = CTimeout(timeoutInMilliseconds); }
static void Test_SingleProcess() { LOG_POST("=== Single-process test ==="); const CTimeout zero_timeout = CTimeout(0,0); LOG_POST("\n--- Test 1"); // Name test {{ try { CInterProcessLock lock(""); } catch (CInterProcessLockException&) {} try { CInterProcessLock lock("relative/path"); } catch (CInterProcessLockException&) {} {{ CInterProcessLock lock("name"); assert(lock.GetName() == "name"); #if defined(NCBI_OS_UNIX) assert(lock.GetSystemName() == "/var/tmp/name"); #elif defined(NCBI_OS_MSWIN) assert(lock.GetSystemName() == "name"); #endif }} }} // Fixed names are usually more appropriate, but here we don't // want independent tests to step on each other... string lockname = CFile::GetTmpName(); CInterProcessLock lock1(lockname); CInterProcessLock lock2(lockname); CInterProcessLock lock3(lockname); LOG_POST("lock name = " << lock1.GetName()); LOG_POST("lock system name = " << lock1.GetSystemName()); LOG_POST("\n--- Test 2"); // Direct CInterProcessLock usage {{ lock1.Lock(/*infinite*/); try { lock2.Lock(zero_timeout); assert(0); } catch (CInterProcessLockException&) {} assert( !lock2.TryLock() ); lock1.Unlock(); lock2.Lock(/*infinite*/); assert( !lock3.TryLock() ); lock2.Unlock(); lock1.Lock(zero_timeout); lock1.Remove(); // everything unlocked }} LOG_POST("\n--- Test 3"); // CGuard usage {{ {{ CGuard<CInterProcessLock> GUARD(lock1); try { lock2.Lock(zero_timeout); assert(0); } catch (CInterProcessLockException&) {} }} lock2.Lock(zero_timeout); lock2.Remove(); // everything unlocked }} LOG_POST("\n--- Test 4"); // Reference count test {{ assert( lock1.TryLock() ); assert( lock1.TryLock() ); assert( !lock2.TryLock() ); assert( lock1.TryLock() ); lock1.Unlock(); lock1.Unlock(); lock1.Unlock(); try { lock1.Unlock(); assert(0); } catch (CInterProcessLockException&) {} // everything unlocked }} // We don't need lock object anymore, remove it from the system lock1.Remove(); }
static void Test_MultiProcess() { LOG_POST("\n=== Multi-process tests ==="); const CTimeout zero_timeout = CTimeout(0,0); // Fixed names are usually more appropriate, but here we don't // want independent tests to step on each other.... string lockname = CFile::GetTmpName(); CInterProcessLock lock(lockname); LOG_POST("lock name = " << lock.GetName()); LOG_POST("lock system name = " << lock.GetSystemName()); string app = CNcbiApplication::Instance()->GetArguments().GetProgramName(); TProcessHandle handle; TExitCode exitcode; LOG_POST("\n--- Test 1"); // Set lock and start child process, that try to set lock also (unsuccessfully). {{ LOG_PARENT("lock"); lock.Lock(/*infinite*/); LOG_PARENT("locked"); LOG_PARENT("start child"); exitcode = CExec::SpawnL(CExec::eWait, app.c_str(), "-test", "1", "-lock", lockname.c_str(), NULL).GetExitCode(); LOG_PARENT("child exitcode = " << exitcode); assert( exitcode == IPCL_SUCCESS ); }} LOG_POST("\n--- Test 2"); // Set lock and start child process, that try to set lock also (successfully after child termination). {{ // lock.Lock(); -- still locked LOG_PARENT("start child"); handle = CExec::SpawnL(CExec::eNoWait, app.c_str(), "-test", "2", "-lock", lockname.c_str(), NULL).GetProcessHandle(); CProcess process(handle, CProcess::eHandle); // Wait until child starts SleepSec(1); LOG_PARENT("unlock"); lock.Unlock(); LOG_PARENT("unlocked"); SleepSec(2); // Child should set lock on this moment LOG_PARENT("try lock"); assert( !lock.TryLock() ); LOG_PARENT("unable to lock"); exitcode = process.Wait(); LOG_PARENT("child exitcode = " << exitcode); assert( exitcode == IPCL_SUCCESS ); // Lock should be already removed LOG_PARENT("lock"); lock.Lock(zero_timeout); LOG_PARENT("locked"); LOG_PARENT("unlock"); lock.Remove(); LOG_PARENT("removed"); }} LOG_POST("\n--- Test 3"); // Child set lock and current process try to lock it also. {{ LOG_PARENT("start child"); handle = CExec::SpawnL(CExec::eNoWait, app.c_str(), "-test", "3", "-lock", lockname.c_str(), NULL).GetProcessHandle(); CProcess process(handle, CProcess::eHandle); // Wait until child starts SleepSec(1); LOG_PARENT("try lock"); assert( !lock.TryLock() ); LOG_PARENT("unable to lock"); LOG_PARENT("lock in 3 sec"); lock.Lock(CTimeout(3,0)); LOG_PARENT("locked"); LOG_PARENT("unlock"); lock.Unlock(); LOG_PARENT("unlocked"); exitcode = process.Wait(); LOG_PARENT("child exitcode = " << exitcode); assert( exitcode == IPCL_SUCCESS ); }} LOG_POST("\n--- Test 4"); // Child set lock, we kill child process and set our own lock. {{ LOG_PARENT("start child"); handle = CExec::SpawnL(CExec::eNoWait, app.c_str(), "-test", "3", "-lock", lockname.c_str(), NULL).GetProcessHandle(); CProcess process(handle, CProcess::eHandle); // Wait until child starts SleepSec(1); // Lock should be set by child LOG_PARENT("try lock"); assert( !lock.TryLock() ); LOG_PARENT("unable to lock"); LOG_PARENT("kill"); assert(process.Kill()); // Lock should be automaticaly released SleepSec(1); LOG_PARENT("lock"); lock.Lock(); LOG_PARENT("locked"); }} // We don't need lock object anymore, remove it from the system lock.Remove(); LOG_PARENT("removed"); }