The Delphi Bug List

Entry No.
604
RTL - Sys - SysUtils
TMultiReadExclusiveWriteSynchronizer lock promotion causes dead-lock.
1.02 2.01 3.0 3.01 3.02 4.0 4.01 4.02 4.03 5.0 5.01 6.0 6.01 6.02 Kylix 1.0
N/AN/AN/AN/AN/AExistsExistsExistsExistsExistsExistsFixedFixedFixedUnknown
Description
Reported by Anders Melander
It is currently impossible to use the lock promotion feature of TMultiReadExclusiveWriteSynchronizer without serious risk of dead-locks. Even though the help does not say so, a comment in the source code states that "Read locks can be promoted to write locks".

Consider the following (pseudo) code:

var
  FSynchronizer: TMultiReadExclusiveWriteSynchronizer;
...
begin
  // Aquire read lock
  FSynchronizer.BeginRead;
  try
    while (...scan list for resource...) do
      if (...resource found...) then
      begin
        // Promote read lock to write lock
        FSynchronizer.BeginWrite;
        try
          ...do something to resource...
        finally
          FSynchronizer.EndWrite;
        end;
      end;
  finally
    FSynchronizer.EndRead;
  end;
end;
If two threads are running this code concurrently, a dead-lock will occur if both threads attempt to promote their read lock to a write lock.
  1. Thread A calls BeginRead to aquire read lock.
  2. Thread B calls BeginRead to aquire read lock.
  3. Thread A calls BeginWrite to promote read lock to write lock.
    The call blocks because another thread has already aquired a read lock.
  4. Thread B calls BeginWrite to promote read lock to write lock.
    The call blocks because another thread has already aquired a read lock.
  5. Dead-lock.
    Thread A is waiting for thread B and thread B is waiting for thread A.
The bug in TMultiReadExclusiveWriteSynchronizer is not that a dead-lock can occur, but the fact that the dead-lock isn't detected. The scenario described above will always cause dead-locks no matter how TMultiReadExclusiveWriteSynchronizer is implemented, but it should detect the dead-lock and raise an exception.

Also, since most people are unaware of the dead-lock risk of lock promotion, this problem should be documented in the online help.

User-contributed comments
Theo van Soest
20 Mar 2001  10:38 PM GMT
There is a very good article on the thread handling topic at

http://www.pergolesi.demon.co.uk/prog/threads/ToC.html

by
Martin Harvey
Anders Melander
19 Jun 2001  10:38 AM GMT
This problem has semi-fixed in Delphi 6; In situations where a lock promotion would cause a dead lock, TMultiReadExclusiveWriteSynchronizer now releases the existing read lock and then acquires the write lock. This "fix" breaks existing code and IMO violates the principle that an already acquired lock is yours until you release it, but I guess the fix is better than a dead lock.
Latest update of this entry: 2001-06-19

Post a comment on this bug


Index page
Delphi Bug List home page
The Delphi Bug Lists are presently maintained by Jordan Russell, who has taken over this task from Reinier Sterkenburg since August 2000.
All feedback is appreciated. See also the feedback section of the Delphi Bug List home page.