Hi all, Any reactions on this?
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