#1 2020-03-09 09:40:30

sakura
Member
From: Germany
Registered: 2018-02-21
Posts: 239
Website

TObjectListLocked changed, creating dead locks

Hi,

so far, it was safe to do following:

  LockedList.Safe.Lock;
  try
    for ItemIdx := 0 to LockedList.Count - 1 do
      ItemClear(TMypSession(LockedList[ItemIdx]));

    LockedList.Clear;
  finally
    LockedList.Safe.UnLock;
  end;

with the recent change, having seen that in many places, it will dead lock at the clear method.

Further, having methods like Add/Remove/... automatically thread safe, and others like Delete not being thread safe is, imho, not a good idea, as one ALWAYS has to look at the documentation, to be sure what's happining. And as the documemantion does not work within the IDE, that means jumping around in the sources.

THe old SafeAdd/Safe... methods where more self-identifying and certainly easy to use.

Please, roll back that change. :-)

Offline

#2 2020-03-09 11:13:57

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: TObjectListLocked changed, creating dead locks

LockedList.Clear would never make a race condition.
It calls the same LockedList.Safe lock, which is reentrant.
If you have a race condition, it doesn't comes from this change.

Offline

#3 2020-03-09 11:29:22

sakura
Member
From: Germany
Registered: 2018-02-21
Posts: 239
Website

Re: TObjectListLocked changed, creating dead locks

So Safe.Lock allows me to "lock" multiple times from within the same thread without deadlocking? It only blocks other threads at the same time? Didn't know/test that before. Would be cool.

Still leaves, imo, the big problem, that some methods do locking automatically (like Add/Remove/Clear), while others like Delete do not, which is not obvious, when using the list.

Offline

#4 2020-03-09 11:38:34

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: TObjectListLocked changed, creating dead locks

@sakura
Yes, this is how TRTLCriticalSection works: they are re-entrant by definition.
Delete() from an index can not be thread-safe, because it uses an index which may change if something is added in a background thread. An explicit lock is needed.
Remove() make a search + delete so it can be made thread-safe.

Offline

#5 2020-03-09 11:43:45

sakura
Member
From: Germany
Registered: 2018-02-21
Posts: 239
Website

Re: TObjectListLocked changed, creating dead locks

Okay, thx.

Still feels a bit funny, but I understand. Have a real problem now, will check a bit further and likely will open another thread in a minute.

Offline

#6 2020-03-09 12:48:53

macfly
Member
From: Brasil
Registered: 2016-08-20
Posts: 374

Re: TObjectListLocked changed, creating dead locks

I particularly like the pattern that returns the locked instance. Then, you can always block and release the necessary access to the list.
It is very simple to implement as you do not need to override the methods in the original list.

with MyList.Locked do //Locked make the lock and returns the FList itself
try
 Add(..);
 Delete(..)
 Clear;
finally
  MyList.unlock;
end;

But the implementation of mORMot is also very good.

Last edited by macfly (2020-03-09 12:50:55)

Offline

#7 2020-03-09 13:02:06

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: TObjectListLocked changed, creating dead locks

"with" is evil. wink

Offline

#8 2020-07-07 15:45:50

George
Member
Registered: 2016-04-05
Posts: 142

Re: TObjectListLocked changed, creating dead locks

Is there an option to allow multiple read single write logic?
Like TMultiReadExclusiveWriteSynchronizer do.
Useful when object must be thread safe with big amount of read operations and rare write operations.

Last edited by George (2020-07-07 15:51:14)

Offline

#9 2020-07-07 20:52:27

ab
Administrator
From: France
Registered: 2010-06-21
Posts: 14,659
Website

Re: TObjectListLocked changed, creating dead locks

Not yet. Use TMultiREWS if you need to.

Offline

#10 2020-07-08 08:10:38

trx
Member
Registered: 2015-08-30
Posts: 30

Re: TObjectListLocked changed, creating dead locks

George wrote:

Is there an option to allow multiple read single write logic?
Like TMultiReadExclusiveWriteSynchronizer do.
Useful when object must be thread safe with big amount of read operations and rare write operations.

I usually use TPasMPMultipleReaderSingleWriterLock from PasMP which works with both Delphi and FPC (Windows and Linux).

Last edited by trx (2020-07-08 08:11:32)

Offline

Board footer

Powered by FluxBB