Re: [twsocket] bug in TCustomWSocket? - 100% cpu; continues calls to OnDataAvailable while no data was received

2008-04-18 Thread Merijn Bosma
Sorry for the late reply, we've had an expo this week which needed some 
(a lot) of attention.

I didn't find any calls to ProcessMessages(). This socket runs in it's 
own thread, so a call to ProcessMessages() would have been out of place. 
I did find something else though.
Even though the server socket had it's MultiThreaded property set to 
true, the client socket it spawns did not have this property set to true 
explicitly. Therefor ICS was calling ProcessMessages() itself now and 
then. Maybe it would be a good idea to let TCustomWSocketServer set 
Multithreaded of newly created clients to the same value it has itself? 
WSocketS.pas around line 360.

Anyway, back to my problem, because it's still here :|

All sockets have now their MultiThreaded property set to true. I removed 
the wsoNoReceiveLoop again, because it didn't seem to have to do 
anything with the problem.
 I've added some logging when the problem occurs, so I have some new 
information.

The OnDataAvailable event is never triggered from within itself. So it 
seems not to be caused by calling a messagepump in the event, which 
triggers the event again!
If in the loop, in each event there is no data to receive.
If in the loop, in each event, error = 0
If in the loop, in each event I note LastError before, and after I call 
ReceiveStr(). I do this because TCustomWSocket.ASyncReceive, which 
triggers the event, looks at FLastError to decide it should call the 
event again. In both cases I had the extended logging, LastError was set 
to a non-zero value. In the first case it was 10054, and the second case 
it was 10034. LastError was the same before and after the call to 
ReceiveStr().

Besides the extended logging, I built in a mechanism which automatically 
dumps a call stack of the thread the socket runs in, 60 seconds after I 
get stuck in the 'loop'. Of course this call stack is just a snapshot 
somewhere in the loop, but since I got the same call stack a couple of 
times now, I'm pretty sure this is how the OnDataAvailable event is 
triggered. The strange thing is, that there always seems to be a strange 
'jump' in the call stack which I can't explain (or probably which I 
don't understand): It goes from Do_FD_READ to AsyncReceive (normal), but 
before AsyncReceive is actually run, it jumps to TriggerDataSent (?). 
After that some other strange things in the call stack.

See the call stack here, the calls to CheckForPendingMessages are 
calls to methods which call the messagepumps for different controls, 
amongst which TCustomWSocket.ProcessMessages().

I really hope someone can give me some more pointers in the right direction!

callstack:

|7C90E9FD|ntdll.dll   | 
|   |NtWriteFile | |
|7C810E10|kernel32.dll| 
|   |WriteFile   | |
|006C268B|AviaVox.exe |ServerTimedSocket.pas
|TServerTimedSocket |_Log|291[16]  |
|006C2528|AviaVox.exe |ServerTimedSocket.pas
|TServerTimedSocket |_Log|275[0]   |
|006C27DB|AviaVox.exe |ServerTimedSocket.pas
|TServerTimedSocket |OnDataAvailable |305[8]   |
|005CBFA0|AviaVox.exe |WSocket.pas  
|TCustomWSocket |TriggerDataAvailable|5970[24] |
|005CBF80|AviaVox.exe |WSocket.pas  
|TCustomWSocket |TriggerDataAvailable|5946[0]  |
|005CDA0B|AviaVox.exe |WSocket.pas  
|TCustomSocksWSocket|TriggerDataAvailable|6504[2]  |
|005CD9E0|AviaVox.exe |WSocket.pas  
|TCustomSocksWSocket|TriggerDataAvailable|6502[0]  |
|005CE90C|AviaVox.exe |WSocket.pas  
|TCustomLineWSocket |TriggerDataAvailable|7065[7]  |
|005C8C58|AviaVox.exe |WSocket.pas  
|TCustomWSocket |ASyncReceive|4204[6]  |
|005C6DB3|AviaVox.exe |WSocket.pas  
|   |WSocket_Synchronized_ioctlsocket|2136[3]  |
|005C6D8C|AviaVox.exe |WSocket.pas  
|   |WSocket_Synchronized_ioctlsocket|2133[0]  |
|005C8CDD|AviaVox.exe |WSocket.pas  
|TCustomWSocket |ASyncReceive|4226[28] |
|71AB42F5|WS2_32.dll  | 
|   |send| |
|71AB42FC|WS2_32.dll  | 
|   |send| |
|005C6CF7|AviaVox.exe |WSocket.pas  
|   |WSocket_Synchronized_send   |2098[3]  |
|005CBEDC|AviaVox.exe |WSocket.pas  
|TCustomWSocket |TriggerSendData |5907[0]  |
|005C87A9|AviaVox.exe |WSocket.pas  
|TCustomWSocket

