[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 0038. thread $26c (TWsClientThread): 0048c6c9 TcpSrv.exe WSocket4159 TCustomWSocket.ThreadDetach 00495706 TcpSrv.exe WSocketS906 TWsClientThread.Execute 00442a36 TcpSrv.exe Classes9372 ThreadProc 004049dc TcpSrv.exe System11554 ThreadWrapper 0042bcbb TcpSrv.exe madExcept ThreadExceptFrame created by main thread ($6ec) at: 0049539a TcpSrv.exe WSocketS787 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.dllKiFastSystemCallRet 7c91e9be ntdll.dllNtWaitForSingleObject 7c8025d5 kernel32.dll WaitForSingleObjectEx 7c80253d kernel32.dll WaitForSingleObject 00426e8a TcpSrv.exe madExcept HandleException 0042bd4d TcpSrv.exe madExcept HookedTThreadExecute 7c91eaf5 ntdll.dllKiUserExceptionDispatcher 0048c6c9 TcpSrv.exe WSocket4159 TCustomWSocket.ThreadDetach 00495706 TcpSrv.exe WSocketS906 TWsClientThread.Execute 00442a36 TcpSrv.exe Classes9372 ThreadProc 004049dc TcpSrv.exe System11554 ThreadWrapper 0042bcbb TcpSrv.exe madExcept ThreadExceptFrame created by main thread ($6ec) at: 0049539a TcpSrv.exe WSocketS787 TWsClientThread.Create thread $728: stack not accessible thread $374 (TWsClientThread): 7c91eb94 ntdll.dllKiFastSystemCallRet 7c91e9be ntdll.dllNtWaitForSingleObject 7c8025d5 kernel32.dll WaitForSingleObjectEx 7c80253d kernel32.dll WaitForSingleObject 00426e8a TcpSrv.exe madExcept HandleException 0042bd4d TcpSrv.exe madExcept HookedTThreadExecute 7c91eaf5 ntdll.dllKiUserExceptionDispatcher 0042bd26 TcpSrv.exe madExcept HookedTThreadExecute 00442a36 TcpSrv.exe Classes9372 ThreadProc 004049dc TcpSrv.exe System11554 ThreadWrapper 0042bcbb TcpSrv.exe madExcept ThreadExceptFrame created by main thread ($6ec) at: 0049539a TcpSrv.exe WSocketS787 TWsClientThread.Create disassembling: 0048c67c public WSocket.TCustomWSocket.ThreadDetach: ; function entry point 0048c67c 4153 pushebp 0048c67dmov ebp, esp 0048c67fpushecx 0048c680mov [ebp-4], eax 0048c683 4154 call-$85750 ($406f38) ; Windows.GetCurrentThreadId 0048c683 0048c688mov edx, [ebp-4] 0048c68bcmp eax, [edx+$548] 0048c691jz loc_48c6a0
Re: [twsocket] Threaded TWSocketServer derivation
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 0038. thread $26c (TWsClientThread): 0048c6c9 TcpSrv.exe WSocket4159 TCustomWSocket.ThreadDetach 00495706 TcpSrv.exe WSocketS906 TWsClientThread.Execute 00442a36 TcpSrv.exe Classes9372 ThreadProc 004049dc TcpSrv.exe System11554 ThreadWrapper 0042bcbb TcpSrv.exe madExcept ThreadExceptFrame created by main thread ($6ec) at: 0049539a TcpSrv.exe WSocketS787 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.dllKiFastSystemCallRet 7c91e9be ntdll.dllNtWaitForSingleObject 7c8025d5 kernel32.dll WaitForSingleObjectEx 7c80253d kernel32.dll WaitForSingleObject 00426e8a TcpSrv.exe madExcept HandleException 0042bd4d TcpSrv.exe madExcept HookedTThreadExecute 7c91eaf5 ntdll.dllKiUserExceptionDispatcher 0048c6c9 TcpSrv.exe WSocket4159 TCustomWSocket.ThreadDetach 00495706 TcpSrv.exe WSocketS906 TWsClientThread.Execute 00442a36 TcpSrv.exe Classes9372 ThreadProc 004049dc TcpSrv.exe System11554 ThreadWrapper 0042bcbb TcpSrv.exe madExcept ThreadExceptFrame created by main thread ($6ec) at: 0049539a TcpSrv.exe WSocketS787 TWsClientThread.Create thread $728: stack not accessible thread $374 (TWsClientThread): 7c91eb94 ntdll.dllKiFastSystemCallRet 7c91e9be ntdll.dllNtWaitForSingleObject 7c8025d5 kernel32.dll WaitForSingleObjectEx 7c80253d kernel32.dll WaitForSingleObject 00426e8a TcpSrv.exe madExcept HandleException 0042bd4d TcpSrv.exe madExcept HookedTThreadExecute 7c91eaf5 ntdll.dll
Re: [twsocket] Threaded TWSocketServer derivation
Francois Piette wrote: Isn't it possible that the client is already destroyed when you call ThreadDetech ? If yes, accessing self in ThreadDetach cause the access violation. Yes, very simple, that seems to be the reason. I think I've fixed it by just waiting for all threads return and being freed manually in the main thread before going ahead in the destructor. Sometimes, when bugs are too obvious I don't find them :( --- Arno Garrels [TeamICS] -- 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
Re: [twsocket] Fw: TCustomSmtpClient.AuthGetType
From: Vander Clock Stephane [..] I think you must replace S := Copy(S, 5, Length(S)); by S := Copy(S, 6, Length(S)); I don't know why, length of both strings is 5 not 6. Typically the lines in question of a EHLO response look like 250-AUTH=LOGIN CRAM-MD5 PLAIN 250-AUTH CRAM-MD5 LOGIN PLAIN --- Arno Garrels [TeamICS] -- 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
Re: [twsocket] Fw: TCustomSmtpClient.AuthGetType
DZ-Jay wrote: since the CompareText calls Copy() with an Index of 1, which means that it starts to delete at the second character, not to mention the call to Delete() uses an Index of 1 also. This should have been: which means that it starts to copy at the second character... Sorry, dZ. -- 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