gabr42 / OmniThreadLibrary

A simple and powerful multithreading library for Delphi
http://www.omnithreadlibrary.com
Other
462 stars 141 forks source link

Using OTL with runtime package and dynamic loaded libraries causes AV. #132

Closed sglienke closed 5 years ago

sglienke commented 5 years ago

Using OTL from a runtime package and dynamically loaded other libraries causes AVs.

The reason for this is that somewhere inside the OTL mechanics the passed callbacks are captured and later cleared which might happen when the original library that was doing a call to the OTL was unloaded already. Trying to free any captured objects or the anonymous method instance itself will then trigger an AV - see attached project.

To solve this issue there should be a Shutdown procedure to finalize/destroy all OTL pieces that are otherwise only ever destroyed when their finalization blocks are being run which happens when the runtime package gets unloaded where the code resides in. With a runtime package this usually happens when the application ends. At that point even other modules that are using the OTL are already unloaded due to the library loading order (even if not dynamically loading them as shown in the example)

OTLShutdownIssue.zip

sglienke commented 5 years ago

Found the issue - here is the fix:

procedure TOmniTaskExecutor.Cleanup;
begin
  oteWorkerIntf := nil;
+  {$IFDEF OTL_Anonymous}
+  oteFunc := nil;
+  {$ENDIF OTL_Anonymous}
  FreeAndNil(oteTimers);
end; { TOmniTaskExecutor.Cleanup }

This will release the reference on the anonymous method after executing it and the entire reference chain that might be attached to it. I am however not sure if this is the only place that might be missing such a line as there are other places within OTL that store anonymous method references which might be kept for too long.

gabr42 commented 5 years ago

Confirmed. Thank you for the fix!