Olivier Sannier wrote:
> Assert(Assigned(GWndHandlerPool), 'GWndHandlerPool is already nil, check your
> threads!!!');
I just wonder whether we shouldn't check "not GUnitFinalized" rather than
"Assigned(GWndHandlerPool)",
what do you think?
--
Arno
>
> 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