Re: [twsocket] 100% CPU usage if data is not processed immediately
Hello Olivier, I can't use LineMode, what is transferred is purely binary. See http://wiki.overbyte.be/wiki/index.php/Sending_and_receiving_data that discusses some possible data transfer modes. buffer and rely on the one from the API itself. I tried it, it works fine, but is it be a nice thing to do? Are there any risks associated with this behavior? if you only receive if you have complete data packet instead of receiving every time winsock want to give you a partial data packet then you design an untested situation because TWSocket is designed to deliver data every time winsock has data. so not by design and not tested seems discouraged to me. but also if you do so and only receive if complete data is received, then how do you know data is complete ? I mean you can only know by examing the data so by receive it ? So I think using your own buffer is the best thing to do. --- Rgds, Wilfried [TeamICS] http://www.overbyte.be/eng/overbyte/teamics.html http://www.mestdagh.biz -- 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] 100% CPU usage if data is not processed immediately
Wilfried Mestdagh wrote: Hello Olivier, I can't use LineMode, what is transferred is purely binary. See http://wiki.overbyte.be/wiki/index.php/Sending_and_receiving_data that discusses some possible data transfer modes. Thanks for that link. My code is for a transport layer that should not make any assumption on what is transferred, so binary mode without any line buffering is the way to go for me. buffer and rely on the one from the API itself. I tried it, it works fine, but is it be a nice thing to do? Are there any risks associated with this behavior? if you only receive if you have complete data packet instead of receiving every time winsock want to give you a partial data packet then you design an untested situation because TWSocket is designed to deliver data every time winsock has data. so not by design and not tested seems discouraged to me. but also if you do so and only receive if complete data is received, then how do you know data is complete ? I mean you can only know by examing the data so by receive it ? It's the packets received before that indicate the length and all that, but my layer does not know it. It is just being requested for N bytes to be put in a given buffer. So if N is greater than what is available, there is a problem anyway. So I think using your own buffer is the best thing to do. Yes, that's what I did in the end, but I reduced the size of this buffer (1024 instead of 2048) as most data transfers are for small chunks (less than 100 bytes). This way I don't use too much memory per client connection. I'll do some benchmarking on this, but I don't see any reason why I would need a bigger buffer for my layer, per client connection. In the end, I do use wsoNoReceiveLoop anyway as the message pump must continue working even if there is more data for one socket. This way it does not stalls the other sockets associated to the message pump. Thanks for the help, all is fine now. Regards Olivier -- 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] 100% CPU usage if data is not processed immediately
Francois Piette wrote: Designing a system having in mind variable length data will result in a better system. Variable length can do fixed length easily, not the reverse. It is variable length, but I'm only writing the socket layer. Basically, I'm given data in an unknown form and being asked for a given amount of data. The rest of the protocol is not up to me, so I cannot make any assumption on what my layer will transmit. From what I see, the layers above are designed to cope with the fact that I only give as much data as I have when I'm being asked for it so there are no issues here. It's just that switching to line mode or not depending on the content is not possible, my layer must not have this sort of intelligence. This is because it allows to write other layers that use other transportation protocols such as Serial port, UDP, bluetooth and so on... Thanks for the help Cheers Olivier -- 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
[twsocket] 100% CPU usage if data is not processed immediately
Hi, I'm using TWSocketS with a custom TWSocket derived class called TMyClientSocket to implement a TCP/IP server. I have overridden TriggerDataAvailable in TMyClientSocket in such a way: function TROAsyncSuperTcpServerSocketClient.TriggerDataAvailable( Error: Word): Boolean; begin inherited TriggerDataAvailable(Error); NotifyDataAvailable; // Return True to indicate that we do not want the data to be dropped. Result := True; end; The NotifyDataAvailable sets a flag in an object associated to the client socket that will then read the available bytes. But it will not do so immediately, clearly after the TriggerDataAvailable has returned. This does not prove to be a problem because all data is queued up until it is actually read, up to a certain limit that I doubt I'll ever reach. Usually, this takes a few milliseconds but it happens sometimes that it takes up to 10 seconds. Ok, this is relatively rare for production use, but because I'm doing tests on the server, I'm seeing this quite often. And this is where I have a problem, because while the data is waiting to be read, the processor usage is 100% (or 1CPU on multi cpu systems). I traced it and that's because TCustomWSocket.ASyncReceive does a loop while the bMore variable is True, without ever giving the operating system to do anything. Hence the 100%CPU usage. To me, this could be avoided by adding the following two lines at the end of the loop: if bMore then Sleep(1); { to avoid 100% CPU } At line 4231, right after the end of the try except block. To me this has little to no effect as the sleep is only done when bMore is True. What do you think of this proposal? Any comments are welcome. Regards Olivier Sannier -- 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] 100% CPU usage if data is not processed immediately
Hello Olivier, The NotifyDataAvailable sets a flag in an object associated to the client socket that will then read the available bytes. But it will not do so immediately That's the problem. You have to read all available data In the OnDataAvailable event. If you do not then OnDataAvailable will fire again in a loop where you must receive the rest of the data, or if you set wsoNoReceiveLoop in ComponentOptions property then it is fired using a custom message handler. So the Sleep is not needed. Also it is a bad idea because if there is high speed data received and more than will be received in the event it will delay the reception of data during a time slice (10..20 millisec depending on the OS) and will grow winsock internal receive buffer, because during the Sleep the message pump is not working. --- Rgds, Wilfried [TeamICS] http://www.overbyte.be/eng/overbyte/teamics.html http://www.mestdagh.biz -- 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] 100% CPU usage if data is not processed immediately
Wilfried Mestdagh wrote: Hello Olivier, The NotifyDataAvailable sets a flag in an object associated to the client socket that will then read the available bytes. But it will not do so immediately That's the problem. You have to read all available data In the OnDataAvailable event. If you do not then OnDataAvailable will fire again in a loop where you must receive the rest of the data, or if you set wsoNoReceiveLoop in ComponentOptions property then it is fired using a custom message handler. That's what I thought, but then again, this means I need to have a buffer of my own, and I have no idea which size it should be. 1k, 10k, more? So the Sleep is not needed. Also it is a bad idea because if there is high speed data received and more than will be received in the event it will delay the reception of data during a time slice (10..20 millisec depending on the OS) and will grow winsock internal receive buffer, because during the Sleep the message pump is not working. I know that, but with 100%CPU usage, the handling of messages is stopped anyway as well as no other thread will be able to take control. Well, maybe on a multi core, but not on single core machines. -- 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] 100% CPU usage if data is not processed immediately
Olivier Sannier wrote: if bMore then Sleep(1); { to avoid 100% CPU } At line 4231, right after the end of the try except block. To me this has little to no effect as the sleep is only done when bMore is True. What do you think of this proposal? That would slow down performance when you use the component as designed. When the application is idle it should read incomming data immediately. There is no reason to wait until a certain amount of data is pending to be read from winsock. -- Arno Garrels [TeamICS] http://www.overbyte.be/eng/overbyte/teamics.html Olivier Sannier wrote: Hi, I'm using TWSocketS with a custom TWSocket derived class called TMyClientSocket to implement a TCP/IP server. I have overridden TriggerDataAvailable in TMyClientSocket in such a way: function TROAsyncSuperTcpServerSocketClient.TriggerDataAvailable( Error: Word): Boolean; begin inherited TriggerDataAvailable(Error); NotifyDataAvailable; // Return True to indicate that we do not want the data to be dropped. Result := True; end; The NotifyDataAvailable sets a flag in an object associated to the client socket that will then read the available bytes. But it will not do so immediately, clearly after the TriggerDataAvailable has returned. This does not prove to be a problem because all data is queued up until it is actually read, up to a certain limit that I doubt I'll ever reach. Usually, this takes a few milliseconds but it happens sometimes that it takes up to 10 seconds. Ok, this is relatively rare for production use, but because I'm doing tests on the server, I'm seeing this quite often. And this is where I have a problem, because while the data is waiting to be read, the processor usage is 100% (or 1CPU on multi cpu systems). I traced it and that's because TCustomWSocket.ASyncReceive does a loop while the bMore variable is True, without ever giving the operating system to do anything. Hence the 100%CPU usage. To me, this could be avoided by adding the following two lines at the end of the loop: if bMore then Sleep(1); { to avoid 100% CPU } At line 4231, right after the end of the try except block. To me this has little to no effect as the sleep is only done when bMore is True. What do you think of this proposal? Any comments are welcome. Regards Olivier Sannier -- 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] 100% CPU usage if data is not processed immediately
Hello Olivier, That's what I thought, but then again, this means I need to have a buffer of my own, and I have no idea which size it should be. 1k, 10k, more? Yes. TWSocket is designed to buffer incoming data for you if you use LineMode. That is when you have your data terminated with a certain character (or a string of characters). If you dont use LineMode then yes you have to buffer on your own. I know that, but with 100%CPU usage, the handling of messages is stopped anyway as well as no other thread will be able to take control. Well, maybe on a multi core, but not on single core machines. Agree, but there is also a componentOptions property wsoNoReceiveLoop which will fire OnDataAvailable again using a custom message handler. In that case message pump stay working. --- Rgds, Wilfried [TeamICS] http://www.overbyte.be/eng/overbyte/teamics.html http://www.mestdagh.biz Wednesday, September 26, 2007, 15:38, Olivier Sannier wrote: Wilfried Mestdagh wrote: Hello Olivier, The NotifyDataAvailable sets a flag in an object associated to the client socket that will then read the available bytes. But it will not do so immediately That's the problem. You have to read all available data In the OnDataAvailable event. If you do not then OnDataAvailable will fire again in a loop where you must receive the rest of the data, or if you set wsoNoReceiveLoop in ComponentOptions property then it is fired using a custom message handler. That's what I thought, but then again, this means I need to have a buffer of my own, and I have no idea which size it should be. 1k, 10k, more? So the Sleep is not needed. Also it is a bad idea because if there is high speed data received and more than will be received in the event it will delay the reception of data during a time slice (10..20 millisec depending on the OS) and will grow winsock internal receive buffer, because during the Sleep the message pump is not working. I know that, but with 100%CPU usage, the handling of messages is stopped anyway as well as no other thread will be able to take control. Well, maybe on a multi core, but not on single core machines. -- 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] 100% CPU usage if data is not processed immediately
Olivier Sannier wrote: That's what I thought, but then again, this means I need to have a buffer of my own, and I have no idea which size it should be. 1k, 10k, more? You have to use some buffer, its size depends on your protocol. I.e. the client could send the data length as the first byte. Or write received data to a stream if you like. Source code of the high level ICS components demonstrate how to do that in detail. -- Arno Garrels [TeamICS] http://www.overbyte.be/eng/overbyte/teamics.html -- 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