Francois PIETTE wrote: > Is the AV occuring when the application is destroying ?
Yes, I'll give it a trial tomorrow. But generally, shouldn't we disable triggers when the component is in status destroying? That would avoid many possible troubles at the root? Arno > If yes, then maybe Display is the culprit, trying to display something on > a TMemo which is already destroyed. > > -- > [EMAIL PROTECTED] > http://www.overbyte.be > > ----- Original Message ----- > From: "Arno Garrels" <[EMAIL PROTECTED]> > To: "ICS support mailing" <twsocket@elists.org> > Sent: Wednesday, March 01, 2006 7:31 PM > Subject: Re: [twsocket] Triggering events > whencsDestroyingisinComponentState? > > >> Francois PIETTE wrote: >>> Do you know what is causing the AV ? >>> I mean the AV occur from OndataAvailable but when accessing what ? >> >> Hard to say. Here's an image: http://www.duodata.de/misc/thrdAV.png >> >> The first line where the IDE shows the green arrow in procedure >> TSimpleThreadedSslServerForm.ClientDataAvailable after the AV is >> => ProcessData(Sender as TMyClient); >> Previous line is Display() but Display is wrapped in a critical section. >> The AV happens when I destroy the component while the stressing client >> is still trying to do his work. >> >>>> From the destructor, the component is still allocated. >> >> Yes >> >> Arno >> >>> >>> -- >>> [EMAIL PROTECTED] >>> http://www.overbyte.be >>> >>> ----- Original Message ----- >>> From: "Arno Garrels" <[EMAIL PROTECTED]> >>> To: "ICS support mailing" <twsocket@elists.org> >>> Sent: Wednesday, March 01, 2006 5:19 PM >>> Subject: Re: [twsocket] Triggering events >>> whencsDestroyingisinComponentState? >>> >>> >>>> 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 >> -- >> 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 -- 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