The recent RAD Studio 10.4.1 is a quality focused release, but it does include a few new features, mostly added in the process of solving open issues. One of these scenarios is that of improving the RTL synchronization objects and in particular addressing the problems of using the TMultiReadExclusiveWriteSynchronizer (a.k.a. TMREWSync) in mobile applications. Lacking the same support the Windows OS offers, this class had a limited implementation for other platforms.
The New TLightweightMREW Record
In 10.4.1 we are introducing a new reader-writer lock implementation, meant to work across all supported platforms and meant to be faster and more lightweight than the old solution. The new record wraps native POSIX APIs, and it is a better replacement in most cases. It has been implemented as a managed record to further reduce the need of creating and freeing it.
The TLightweightMREW record is part of the System.SyncObjs unit and it wraps a native implementation of a reader-writer lock (also known as MRSW lock, or MREW lock). Threads can use TLightweightMREW to synchronize access to a resource that is mostly read from and rarely updated. A reader-writer lock offers two types of access. Shared (reading) access allows multiple readers to access the resource at the same time while it prevents any thread from acquiring an exclusive (writing) access. Exclusive (writing) access allows only one writer to access the resource and also blocks any readers.
Shared Read Access
- Shared access allows multiple readers to access the resource at the same time, while it also prevents any thread from acquiring an exclusive (write) access.
- Shared access can be requested recursively. A single thread can acquire it multiple times in a row. Each BeginRead/TryBeginRead call must be paired with a call to EndRead.
Exclusive Write Access
- Exclusive (write) access can only be granted to one thread at a time. While a TLighweightMREW lock is in exclusive mode, it will prevent any thread from getting shared (read) access.
- Exclusive access cannot be requested recursively.
- Shared access cannot be upgraded to exclusive access.
Additional Details and Platform Differences
While the TLightweightMREW implementation is dependent on the operating system, such lock functions are almost identical on all supported platforms. The following facts hold for all implementations:
- If any thread holds a read lock then any other thread can also acquire a read lock while no one can acquire a write lock.
- If any thread holds a write lock then no thread can acquire a read nor a write lock.
- If a thread holds a read lock, it can acquire another read lock again before the first read lock is released (recursion).
- If a thread holds a write lock, it cannot acquire another write lock
The following behavior depends on the operating system:
- If at least one reader is always active, a writer may never get the lock (starvation)
- If the same thread tries to recursively acquire a write lock two times, the application will deadlock on Windows but raise an exception on POSIX systems.
The full interface of the class is listed in the RAD Studio documentation at http://docwiki.embarcadero.com/Libraries/Sydney/en/System.SyncObjs.TLightweightMREW while the list of the methods is at http://docwiki.embarcadero.com/Libraries/Sydney/en/System.SyncObjs.TLightweightMREW_Methods
Delphi and C++Builder 10.4.1 is notable because it’s a quality-focused release, with over 500 customer reported issues addressed, plus a few nice features like the new TLightweightMREW record. In particular for Delphi developers, 10.4.1 offers significant improvements for the new LSP-based Code Insight implementation introduced in 10.4, as you can read in this blog post by David Millington.