Main BLOGGER
Google
WWW THIS BLOG
Wednesday, June 21, 2006
 
using inter-process lock

In Linux

A tutorial on how to use flock

http://www.ecst.csuchico.edu/~beej/guide/ipc/flock.html

Linux command: ipcs and ipcrm ACE

In ACE

ACE_OS::flock_xxx is a wrapper facility on top of flock which is fully supported in Linux 2.4.

In windows 2003 server, it is not working well. Instead, we can use ACE_Process_Mutex

Note:

Essentially, the initialization of a lock is to open a file. In order to avoid file handler leaking, we need to call flock_destroy() or delete the ACE_Process_Mutex object.

If we fail to get the lock by trywrlock(), we call flock_destroy() to release the file handler created in flock_init(), but we have to use “0” to indicate that we do not want to unlink the file; else it will break the lock if other processes depends on this file.

In Linux, the process_mutex is implemented by semaphore. Semaphore is a system wide resource. It will lead to serious situation if there is a leak on it. You can use ipcs or ipcrm to dump and control semaphore.

While flock will be released once the process is gone, therefore, it is much safer in case the process could be possibly killed abnormally.

Here is the code snippet.

#if !defined(WIN32) //in Linux

void SymLoggerControl::finiLog()

{

ACE_OS::flock_destroy(&m_flock);

}

int SymLoggerControl::initAutoIndex(const SymString &filename, const SymString &i_name)

{

const int MAX_TRY = 1000;

int iret = -1;

if (i_name != "sim")

return iret;

SymString fstr;

SymString lockName;

for (int i=1; i<MAX_TRY;i++)

{

fstr = filename + "." + intToString(i) + ".log";

lockName = "."+i_name + intToString(fstr.hash());

if (ACE_OS::flock_init(&m_flock,O_CREAT|O_RDWR,lockName.c_str(),0600)!=0)

continue;

if (ACE_OS::flock_trywrlock(&m_flock)!=0)

{

//we use 0 to indicate that the destroy can not unlink the file

//else it breaks the lock on other processes

ACE_OS::flock_destroy(&m_flock,0);

continue;

}

setAutoIndex(i);

return iret;

}

setAutoIndex(0);

return -1;

}

#else

void SymLoggerControl::finiLog()

{

if (m_logfileLock)

m_logfileLock->release();

}

int SymLoggerControl::initAutoIndex(const SymString &filename, const SymString &i_name)

{

if (i_name != "sim")

return 0;

const int MAX_TRY = 1000;

SymString lockName;

SymString fstr;

for (int i=1; i< MAX_TRY;i++)

{

fstr = filename + "." + intToString(i) + ".log";

lockName = i_name + intToString(fstr.hash());

// try to get the lock.

ACE_NEW_RETURN(m_logfileLock, ACE_Process_Mutex(lockName.c_str()), -1);

if (m_logfileLock->tryacquire() != 0)

{

//avoid memory leak

SAFE_DELETE(m_logfileLock);

continue;

}

setAutoIndex(i);

return 0;

}

setAutoIndex(0);

return -1;

}




<< Home

Powered by Blogger

Google
WWW THIS BLOG