Olivier Sannier wrote: > Hi all, > > Any reactions on this? Thanks, looks OK at the first glance. Raising an exception is IMO a good idea. Will add your code to my working copy soon, hopefully I'll have some time left for ICS this week.
-- Arno Garrels > > Cheers > Olivier > > Olivier Sannier wrote: >> Olivier Sannier wrote: >> >>> I'll try to figure out a way to do this and will submit a patch >>> when I get it working properly. >>> >>> >> Ok, figured it out quite easily. Please see the proposed patch at the >> end of this message. >> The only question is whether or not I could have read GWndHandleCount >> directly instead of locking GWndHandlerPool and then reading the >> count >> property of its FList field. >> >> Hope this helps >> Cheers >> Olivier >> >> //////////////////////////////////////////////////////////////////////////////////////////// >> >> Index: OverbyteIcsWndControl.pas >> =================================================================== >> --- OverbyteIcsWndControl.pas (revision 201) >> +++ OverbyteIcsWndControl.pas (working copy) >> @@ -287,6 +287,10 @@ >> // the GWndHandlerMsgLow + WH_MAX_MSG >> GWndHandlerMsgLow : Integer; >> >> + // Will be used by the last socket to know if it must cleanup the >> global + // handler because the unit has been finalized before the >> socket was diposed + GUnitFinalized: Boolean; >> + >> implementation >> >> // Forward declaration for our Windows callback function >> @@ -413,6 +417,23 @@ >> {$ENDIF} >> >> >> +procedure FinalizeGlobalHandler; >> +begin >> + // If the list is empty, we can safely delete the global >> handler, + // else we leave it up to the last socket to do the >> cleanup + GWndHandlerPool.Lock; >> + try >> + if GWndHandlerPool.FList.Count > 0 then >> + Exit; >> + finally >> + GWndHandlerPool.UnLock; >> + end; >> + >> + FreeAndNil(GWndHandlerPool); >> + DeleteCriticalSection(GWndHandlerCritSect); >> +end; >> + >> + >> {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * >> * * * * *} // MsgHandlersCount _must_ be overriden in derived >> classes to adjust the number // of message handlers needed. >> @@ -457,6 +478,20 @@ >> if FHandle <> 0 then >> Exit; // Already done >> >> + // Despite the precautions taken not to destroy GWndHandlerPool >> via the + // finalization when a socket is still there, we could >> still be going + // through this code in the following situation: >> + // >> + // Application shuts down >> + // The last known socket frees GWndHandlerPool >> + // A thread is still running and creates a new socket >> + // >> + // Note that this is highly unlikely, but as a courtesy to >> developers + // we raise an assertion error when this happens. >> + // The solution to this problem is to make sure that all >> threads are + // finished before the application is terminated >> itself. + Assert(Assigned(GWndHandlerPool), 'GWndHandlerPool is >> already nil, check your threads!!!'); + >> FThreadId := GetCurrentThreadId; >> GWndHandlerPool.Lock; >> try >> @@ -492,6 +527,9 @@ >> finally >> GWndHandlerPool.UnLock; >> end; >> + >> + if GUnitFinalized then >> + FinalizeGlobalHandler; >> end; >> >> >> @@ -1269,7 +1307,7 @@ >> InitializeCriticalSection(GWndHandlerCritSect); >> >> finalization >> - GWndHandlerPool.Free; >> - DeleteCriticalSection(GWndHandlerCritSect); >> + FinalizeGlobalHandler; >> + GUnitFinalized := True; >> >> 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