whateverblog.
Writing an inter-process Read/Write locking mechanism
Wednesday, June 18, 2003 12:29 AM

Encountered a particularly interesting little problem today. The requirement was to create a read/write locking mechanism for .NET that behaved according to these rules:

That's a description of a fairly standard read/write lock. What makes it more interesting is that this read/write lock must protect a resource across multiple processes. Thus, most of the standard .NET threading constructs are useless, since they're only good for coordinating multiple threads inside a single process.

Win32 does provide a few cross-process synchronization primitives, however: Mutexes, Semaphores, and Events. These can be used from .NET with relative ease (i.e., relative to many other interop chores). Between my friend John and me, we figured out that you can actually satisfy the requirements using only Mutex and Semaphore. It sure isn't pretty, though.

Start by picking a number that is slightly higher than the number of concurrent reads you can reasonably expect. In this case, let's say it's 100. We will create a global semaphore with this number of permits. We'll also create a global mutex. (The code that follows should be considered pseudocode: for illustration purposes only.)

// create or open global mutex
GlobalMutex mutex = new GlobalMutex("IdOfProtectedResource.Mutex");
// create or open global semaphore
GlobalSemaphore semaphore = new GlobalSemaphore("IdOfProtectedResource.Semaphore", 100);

public void AcquireReadLock()
{
  mutex.Acquire();
  semaphore.Acquire();
  mutex.Release();
}

public void ReleaseReadLock()
{
  semaphore.Release();
}

public void AcquireWriteLock()
{
  mutex.Acquire();
  for (int i = 0; i < 100; i++)
    semaphore.Acquire();
  mutex.Release();
}

public void ReleaseWriteLock()
{
  for (int i = 0; i < 100; i++)
    semaphore.Release();
}

Thus, having read lock simply means holding one of the semaphore's permits, while having write lock means holding all of the semaphore's permits. It's a little bit nasty and inefficient, but it seems like it should work.

Tune in next week, when we'll be creating a FIFO monitor using only bubble gum and a pocket watch. ;)