views:

613

answers:

2

I'm porting a Windows application to Linux and I have a synchronization problem.

In Windows I'm using a system-level named mutex to sync access to a shared memory block.

How do I emulate that in Linux? I've created a SystemV semaphore, using semget. The problem is that it is not reentrant, if I already hold it it will block, unlike on Windows. I could add a reference count to it, but then I would need to synchronize access to that, which means another (this time for the current process only) mutex.

Is there a class somewhere which provides a reentrant interprocess lock (maybe in Boost)?

BTW, using a file lock is not acceptable since it will probably be too slow (I need ultra-low latency communication between the two processes).

+1  A: 

You could try building your own out of futexes. See usersem.c in this tarball.

atomice
I also need for this port something similar to a Windows CRITICAL_SECTION, and futex seems to be just that. The problem is that it seems that the futex does not have yet a Lock/Unlock simple API to use, and from what I've seen it's not trivial to use (lots of traps you can fall into). And since my Linux fu is not that great yet, I'm sticking to simpler primitives for now.
Adal
+4  A: 

You can just use a shared (interprocess), recursive pthread_mutex_t. Create a normal pthread_mutex (stored in shared memory) and set its attributes using pthread_mutexattr_settype with the PTHREAD_MUTEX_RECURSIVE flag, and then call pthread_mutexattr_setpshared with the PTHREAD_MUTEX_SHARED flag.

That will give you a reentrant, interprocess lock.

Charles Salvia
Storing the mutex in the shared memory is not ideal. But if I can't find something better I guess I will have to go with this.
Adal
You have no choice. The mutex has to be stored in shared memory if you want it to be interprocess
Charles Salvia
boost::interprocess::named_recursive_mutex seems to do just this. I will give you the answer points, since the other answer pointing to boost::interprocess::named_mutex has disappeared (even if it was not the recursive one).
Adal
Charles is right. boost::interprocess::named_recursive_mutex just hides the fact that it uses shared memory.See "detail::managed_open_or_create_impl<shared_memory_object> m_shmem;"
Paul Du Bois