Re: [twsocket] bug in TCustomWSocket? - 100% cpu; continues calls to OnDataAvailable while no data was received

2008-04-18 Thread Merijn Bosma
I just noticed the layout of the call stack got kind of messed up, so 
I've attached as a text file.


Merijn Bosma wrote:
Sorry for the late reply, we've had an expo this week which needed some 
(a lot) of attention.


I didn't find any calls to ProcessMessages(). This socket runs in it's 
own thread, so a call to ProcessMessages() would have been out of place. 
I did find something else though.
Even though the server socket had it's MultiThreaded property set to 
true, the client socket it spawns did not have this property set to true 
explicitly. Therefor ICS was calling ProcessMessages() itself now and 
then. Maybe it would be a good idea to let TCustomWSocketServer set 
Multithreaded of newly created clients to the same value it has itself? 
WSocketS.pas around line 360.


Anyway, back to my problem, because it's still here :|

All sockets have now their MultiThreaded property set to true. I removed 
the wsoNoReceiveLoop again, because it didn't seem to have to do 
anything with the problem.
 I've added some logging when the problem occurs, so I have some new 
information.


The OnDataAvailable event is never triggered from within itself. So it 
seems not to be caused by calling a messagepump in the event, which 
triggers the event again!

If in the loop, in each event there is no data to receive.
If in the loop, in each event, error = 0
If in the loop, in each event I note LastError before, and after I call 
ReceiveStr(). I do this because TCustomWSocket.ASyncReceive, which 
triggers the event, looks at FLastError to decide it should call the 
event again. In both cases I had the extended logging, LastError was set 
to a non-zero value. In the first case it was 10054, and the second case 
it was 10034. LastError was the same before and after the call to 
ReceiveStr().


Besides the extended logging, I built in a mechanism which automatically 
dumps a call stack of the thread the socket runs in, 60 seconds after I 
get stuck in the 'loop'. Of course this call stack is just a snapshot 
somewhere in the loop, but since I got the same call stack a couple of 
times now, I'm pretty sure this is how the OnDataAvailable event is 
triggered. The strange thing is, that there always seems to be a strange 
'jump' in the call stack which I can't explain (or probably which I 
don't understand): It goes from Do_FD_READ to AsyncReceive (normal), but 
before AsyncReceive is actually run, it jumps to TriggerDataSent (?). 
After that some other strange things in the call stack.


See the call stack here, the calls to CheckForPendingMessages are 
calls to methods which call the messagepumps for different controls, 
amongst which TCustomWSocket.ProcessMessages().


I really hope someone can give me some more pointers in the right direction!

callstack:

|7C90E9FD|ntdll.dll   | 
|   |NtWriteFile | |
|7C810E10|kernel32.dll| 
|   |WriteFile   | |
|006C268B|AviaVox.exe |ServerTimedSocket.pas
|TServerTimedSocket |_Log|291[16]  |
|006C2528|AviaVox.exe |ServerTimedSocket.pas
|TServerTimedSocket |_Log|275[0]   |
|006C27DB|AviaVox.exe |ServerTimedSocket.pas
|TServerTimedSocket |OnDataAvailable |305[8]   |
|005CBFA0|AviaVox.exe |WSocket.pas  
|TCustomWSocket |TriggerDataAvailable|5970[24] |
|005CBF80|AviaVox.exe |WSocket.pas  
|TCustomWSocket |TriggerDataAvailable|5946[0]  |
|005CDA0B|AviaVox.exe |WSocket.pas  
|TCustomSocksWSocket|TriggerDataAvailable|6504[2]  |
|005CD9E0|AviaVox.exe |WSocket.pas  
|TCustomSocksWSocket|TriggerDataAvailable|6502[0]  |
|005CE90C|AviaVox.exe |WSocket.pas  
|TCustomLineWSocket |TriggerDataAvailable|7065[7]  |
|005C8C58|AviaVox.exe |WSocket.pas  
|TCustomWSocket |ASyncReceive|4204[6]  |
|005C6DB3|AviaVox.exe |WSocket.pas  
|   |WSocket_Synchronized_ioctlsocket|2136[3]  |
|005C6D8C|AviaVox.exe |WSocket.pas  
|   |WSocket_Synchronized_ioctlsocket|2133[0]  |
|005C8CDD|AviaVox.exe |WSocket.pas  
|TCustomWSocket |ASyncReceive|4226[28] |
|71AB42F5|WS2_32.dll  | 
|   |send| |
|71AB42FC|WS2_32.dll  | 
|   |send| |
|005C6CF7|AviaVox.exe |WSocket.pas  
|   |WSocket_Synchronized_send   |2098[3]  |
|005CBEDC|AviaVox.exe |WSocket.pas