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] Threaded TWSocketServer derivation
Hello Arno, I suggest to write a little logging code to a file in the ThreadDetach method. Just to see if you get there, and how far you get inthere. I think this is the most easy to find out since you dont have the AV always. --- Rgds, Wilfried [TeamICS] http://www.overbyte.be/eng/overbyte/teamics.html http://www.mestdagh.biz Friday, November 4, 2005, 12:14, Arno Garrels wrote: > 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: > 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 System
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" 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: > 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 madEx
Re: [twsocket] Threaded TWSocketServer derivation
Arno Garrels a écrit : > 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] > if Assigned(Client) then > Client.ThreadDetach; <= *AV here Hi Arno, Have you tried to look at *what* causes the AV ? is it Client which is already destroyed (but that Client variable is not "Niled") or is it something withiin ThreadDetach proc which is "Niled" (or a variable within destroyed but not "niled") ? -- Guillaume MAISON - [EMAIL PROTECTED] 83, Cours Victor Hugo 47000 AGEN Tél : 05 53 87 91 48 - Fax : 05 53 68 73 50 e-mail : [EMAIL PROTECTED] - Web : http://nauteus.com -- 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