System.SyncObjs.TLightweightMREW

From RAD Studio API Documentation
Jump to: navigation, search

Delphi

  TLightweightMREW = record
{$IFDEF MACOS}
  private
    class var CalendarClock: clock_serv_t;
{$ENDIF MACOS}
  private
{$IFDEF MSWINDOWS}
    FNativeRW: SRWLOCK;
{$ENDIF MSWINDOWS}
{$IFDEF POSIX}
    FNativeRW: pthread_rwlock_t;
    procedure GetPosixEndTime(var EndTime: timespec; TimeOut: Cardinal); inline;
{$ENDIF POSIX}
  public
{$IFDEF MACOS}
    class constructor Create;
    class destructor Destroy;
{$ENDIF MACOS}
    [HPPGEN('TLightweightMREW() { _op_Initialize(*this); }' + #13#10#13#10#9 +
            'static void __fastcall _op_Initialize(/* out */ TLightweightMREW &Dest)')]
    class operator Initialize(out Dest: TLightweightMREW);
    procedure BeginRead;
    function TryBeginRead: Boolean; {$IF defined(LINUX) or defined(ANDROID)}overload;{$ENDIF}
{$IF defined(LINUX) or defined(ANDROID)}
    function TryBeginRead(Timeout: Cardinal): Boolean; overload;
{$ENDIF LINUX or ANDROID}
    procedure EndRead;
    procedure BeginWrite;
    function TryBeginWrite: Boolean; {$IF defined(LINUX) or defined(ANDROID)}overload;{$ENDIF}
{$IF defined(LINUX) or defined(ANDROID)}
    function TryBeginWrite(Timeout: Cardinal): Boolean; overload;
{$ENDIF LINUX or ANDROID}
    procedure EndWrite;
  end;

C++

struct DECLSPEC_DRECORD TLightweightMREW
{
private:
    _RTL_SRWLOCK FNativeRW;
public:
    TLightweightMREW() { _op_Initialize(*this); }

	static void __fastcall _op_Initialize(/* out */ TLightweightMREW &Dest);
    void __fastcall BeginRead();
    bool __fastcall TryBeginRead();
    void __fastcall EndRead();
    void __fastcall BeginWrite();
    bool __fastcall TryBeginWrite();
    void __fastcall EndWrite();
};

Properties

Type Visibility Source Unit Parent
record
struct
public
System.SyncObjs.pas
System.SyncObjs.hpp
System.SyncObjs System.SyncObjs

TLightweightMREW Record

TLightweightMREW is a reader-writer lock implementation introduced in RAD Studio 10.4.1, which works across all supported platforms to be faster and more lightweight than the existing TMultiReadExclusiveWriteSynchronizer

This synchronizer is implemented as a managed record (rather than a class, so that it doesn't require to be released from memory). It has more limited memory requirements and it is generally faster, as it wraps native POSIX APIs.

TLightweightMREW is much faster than the TMultiReadExclusiveWriteSynchronizer and implements a reader-writer locking mechanism on all platforms while the TMultiReadExclusiveWriteSynchronizer is implemented as a critical section on non-Windows platforms. This is why in most cases, TLightweightMREW is a better replacement of the classic TMultiReadExclusiveWriteSynchronizer.

TLightweightMREW access modes

TLightweightMREW wraps a native implementation of a reader-writer lock (also known as MRSW lock, or MREW lock). This mechanism allows two different "modes" of access: shared read access and exclusive write access.

Shared 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 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.

Using TLightweightMREW across supported platforms

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.