Isn't it possible that the client is already destroyed when you call 
ThreadDetech ? If yes,
accessing "self" in ThreadDetach cause the access violation.

Each time a client is freed, it must be remove from the list to avoid this 
problem.

--
Contribute to the SSL Effort. Visit
http://www.overbyte.be/eng/ssl.html
--
[EMAIL PROTECTED]
Author of ICS (Internet Component Suite, freeware)
Author of MidWare (Multi-tier framework, freeware)
http://www.overbyte.be



----- Original Message ----- 
From: "Arno Garrels" <[EMAIL PROTECTED]>
To: "ICS support mailing" <twsocket@elists.org>
Sent: Friday, November 04, 2005 12:14 PM
Subject: [twsocket] Threaded TWSocketServer derivation


> 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

-- 
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