Click here to Skip to main content
15,885,365 members
Please Sign up or sign in to vote.
4.00/5 (1 vote)
See more:
Hi,
I'm revising some code i wrote and i've this scenario: i should write something that does the following

If a pthread_rwlock_t is not in use (i mean, no one holds it, and no one is waiting for it)
      destroy it


Now, how can i do this check? I mean, i think that different implementations of pthread_rwlock_t have different structure fields (on my system, pthread_rwlock_t is a union tbh, i think there isn't a standard for the type), so i should do it through pthread functions, but how? Also i found out that "destroy" has not a standard behaviour if you call it on a "busy" rwlock (with busy, i mean that someone holds it or someone is waiting for it)

How can i do this? The only idea i have is using a struct like this

struct MyLock
{
  pthread_rwlock_t l;
  int waiting;
}


increase waiting everytime before calling rdlock or wrlock and deacreasing everytime i acquire the lock, and then i could check if i can destroy it if and only if i acquire the exclusive lock on it (that means no one is holding it) and waiting is zero.. any other ideas that don't require me to count the threads waiting?
Posted

1 solution

A solution to this problem is not going to be pretty, even if we pretend that the reference counting solution that you suggested is going to work as expected (you would need to use something similar to InterlockedIncrement[^] to avoid additional locking around the code that increments and decrements the waiting variable). The problem is that even if you are certain that no other thread is holding the lock, and also that nobody is waiting on it, you cannot be sure that there are no threads that are about to grab that lock. Additionally, other threads would need to check if the lock has been destroyed before acquiring it - an operation that needs to be synchronized, too.

Generally, I avoid creating and destroying locks dynamically. I create all locks that I need in a constructor, and destroy them in the destructor. For more dynamic situations requiring synchronization I use interlocked instructions to avoid locking altogether.
 
Share this answer
 
Comments
tuccio 24-May-11 7:54am    
well i made the assumption that no one is going to grab the lock, because i've a std::map containing locks and i access this map in mutual exclusion, so, while i've the lock on the map, no one is going to grab it, because no one can access it (i know this sounds weird and inefficient, but it's the easiest solution i've found, and i've not requirements of efficience)

of course this map mutual exclusion implies no one can access waiting variabile, so this is a kind of interlocked increment too

my point is that i've this std::map<ino_t,> to lock files on a thread base, i add locks to this map when i request lock for the file, but i need a condition to remove them safely, to avoid the map being full of useless locks
dasblinkenlight 24-May-11 10:03am    
If your locks are stored in std::map, you can remove the lock you need to destroy from that map, release the lock on the map, call a pthread_rwlock_rdlock followed by pthread_rwlock_unlock, and finally a pthread_rwlock_wrlock followed by pthread_rwlock_unlock again. Once your call succeeds, you can be sure that (1) all writers that requested the lock prior to its removal from the map have released it (rwlock allows writers to proceed ahead of readers; once you get a read lock, you know there are no further writers), (2) all readers that requested the lock prior to its removal from the map have released it (because you grabbed a write lock), and (3) no new readers or writers are trying to get a hold of it, because you have removed it from the map prior to locking it. This way you can be sure that it's OK to dispose of the lock.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900