Hello Olivier, Thank you for your analysis. Initialization/finalization order has always been an issue, no matter which component you use. Developer has control on it ! Finalization sections are executed in the reverse order of their initialization section which in turn are executed in the order of their enumeration in the uses clause. So for your problem, if you add OverbyteIcsWndControl in front (well after other higher priority units such as FastMM4) of the dpr uses clause, the issue should go away. Please check and tell me what.
About your changes: It's sure that using FreeAndNil is a good idea. Checking Assigned(GWndHandlerPool) is also good but be aware that this would hide the exception and still may produce unexpected results since the lock is no more used. If you some reason a thread is still working and using the same code section, you'll be in trouble. Granted this is not common situation. -- [EMAIL PROTECTED] Author of ICS (Internet Component Suite, freeware) Author of MidWare (Multi-tier framework, freeware) http://www.overbyte.be ----- Original Message ----- From: "Olivier Sannier" <[EMAIL PROTECTED]> To: "ICS support mailing" <[email protected]> Sent: Friday, October 10, 2008 10:13 AM Subject: [twsocket] GWndHandlerPool is freed before sockets are destroyed Hi, I just ported an application to ICSv6 and I'm encountering a problem when closing it down. It gives me an access violation in ntdll.dll, write of address 00000010 Digging around, I discovered that it comes from the call to GWndHandlerPool.Lock inside TIcsWndControl.DeallocateHWnd At the time it is being called, GWndHandlerPool has already been freed by the finalization section of OverbyteIcsWndControl.pas which ran before my own finalization section. In my own section, I'm freeing, indirectly, a class that contains a TWSocketServer which not active. I know this comes from the indirect nature of my usage of the class, but still, the order of finalization clauses should not be relied upon, as it was always indicated by the Delphi team. In particular, it will be different and changing when using packages. I tried this with ICSv7, it shows the same behavior. I thus propose to FreeAndNil GWndHandlerPool instead of simply freeing it, and then test if it is Assigned in all places it can be used (or the associated GWndHandlerCritSect section) when deallocating the window handle. I placed a "TortoiseSVN" patch file at the end of this message, you should be able to paste it into a blank .patch file and apply it to the current version of ICS. Please let me know what you think, right now this issue is blocking my upgrade. Cheers Olivier //////////////////////////////////////////////////////////////////////////// //////////////// Index: OverbyteIcsWndControl.pas =================================================================== --- OverbyteIcsWndControl.pas (revision 34841) +++ OverbyteIcsWndControl.pas (working copy) @@ -481,16 +481,18 @@ if FHandle = 0 then Exit; // Already done - GWndHandlerPool.Lock; + if Assigned(GWndHandlerPool) then + GWndHandlerPool.Lock; try FreeMsgHandlers; - if Assigned(FWndHandler) and (FWndHandler.FMsgCnt <= 0) then + if Assigned(FWndHandler) and (FWndHandler.FMsgCnt <= 0) and Assigned(GWndHandlerPool) then GWndHandlerPool.FreeWndHandler(FWndHandler); FHandle := 0; FWndHandler := nil; FThreadID := 0; finally - GWndHandlerPool.UnLock; + if Assigned(GWndHandlerPool) then + GWndHandlerPool.UnLock; end; end; @@ -877,7 +879,8 @@ DestroyWindow(FHandle); // Détruit la fenêtre cachée FHandle := 0; // On n'a plus de handle ! - EnterCriticalSection(GWndHandlerCritSect); + if Assigned(GWndHandlerPool) then + EnterCriticalSection(GWndHandlerCritSect); try Dec(GWndHandleCount); if GWndHandleCount <= 0 then @@ -888,7 +891,8 @@ OverbyteIcsLibrary.UnregisterClass( IcsWndControlWindowClassName, HInstance); finally - LeaveCriticalSection(GWndHandlerCritSect); + if Assigned(GWndHandlerPool) then + LeaveCriticalSection(GWndHandlerCritSect); end; end; {$ENDIF} @@ -1269,7 +1273,7 @@ InitializeCriticalSection(GWndHandlerCritSect); finalization - GWndHandlerPool.Free; + FreeAndNil(GWndHandlerPool); DeleteCriticalSection(GWndHandlerCritSect); end. -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be -- To unsubscribe or change your settings for TWSocket mailing list please goto http://lists.elists.org/cgi-bin/mailman/listinfo/twsocket Visit our website at http://www.overbyte.be
