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

Reply via email to