Hello Arno,

> Because I think that DataAvailable should not be triggered when the
> component is destroyed anyway, but I may be wrong. 

As I recall it was by design that OnDataAvailable will trigger if there
is partial data in buffer. This can happen with LineMode set.

---
Rgds, Wilfried [TeamICS]
http://www.overbyte.be/eng/overbyte/teamics.html
http://www.mestdagh.biz

Wednesday, March 1, 2006, 17:19, Arno Garrels wrote:

> Francois Piette wrote:
>>> When I destroy the SimpleThrdSslServer with alot of threads and clients
>>> I can avoid AV's by this code:
>>> 
>>> function TCustomWSocket.TriggerDataAvailable(Error : Word) : Boolean;
>>> begin
>>>     Result := Assigned(FOnDataAvailable) and not (csDestroying in
>>> ComponentState);     if not Result then
>>>         Exit;
>>> ...
>> 
>> At first glance, I don't see why this code would cause trouble in
>> existing application. But why don't put it in the application code ?

> Because I think that DataAvailable should not be triggered when the 
> component is destroyed anyway, but I may be wrong. 

> I've played with the TWSocketThrdServer and modified it to always 
> wait for the threads, now FreeOnTerminate is _always_ set to FALSE.
> You know that the threads post WM_THREAD_TERMINATED at the end of
> method execute to the server window. So, in destructor messages must
> be processed. If you have a better idea please let me know.
> May be this is the reason why I get random AV's in OnDataAvailable.
> Note that I'm stress-testing with a client that connects, sends
> a request and server echos the request, this all very fast, one
> after the another, until there are up to thousand concurrent
> connections.


> procedure TWSocketThrdServer.WmThreadTerminated(var Msg: TMessage);
> var
>     AThread : TWsClientThread;
>     I      : Integer;
> begin
>     AThread := TObject(Msg.WParam) as TWsClientThread;
>     I := FThreadList.IndexOf(AThread);
>     if I > -1 then
>         FThreadList.Delete(I);
>     AThread.WaitFor;
>     if Assigned(FOnBeforeThreadDestroy) then
>         FOnBeforeThreadDestroy(Self, AThread);
>     if not AThread.FreeOnTerminate then
>         AThread.Destroy;
> end;


> {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
> procedure TWSocketThrdServer.TerminateThreads;
> var
>     AThread : TWsClientThread;
>     I       : Integer;
> begin
>     for I := 0 to FThreadList.Count - 1 do begin
>         AThread := TWsClientThread(FThreadList[I]);
>         if PostThreadMessage(AThread.ThreadID,
>                              WM_THREAD_TERMINATE, 0, 0) then begin
>             InterlockedDecrement(FThreadCount);
>             Sleep(0);
>         end;
>     end;
> end;


> destructor TWSocketThrdServer.Destroy;
> var
>     WaitRes : LongWord;
>     Dummy   : Byte;
>     Msg     : tagMsg;
> begin
>     Pause; // while waiting for our threads don't accept new clients!!
>     TerminateThreads;
>     try
>         if FThreadList.Count > 0 then
>         repeat
>             WaitRes := MsgWaitForMultipleObjects(0, Dummy, FALSE, 500,
>                                              QS_POSTMESSAGE or 
> QS_SENDMESSAGE);
>             if WaitRes = WAIT_FAILED then
>                 raise Exception.Create('Wait for threads failed ' +
>                                        SysErrorMessage(GetLastError))
>             else if WaitRes = WAIT_OBJECT_0 then
>                 while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
>                 begin
>                     TranslateMessage(Msg);
>                     DispatchMessage(Msg);
>                 end;
>         until FThreadList.Count = 0;
>     finally
>         inherited Destroy;
>         FreeAndNil(FThreadList);        
>     end;
> end;


-- 
To unsubscribe or change your settings for TWSocket mailing list
please goto http://www.elists.org/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be

Reply via email to