Reputation: 2022
Is this the correct way to free TCriticalSection
object created inside the initialization section in Delphi?
initialization
FPoolingCS := TCriticalSection.Create;
finalization
FPoolingCS.Acquire;
FreeAndNil(FPoolingCS);
Should I call the Release
method before the Free
?
Could the Acquire
method throw some exceptions that I need to handle?
Upvotes: 1
Views: 1009
Reputation: 28516
This is not the correct way to release critical section for several reasons.
According to documentation EnterCriticalSection function
This function can raise EXCEPTION_POSSIBLE_DEADLOCK if a wait operation on the critical section times out. The timeout interval is specified by the following registry value: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\CriticalSectionTimeout. Do not handle a possible deadlock exception; instead, debug the application.
If a critical section is deleted while it is still owned, the state of the threads waiting for ownership of the deleted critical section is undefined.
While a process is exiting, if a call to EnterCriticalSection would block, it will instead terminate the process immediately. This may cause global destructors to not be called.
Calling FPoolingCS.Acquire
on Windows platform calls EnterCriticalSection
function. So the answer to first question, whether acquiring critical section can raise exception, is yes.
Also according to documentation, you should not try to handle such exceptions, but you have to debug the application, because origin of the problem is in some other code.
But the most notable reason why you should not call Acquire
before releasing critical section instance on any platform is that if at that point there are some other threads that are doing some work and are relying on that critical section means your shutdown and cleaning process is completely broken. In other words, if Acquire
solves your problem, real issue is in another castle and you haven't really solved anything, you have just slightly changed the dynamics, which may work and may not work, depending on all other code involved.
Calling Release
before Free
would be meaningless, for the same reason. If there are other involved threads still running, they may acquire the lock before Free
is executed.
Just call Free
on critical section, or if you like use FreeAndNil
that will ultimately crash if your shutdown process is broken. Just remember, threading issues are not consistently reproducible, so absence of a crash still does not mean you have fully bug free code.
Upvotes: 8