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