Project Home
Project Home
Documents
Documents
Wiki
Wiki
Discussion Forums
Discussions
Project Information
Project Info
Forum Topic - A mutex in shared memory: (4 Items)
   
A mutex in shared memory  
I'm trying to implement a mutex in shared memory but have run into a problem.

My system is QNX 6.3.0 SP3.
A single process creates a file with shm_open( , O_RDWR | O_CREAT, ) under /dev/shmem and maps it as mmap(, PROT_READ | 
PROT_WRITE, MAP_SHARED, ).
Then process initializes a mutex in shared section with PTHREAD_PROCESS_SHARED and sets a boolean in shared section to 
indicate the mutex is initialized.
Then process locks the mutex and terminates on assertion failure afterwards.
When I start the process for the second time the file already exists so the process only opens it with shm_open(, O_RDWR
, ) without ftruncate() and maps into memory.
It detects the flag that the mutex is already created so it does not do anything else to init the mutex.
After that pthread_mutex_trylock() returns EINVAL instead of expected EBUSY and SyncMutexRevive() returns EINVAL too.
Is that the expected behavior? I was sure the mutex should persist even after all the clients terminate until the file 
is unlinked. Otherwise there is not much sense in all those dances around SyncMutexRevive().
Re: A mutex in shared memory  
> I'm trying to implement a mutex in shared memory but have run into a problem.
> 
> My system is QNX 6.3.0 SP3.
> A single process creates a file with shm_open( , O_RDWR | O_CREAT, ) under /
> dev/shmem and maps it as mmap(, PROT_READ | PROT_WRITE, MAP_SHARED, ).
> Then process initializes a mutex in shared section with PTHREAD_PROCESS_SHARED
>  and sets a boolean in shared section to indicate the mutex is initialized.
> Then process locks the mutex and terminates on assertion failure afterwards.
> When I start the process for the second time the file already exists so the 
> process only opens it with shm_open(, O_RDWR, ) without ftruncate() and maps 
> into memory.
> It detects the flag that the mutex is already created so it does not do 
> anything else to init the mutex.
> After that pthread_mutex_trylock() returns EINVAL instead of expected EBUSY 
> and SyncMutexRevive() returns EINVAL too.
> Is that the expected behavior? I was sure the mutex should persist even after 
> all the clients terminate until the file is unlinked. Otherwise there is not 
> much sense in all those dances around SyncMutexRevive().


Another interesting thing is that pthread_mutex_init() on that address seems to be returning EBUSY. So, does not 
SyncMutexRevive() work without prior SyncMutextEvent()? Why?
Re: A mutex in shared memory  
> > I'm trying to implement a mutex in shared memory but have run into a problem
> .
> > 
> > My system is QNX 6.3.0 SP3.
> > A single process creates a file with shm_open( , O_RDWR | O_CREAT, ) under /
> 
> > dev/shmem and maps it as mmap(, PROT_READ | PROT_WRITE, MAP_SHARED, ).
> > Then process initializes a mutex in shared section with 
> PTHREAD_PROCESS_SHARED
> >  and sets a boolean in shared section to indicate the mutex is initialized.
> > Then process locks the mutex and terminates on assertion failure afterwards.
> 
> > When I start the process for the second time the file already exists so the 
> 
> > process only opens it with shm_open(, O_RDWR, ) without ftruncate() and maps
>  
> > into memory.
> > It detects the flag that the mutex is already created so it does not do 
> > anything else to init the mutex.
> > After that pthread_mutex_trylock() returns EINVAL instead of expected EBUSY 
> 
> > and SyncMutexRevive() returns EINVAL too.
> > Is that the expected behavior? I was sure the mutex should persist even 
> after 
> > all the clients terminate until the file is unlinked. Otherwise there is not
>  
> > much sense in all those dances around SyncMutexRevive().
> 
> 
> Another interesting thing is that pthread_mutex_init() on that address seems 
> to be returning EBUSY. So, does not SyncMutexRevive() work without prior 
> SyncMutextEvent()? Why?

Today I was doing more experiments.
SyncMutexEvent succeeds for that mutex but the pulse is never delivered to the channel.
After the first process instance terminates the mutex is placed in {0x80000001, 0xfffffffe} state (not recursive, locked
, destroyed).

So, to summarize the open questions are:
1) Why is the mutex destroyed if the shared memory section that contains it still exists?
2) Why does an attempt to create a new mutex at that place fail with EBUSY if the previous one had been destroyed?
3) Why does SyncMutexEvent() succeed if the mutex has been destroyed?
4) [the most hard one] What is your suggested approach to make working with a mutex in shared memory feasible?
Re: A mutex in shared memory  
> So, to summarize, the open questions are:
> 1) Why is the mutex destroyed if the shared memory section that contains it 
> still exists?
> 2) Why does an attempt to create a new mutex at that place fail with EBUSY if 
> the previous one had been destroyed?
> 3) Why does SyncMutexEvent() succeed if the mutex has been destroyed?
> 4) [the most hard one] What is your suggested approach to make working with a 
> mutex in shared memory feasible?


The situation is even much worse than I could assume.
I've started two instances of process so that they both have opened the shared section and its open count did not drop 
to zero when one of processes terminates. It appears that if a mutex was watched by SyncMutexEvent() at the moment of 
process death the mutex transits to _NTO_SYNC_DEAD. However if there was another mutex which was not watched by 
SyncMutexEvent(), it transits to _NTO_SYNC_DESTROYED and hence, is not available for being attached and reviven later 
any more. This means that if the master process has managed to attach to the slave mutex until the slave dies, 
everything will be fine. But if the master was a bit too late and the slave terminated before master could find it and 
attach to it, the game is over.