views:

497

answers:

3

I am in search of an upgradeable read write lock for win32 with the behaviour of pthreads rwlock, where a read lock can be up- and downgraded.

What I want:

pthread_rwlock_rdlock( &lock );
...read...
if( some condition ) {
    pthread_rwlock_wrlock( &lock );
    ...write...
    pthread_rwlock_unlock( &lock );
}
...read...
pthread_rwlock_unlock( &lock );

The upgrade behaviour is not required by posix, but it works on linux on mac.

Currently, I have a working implementation (based on an event, a semaphore and a critical section) that is upgradeable, but the upgrade may fail when readers are active. If it fails a read unlock + recheck + write lock is necessary.

What I have:

lock.rdlock();
...read...
if( some condition ) {
    if( lock.tryupgrade() ) {
        ...write...
        lock.unlock();
        return;
    } else {
        lock.unlock();
        // <- here, other threads may alter the condition ->
        lock.wrlock();
        if( some condition ) { // so, re-check required
            ...write...
        }
        lock.unlock();
        return;
    }
}
...read...
lock.unlock();

EDIT: The bounty:

I am still in search, but want to add some restrictions: it is used intra-process-only (so based on critical sections is ok, WIN32 mutexes are not ok), and it should be pure WIN32 API (no MFC, ATL etc.). Acquiring read locks should be fast (so, acquiring the read lock should not enter a critical section in its fast path). Maybe an InterlockedIncrement based solution is possible?

+1  A: 

I hope that this article 'Recursive, Upgradable Read/Write Lock for Windows' will be helpful.

OwnWaterloo
Looks good. But Win32 Mutexes tend to have much overhead, I would prefer a solution based on Critical Sections. But I will give it a try and do a benchmark. Or maybe I can adapt it. Thanks!
frunsi
A: 

pthread library is a 'Portable Threads' library. That means it's also supported on windows ;) Have a look: Pthreads-w32.

Additionally, consider using OpenMP instead of locks: the compiler extension provides portable critical sections, kernes threading model, tasks and much more! MS C++ supports this technology as well as g++ in Linux.

Cheers! :)

o_O Tync
In fact, pthread means POSIX thread. Windows can be POSIX compliant if you download the necessary services
Gab Royer
You're right, but they're often called "Portable" because they are. :)
o_O Tync
+1  A: 

The boost shared_mutex class supports reader (shared) and writer (unique) locks and temporary upgrades from shared to unique locks.

http://stackoverflow.com/questions/989795

I don't recommend writing your own, it's a tricky thing to get right and difficult to test thoroughly.

Tim Sylvester
The win32 implementation of `boost::shared_mutex` looks promising. The pthread implementation is not so pretty (it has more than I need, and so the method they use maybe is not as efficient as pthread_rwlock_ with the non-standard upgrade behaviour..). I'll give it a try...
frunsi
Well, its perfect, and after reading the documentation and trying it out, it all makes sense now :-)
frunsi