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

Reply via email to