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