The documentation of delphi says that the WaitFor function for TMutex and others sychronization objects wait until a handle of object is signaled.But this function also guarantee the ownership of the object for the caller?
2 Answers
Yes, the calling thread of a TMutex
owns the mutex; the class is just a wrapper for the OS mutex object. See for yourself by inspecting SyncObjs.pas.
The same is not true for other synchronization objects, such as TCriticalSection
. Any thread my call the Release
method on such an object, not just the thread that called Acquire
.

- 161,384
- 21
- 275
- 467
-
1Except doing so will/may cause problems. WINSDK: If a thread calls LeaveCriticalSection when it does not have ownership of the specified critical section object, an error occurs that may cause another thread using EnterCriticalSection to wait indefinitely. – Marjan Venema May 28 '10 at 06:39
-
1Yes, I suppose the issue with ownership isn't so much about who's allowed to release something as it is about what happens when the owner disappears without releasing what it owned. For mutex objects, the OS detects and reports that the mutex has been *abandoned*, whereas with a critical section, the OS doesn't really notice. – Rob Kennedy May 28 '10 at 07:49
TMutex.Acquire
is a wrapper around THandleObjects.WaitFor
, which will call WaitForSingleObject
OR CoWaitForMultipleHandles
depending on the UseCOMWait
contructor argument.
This may be very important, if you use STA COM objects in your application (you may do so without knowing, dbGO/ADO is COM, for instance) and you don't want to deadlock.
It's still a dangerous idea to enter a long/infinite wait in the main thread, 'cause the only method which correctly handles calls made via TThread.Synchronize
is TThread.WaitFor
and you may stall (or deadlock) your worker threads if you use the SyncObjs objects or WinAPI wait functions.
In commercial projects, I use a custom wait method, built upon the ideas from both THandleObjects.WaitFor
AND TThread.WaitFor
with optional alertable waiting (good for asynchronous IO but irreplaceable for the possibility to abort long waits).
Edit: further clarification regarding COM/OLE:
COM/OLE model (e.g. ADO) can use different threading models: STA (single-threaded) and MTA (multi or free-threaded).
By definition, the main GUI thread is initialized as STA, which means, the COM objects can use window messages for their asynchronous messaging (particulary when invoked from other threads, to safely synchronize). AFAIK, they may also use APC procedures.
There is a good reason for the CoWaitForMultipleHandles
function to exist - see its' use in SyncObjs.pas THandleObject.WaitFor
- depending on the threading model, it can process internal COM messages, while blocking on the wait handle.

- 1,451
- 10
- 15
-
Viktor Svub: Could you please explain in more detail the problems about using `WaitForSingleObject` when the application uses COM? How is a call to `WaitForSingleObject`, main thread or any thread, related to e.g. using ADO in yet another thread? I understand the > It's still a dangerous idea to enter a long/infinite... part of your post. Thanks! – nang Jun 16 '10 at 09:50