Hello Arno, You are right. If you destroy a component you dont wants data from it anuymore.
--- Rgds, Wilfried [TeamICS] http://www.overbyte.be/eng/overbyte/teamics.html http://www.mestdagh.biz Wednesday, March 1, 2006, 19:46, Arno Garrels wrote: > Wilfried Mestdagh wrote: >> 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. > Yes, but if you are already in the destructor the question is, whether it > is still required to read remaining data from the buffer or not? > I think it isn't required. > Arno >> >> --- >> 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