Hello

Hello,

This will be my first post/question :-)

I have a large VCL application made up of several EXE's and 100+ dynamically loaded DLL's with forms. The primary EXE has a Datasnap client inside it that calls methods of a service running on a server for concurrent user tracking, so we know who is logged into the software.

Today I implemented a Datasnap callback so a message can be sent through the Datasnap channel from a monitoring EXE to all connected clients. The message trigger on the client side then issues a thread sync call to a procedure in the main GUI thread that calls "Close;" to end the program. This is working like I expected it to, it calls Close and the EXE ends as normal....until a form from a DLL is in use. The DLL is calling Application.Terminate, which destroys all the created forms in the DLL and exists the DLL and frees the resources, but then it stops at the EXE in the method where the DLL was loaded from, like the user just close the form normally, it does not contunie the shutdown. If I send the callback message again the EXE will then end as normal. There are DLL's called from inside DLL's (I know packages...but I lost that battle 18 years ago) the level of DLL corresponds to the number of callback calls to get the whole process to end.

The question is...is the DLL eating the Close and is there a way to cascade the call or loop through the open forms and end the whole process correctly?

Comments

  1. The DLLs are treated like self-contained modular processes that are dynamically loaded, used to do what they need to do then unloaded. All forms are modal, none are embeded in other forms or components. All calls/parms are C type so they can be called from other languages if need, although this has not be used this was the reason for using DLLs instead of BPLs. All EXEs and DLLs are compiled with the same version of Delphi (Berlin 10.1) . All testing is done with a version compiled with FastMM4 in full debug mode to confirm no memory leaks. This software has been in production for over 18 years using forms in DLL like this. We know there is overhead with multiple copies of the VCL, TApplication and TScreen that is why all forms are modal and the DLLs are self-contained.

    Since the GUI threads TApplication is getting a message to "Close" it is being sent through the forms "close" which calls Application.Terminate because the form is the active form in the main thread. But the "active" TApplication.Terminate is inside a DLL, so the DLL gets the Application.Terminate first, this is not causing memory leaks, all open forms from within the DLL are getting their OnDeactivate, OnHide and OnDestroy events called just like an EXE would and the DLL is unloaded as normal and the GUI thread continues.

    ReplyDelete
  2. You can make an experiment: go through all your dll and exe projects and enable runtime packages. Then try to close the app again. I am 99% sure that your bug will go away.

    ReplyDelete
  3. Tom Chamberlain your app is hell's fury waiting to happen. Try Микола Петрівський approach to solve your troubles. Maybe God was on your side all this time.

    ReplyDelete

Post a Comment