5

When calling the TryEnter method on a TCriticalSection the result is always true. Surely this should only return true if it is able to aquire the lock?

var
  MyCritSect: TCriticalSection;

begin
  MyCritSect := TCriticalSection.Create;
  try
    //    MyCritSect.Enter;
    Writeln(BoolToStr(MyCritSect.TryEnter, True)); // This should return True
    Writeln(BoolToStr(MyCritSect.TryEnter, True)); // This should return False?
    Readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Even if you uncomment the MyCritSect.Enter; line it still returns True for both calls to TryEnter.

I am using Delphi XE and Windows 10.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Donovan Boddy
  • 489
  • 1
  • 6
  • 14

1 Answers1

4

Critical sections are re-entrant locks. From the documentation:

When a thread owns a critical section, it can make additional calls to EnterCriticalSection or TryEnterCriticalSection without blocking its execution. This prevents a thread from deadlocking itself while waiting for a critical section that it already owns.

Your call to TryEnter will fail if made from a different thread, and the first thread already owns the lock.

Community
  • 1
  • 1
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Thanks David, I think a TSpinLock might be better suited to my needs. – Donovan Boddy Dec 10 '15 at 08:17
  • 1
    I couldn't offer any opinion on whether or not that is the case since we don't know the motivation. Spin locks do burn CPU so they are only useful for low contention on small regions. – David Heffernan Dec 10 '15 at 08:19
  • @DonovanBoddy If you are trying to do a spinlock on the same thread then you will be in trouble because it will hang or behave the same as the critical section depending on the implementation. – Graymatter Dec 10 '15 at 09:29