Hello,

After a big fight with deadlocks and race conditions for one day my
threaded TWSocketServer derivation is now working stable. 
(tested with Wilfrieds GPRS Client and other stressing clients)
But.. I have still a tiny problem with ThreadDetach.
An AV is sometimes raised (see MadExcept trace below) from within
the Execute procedure when csDestroying is in client's ComponentState.
I can work around that by checking for (Client.ComponentState = [])
but I don't think it's good practice. It happens only when the
destructor is called and a lot of threads are busy. 

Any idea?

---
Arno Garrels [TeamICS]


 
Destructor of TThrdWSocketServer terminates the threads:

for I := 0 to FThreadList.Count -1 do
begin
    AThread := TThread(FThreadList[I]);
    if PostThreadMessage(AThread.ThreadID, WM_THREAD_TERMINATE, 0, 0) then
    begin
            Dec(FThreadCount);
            Sleep(0);
    end;
end;

WM_THREAD_TERMINATE exits PumpMessages()

procedure TWSClientThread.Execute;
var
    I      : Integer;
    Client : TThrdWSocketClient;
    Msg    : TMsg;
begin
    try
        { Initialize thread's message queue }
        PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE);
        SetEvent(EventArray[THREAD_READY_EVENT]);
        FReadyForMsgs := TRUE;
        FClients := TList.Create;
        try
            PumpMessages(True);
            if not Terminated then
                Terminate;
            InterlockedDecrement(FServer.FThreadCount);
            for I := 0 to FClients.Count -1 do 
            begin
                Client := FClients[I];
                if Assigned(Client) then
                    Client.ThreadDetach; <= *********AV here************
            end;
        finally
            FClients.Free;
            FClients := nil;
        end;
    finally
        PostMessage(FServer.Handle, WM_THREAD_TERMINATED, Integer(Self), 0);
        { Just to make sure the  main thread isn't waiting for this thread }
        { signal the events }
        SetEvent(EventArray[CLIENT_REMOVED_EVENT]);
        SetEvent(EventArray[CLIENT_ATTACHED_EVENT]);
    end;
end; 
 

exception class   : EAccessViolation
exception message : Accessviolation at Address 0048C6C9 in Module 'TcpSrv.exe'. 
Read from Address 00000038.

thread $26c (TWsClientThread):
0048c6c9 TcpSrv.exe WSocket    4159 TCustomWSocket.ThreadDetach
00495706 TcpSrv.exe WSocketS    906 TWsClientThread.Execute
00442a36 TcpSrv.exe Classes    9372 ThreadProc
004049dc TcpSrv.exe System    11554 ThreadWrapper
0042bcbb TcpSrv.exe madExcept       ThreadExceptFrame
>> created by main thread ($6ec) at:
0049539a TcpSrv.exe WSocketS    787 TWsClientThread.Create

main thread ($6ec):
7c91eb94 ntdll.dll  KiFastSystemCallRet
7c91e64c ntdll.dll  NtSetInformationThread

thread $3fc: <priority:1>
7c91eb94 ntdll.dll  KiFastSystemCallRet
7c91e319 ntdll.dll  NtRemoveIoCompletion

thread $314:
>> stack not accessible

thread $798:
>> stack not accessible

thread $778:
>> stack not accessible

thread $90 (TWsClientThread):
7c91eb94 ntdll.dll                    KiFastSystemCallRet
7c91e9be ntdll.dll                    NtWaitForSingleObject
7c8025d5 kernel32.dll                 WaitForSingleObjectEx
7c80253d kernel32.dll                 WaitForSingleObject
00426e8a TcpSrv.exe   madExcept       HandleException
0042bd4d TcpSrv.exe   madExcept       HookedTThreadExecute
7c91eaf5 ntdll.dll                    KiUserExceptionDispatcher
0048c6c9 TcpSrv.exe   WSocket    4159 TCustomWSocket.ThreadDetach
00495706 TcpSrv.exe   WSocketS    906 TWsClientThread.Execute
00442a36 TcpSrv.exe   Classes    9372 ThreadProc
004049dc TcpSrv.exe   System    11554 ThreadWrapper
0042bcbb TcpSrv.exe   madExcept       ThreadExceptFrame
>> created by main thread ($6ec) at:
0049539a TcpSrv.exe   WSocketS    787 TWsClientThread.Create

thread $728:
>> stack not accessible

thread $374 (TWsClientThread):
7c91eb94 ntdll.dll                    KiFastSystemCallRet
7c91e9be ntdll.dll                    NtWaitForSingleObject
7c8025d5 kernel32.dll                 WaitForSingleObjectEx
7c80253d kernel32.dll                 WaitForSingleObject
00426e8a TcpSrv.exe   madExcept       HandleException
0042bd4d TcpSrv.exe   madExcept       HookedTThreadExecute
7c91eaf5 ntdll.dll                    KiUserExceptionDispatcher
0042bd26 TcpSrv.exe   madExcept       HookedTThreadExecute
00442a36 TcpSrv.exe   Classes    9372 ThreadProc
004049dc TcpSrv.exe   System    11554 ThreadWrapper
0042bcbb TcpSrv.exe   madExcept       ThreadExceptFrame
>> created by main thread ($6ec) at:
0049539a TcpSrv.exe   WSocketS    787 TWsClientThread.Create

disassembling:
0048c67c      public WSocket.TCustomWSocket.ThreadDetach:  ; function entry 
point
0048c67c 4153   push    ebp
0048c67d        mov     ebp, esp
0048c67f        push    ecx
0048c680        mov     [ebp-4], eax
0048c683 4154   call    -$85750 ($406f38)      ; Windows.GetCurrentThreadId
0048c683
0048c688        mov     edx, [ebp-4]
0048c68b        cmp     eax, [edx+$548]
0048c691        jz      loc_48c6a0
0048c691
0048c693 4155   mov     edx, $48c6d8           ; 'Cannot detach from other 
thread'
0048c698        mov     eax, [ebp-4]
0048c69b        mov     ecx, [eax]
0048c69d        call    dword ptr [ecx+$64]
0048c69d
0048c6a0      loc_48c6a0:
0048c6a0 4157   mov     eax, [ebp-4]
0048c6a3        cmp     dword ptr [eax+$458], -1
0048c6aa        jz      loc_48c6c4
0048c6aa
0048c6ac 4158   push    0
0048c6ae        xor     ecx, ecx
0048c6b0        mov     eax, [ebp-4]
0048c6b3        mov     edx, [eax+$40]
0048c6b6        mov     eax, [ebp-4]
0048c6b9        mov     eax, [eax+$458]
0048c6bf        call    -$1698 ($48b02c)       ; 
WSocket.WSocket_Synchronized_WSAAsyncSelect
0048c6bf
0048c6c4      loc_48c6c4:
0048c6c4 4159   mov     eax, [ebp-4]
0048c6c7        mov     edx, [eax]
0048c6c9      > call    dword ptr [edx+$38]
0048c6c9
0048c6cc 4160   pop     ecx
0048c6cd        pop     ebp
0048c6ce        ret   
-- 
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