I was just reading WWN and saw this discussion. Here's a wacky idea that might or might not work.
The basic idea is to grant ownership of each mutex to one Win32 process at a time. Let any thread grab the mutex quickly if it belongs to the process that owns the mutex. If its process does not own the mutex, then it must communicate with the wineserver and the wineserver must communicate with the owning process to transfer ownership of the mutex from the current owner to the requesting thread.
Here's how to implement it. For each Win32 process, for each mutex that's been mapped into it using DuplicateHandle or whatever, allocate a standard shared-memory-based critical section, along with a weOwnIt flag that indicates whether we own the mutex or not. Processes that don't own the mutex leave their critical sections locked. Then implement the operations as follows:
AcquireMutex { retry: TryToEnterCriticalSection(); // nonblocking if (failed) { if (!weOwnIt) { wineserver->GiveUsOwnership(); // blocking goto retry; } else { EnterCriticalSection(); // blocking } } }
ReleaseMutex { LeaveCriticalSection(); }
Then on some other thread in the same address space that serves wineserver requests:
WineserverGrantsUsOwnership { weOwnIt = true; LeaveCriticalSection(); }
WineserverWantsToTakeAwayOwnership { EnterCriticalSection(); weOwnIt = false; wineserver->WeHaveGivenUpOwnership(); }
Because the ownership test in AcquireMutex can race, the server needs to ignore GiveUsOwnership requests for processes that already own the mutex.
It seems like this will be efficient (a lot more efficient than a kernel call actually) unless the mutex is pingponging between processes, in which case you'll be eating lots of context switches anyway.
In terms of safety, a correctly functioning process will never complete AcquireMutex unless the wineserver has granted it the mutex. A misbehaving process can hold the mutex indefinitely or incorrectly think it has the mutex, but of course that's true under any scheme. When the wineserver terminates a process, it can reassign mutex ownership. (So if a process is asked to give up the mutex but doesn't, the wineserver can time out, kill the process and grant the mutex to someone else).
Rob