Thread: Re: [Dclib-devel] non blocking patch
Brought to you by:
davisking
|
From: Davis K. <dav...@us...> - 2009-05-18 00:03:55
|
I have been testing out this patch for a while (on windows and linux) and trying to think if there are any funny corner cases. I also spent a lot of time a few years ago trying to work something like this into the connection object and ended up giving up but I forgot why until just now. Anyway, I found a problem related to sending data via send(). The problem is that send() will block, even if select() says it won't, if you give it a buffer larger than a certain value (the value depends on your platform and isn't at all portable). Linux allows you to set the MSG_DONTWAIT flag which fixes the issue but MSG_DONTWAIT isn't a POSIX thing and so isn't portable to other platforms. See http://www.opengroup.org/onlinepubs/009695399/functions/send.html for example. I think the only safe way to get this to work is to create the socket in non-blocking mode to begin with. Then we don't have to worry about functions blocking when hidden buffer size limits are hit. So I think that would mean making a new object that explicitly represented a non-blocking socket. I'm not in any dire need for non-blocking sockets so I probably won't be implementing this any time soon. You might also want to check out the asio library ( http://think-async.com/Asio/). It has a whole lot of support for varous kinds of networking modes. It is also, in all probability, the networking library that will eventually make it into C++ standard library. So it might be worth learning just for that reason :) Cheers, Davis On Fri, Apr 17, 2009 at 7:35 PM, miguelg50 <mig...@ve...> wrote: > Davis, > > Attached is the patch for the non-blocking socket changes I've made. I hope > it is useful. > > Miguel |
|
From: Davis K. <dav...@us...> - 2009-05-23 15:06:01
|
Yeah, I think you are right about the non-blocking reading. Right now the only way to implement a timeout on a read operation is to use the dlib::timeout class which is sort of a heavyweight solution. So having non-blocking reading seems like it would be a nice alternative. What do you usually do when you aren't blocking on a call to read? You have to be blocking on a call to something else right? sleep() maybe? Either that or you are spinning in a loop and killing CPU time. Cheers, Davis On Sat, May 23, 2009 at 2:21 AM, Miguel Grinberg <mig...@ve...>wrote: > Hi Davis, > > I guess for the write side this change is more of a "ready_to_send" > function. A non-blocking operation cannot be guaranteed, the only thing you > can ensure is that at least part of your data buffer will get through right > away. > > I'm only using the non-blocking read function right now, that one doesn't > seem to have any side effects, it seems to me that for read with the use of > select you can achieve true non-blocking behavior. > > In my experience non-blocking writing isn't all that common anyway, I > normally use non-blocking I/O to prevent my application from blocking while > waiting for the other end to send data, but when I'm the one sending I don't > mind blocking. > > Thanks for your email. > > Miguel > > Davis King wrote: > >> I have been testing out this patch for a while (on windows and linux) and >> trying to think if there are any funny corner cases. I also spent a lot of >> time a few years ago trying to work something like this into the connection >> object and ended up giving up but I forgot why until just now. >> Anyway, I found a problem related to sending data via send(). The problem >> is that send() will block, even if select() says it won't, if you give it a >> buffer larger than a certain value (the value depends on your platform and >> isn't at all portable). Linux allows you to set the MSG_DONTWAIT flag which >> fixes the issue but MSG_DONTWAIT isn't a POSIX thing and so isn't portable >> to other platforms. >> See http://www.opengroup.org/onlinepubs/009695399/functions/send.html for >> example. >> >> I think the only safe way to get this to work is to create the socket in >> non-blocking mode to begin with. Then we don't have to worry about >> functions blocking when hidden buffer size limits are hit. So I think that >> would mean making a new object that explicitly represented a non-blocking >> socket. >> I'm not in any dire need for non-blocking sockets so I probably won't be >> implementing this any time soon. >> You might also want to check out the asio library ( >> http://think-async.com/Asio/). It has a whole lot of support for varous >> kinds of networking modes. It is also, in all probability, the networking >> library that will eventually make it into C++ standard library. So it might >> be worth learning just for that reason :) >> >> Cheers, >> Davis >> >> On Fri, Apr 17, 2009 at 7:35 PM, miguelg50 <mig...@ve...<mailto: >> mig...@ve...>> wrote: >> >> Davis, >> >> Attached is the patch for the non-blocking socket changes I've >> made. I hope >> it is useful. >> >> Miguel >> >> >> > > |
|
From: Miguel G. <mig...@ve...> - 2009-05-23 18:06:36
|
Well, the problem is not that the call to read blocks, it is that it blocks forever. The readable() method I added has a timeout, so with that I can control for how long I want to block while waiting for data. It is a much cleaner way than using dlib::timeout, which if I understand it correctly would close the connection when the timeout expires. Miguel Davis King wrote: > Yeah, I think you are right about the non-blocking reading. > > Right now the only way to implement a timeout on a read operation is > to use the dlib::timeout class which is sort of a heavyweight > solution. So having non-blocking reading seems like it would be a > nice alternative. > > What do you usually do when you aren't blocking on a call to read? > You have to be blocking on a call to something else right? sleep() > maybe? Either that or you are spinning in a loop and killing CPU time. > > Cheers, > Davis > > On Sat, May 23, 2009 at 2:21 AM, Miguel Grinberg > <mig...@ve... <mailto:mig...@ve...>> wrote: > > Hi Davis, > > I guess for the write side this change is more of a > "ready_to_send" function. A non-blocking operation cannot be > guaranteed, the only thing you can ensure is that at least part of > your data buffer will get through right away. > > I'm only using the non-blocking read function right now, that one > doesn't seem to have any side effects, it seems to me that for > read with the use of select you can achieve true non-blocking > behavior. > > In my experience non-blocking writing isn't all that common > anyway, I normally use non-blocking I/O to prevent my application > from blocking while waiting for the other end to send data, but > when I'm the one sending I don't mind blocking. > > Thanks for your email. > > Miguel > > Davis King wrote: > > I have been testing out this patch for a while (on windows and > linux) and trying to think if there are any funny corner > cases. I also spent a lot of time a few years ago trying to > work something like this into the connection object and ended > up giving up but I forgot why until just now. > Anyway, I found a problem related to sending data via send(). > The problem is that send() will block, even if select() says > it won't, if you give it a buffer larger than a certain value > (the value depends on your platform and isn't at all > portable). Linux allows you to set the MSG_DONTWAIT flag > which fixes the issue but MSG_DONTWAIT isn't a POSIX thing and > so isn't portable to other platforms. > See > http://www.opengroup.org/onlinepubs/009695399/functions/send.html > for example. > > I think the only safe way to get this to work is to create the > socket in non-blocking mode to begin with. Then we don't have > to worry about functions blocking when hidden buffer size > limits are hit. So I think that would mean making a new > object that explicitly represented a non-blocking socket. > I'm not in any dire need for non-blocking sockets so I > probably won't be implementing this any time soon. > You might also want to check out the asio library > (http://think-async.com/Asio/). It has a whole lot of support > for varous kinds of networking modes. It is also, in all > probability, the networking library that will eventually make > it into C++ standard library. So it might be worth learning > just for that reason :) > > Cheers, > Davis > > On Fri, Apr 17, 2009 at 7:35 PM, miguelg50 > <mig...@ve... <mailto:mig...@ve...> > <mailto:mig...@ve... <mailto:mig...@ve...>>> > wrote: > > Davis, > > Attached is the patch for the non-blocking socket changes I've > made. I hope > it is useful. > > Miguel > > > > > |
|
From: Davis K. <dav...@us...> - 2009-05-23 21:33:02
|
Indeed, that's what dlib::timeout does. How about I just add the timeout directly to the read() function? It sounds like that is all you need. And maybe in the future we can setup some kind of nonblocking_connection object with full support for using select on multiple connections and all that good stuff. Cheers, Davis On Sat, May 23, 2009 at 2:06 PM, Miguel Grinberg <mig...@ve...>wrote: > Well, the problem is not that the call to read blocks, it is that it blocks > forever. The readable() method I added has a timeout, so with that I can > control for how long I want to block while waiting for data. It is a much > cleaner way than using dlib::timeout, which if I understand it correctly > would close the connection when the timeout expires. > > Miguel > > Davis King wrote: > >> Yeah, I think you are right about the non-blocking reading. >> Right now the only way to implement a timeout on a read operation is to >> use the dlib::timeout class which is sort of a heavyweight solution. So >> having non-blocking reading seems like it would be a nice alternative. >> What do you usually do when you aren't blocking on a call to read? You >> have to be blocking on a call to something else right? sleep() maybe? >> Either that or you are spinning in a loop and killing CPU time. >> >> Cheers, >> Davis >> >> On Sat, May 23, 2009 at 2:21 AM, Miguel Grinberg <mig...@ve...<mailto: >> mig...@ve...>> wrote: >> >> Hi Davis, >> >> I guess for the write side this change is more of a >> "ready_to_send" function. A non-blocking operation cannot be >> guaranteed, the only thing you can ensure is that at least part of >> your data buffer will get through right away. >> >> I'm only using the non-blocking read function right now, that one >> doesn't seem to have any side effects, it seems to me that for >> read with the use of select you can achieve true non-blocking >> behavior. >> >> In my experience non-blocking writing isn't all that common >> anyway, I normally use non-blocking I/O to prevent my application >> from blocking while waiting for the other end to send data, but >> when I'm the one sending I don't mind blocking. >> >> Thanks for your email. >> >> Miguel >> >> Davis King wrote: >> >> I have been testing out this patch for a while (on windows and >> linux) and trying to think if there are any funny corner >> cases. I also spent a lot of time a few years ago trying to >> work something like this into the connection object and ended >> up giving up but I forgot why until just now. >> Anyway, I found a problem related to sending data via send(). >> The problem is that send() will block, even if select() says >> it won't, if you give it a buffer larger than a certain value >> (the value depends on your platform and isn't at all >> portable). Linux allows you to set the MSG_DONTWAIT flag >> which fixes the issue but MSG_DONTWAIT isn't a POSIX thing and >> so isn't portable to other platforms. See >> http://www.opengroup.org/onlinepubs/009695399/functions/send.html >> for example. >> >> I think the only safe way to get this to work is to create the >> socket in non-blocking mode to begin with. Then we don't have >> to worry about functions blocking when hidden buffer size >> limits are hit. So I think that would mean making a new >> object that explicitly represented a non-blocking socket. >> I'm not in any dire need for non-blocking sockets so I >> probably won't be implementing this any time soon. >> You might also want to check out the asio library >> (http://think-async.com/Asio/). It has a whole lot of support >> for varous kinds of networking modes. It is also, in all >> probability, the networking library that will eventually make >> it into C++ standard library. So it might be worth learning >> just for that reason :) >> >> Cheers, >> Davis >> >> On Fri, Apr 17, 2009 at 7:35 PM, miguelg50 >> <mig...@ve... <mailto:mig...@ve...> >> <mailto:mig...@ve... <mailto:mig...@ve...>>> >> wrote: >> >> Davis, >> >> Attached is the patch for the non-blocking socket changes I've >> made. I hope >> it is useful. >> >> Miguel >> >> >> >> >> >> > > |
|
From: Miguel G. <mig...@ve...> - 2009-05-24 02:24:39
|
Sure, a timeout on read() works as well. Thanks! Miguel Davis King wrote: > Indeed, that's what dlib::timeout does. > > How about I just add the timeout directly to the read() function? It > sounds like that is all you need. And maybe in the future we can > setup some kind of nonblocking_connection object with full support for > using select on multiple connections and all that good stuff. > > Cheers, > Davis > > On Sat, May 23, 2009 at 2:06 PM, Miguel Grinberg > <mig...@ve... <mailto:mig...@ve...>> wrote: > > Well, the problem is not that the call to read blocks, it is that > it blocks forever. The readable() method I added has a timeout, so > with that I can control for how long I want to block while waiting > for data. It is a much cleaner way than using dlib::timeout, which > if I understand it correctly would close the connection when the > timeout expires. > > Miguel > > Davis King wrote: > > Yeah, I think you are right about the non-blocking reading. > Right now the only way to implement a timeout on a read > operation is to use the dlib::timeout class which is sort of a > heavyweight solution. So having non-blocking reading seems > like it would be a nice alternative. > What do you usually do when you aren't blocking on a call to > read? You have to be blocking on a call to something else > right? sleep() maybe? Either that or you are spinning in a > loop and killing CPU time. > > Cheers, > Davis > > On Sat, May 23, 2009 at 2:21 AM, Miguel Grinberg > <mig...@ve... <mailto:mig...@ve...> > <mailto:mig...@ve... <mailto:mig...@ve...>>> > wrote: > > Hi Davis, > > I guess for the write side this change is more of a > "ready_to_send" function. A non-blocking operation cannot be > guaranteed, the only thing you can ensure is that at least > part of > your data buffer will get through right away. > > I'm only using the non-blocking read function right now, > that one > doesn't seem to have any side effects, it seems to me that for > read with the use of select you can achieve true non-blocking > behavior. > > In my experience non-blocking writing isn't all that common > anyway, I normally use non-blocking I/O to prevent my > application > from blocking while waiting for the other end to send data, but > when I'm the one sending I don't mind blocking. > > Thanks for your email. > > Miguel > > Davis King wrote: > > I have been testing out this patch for a while (on > windows and > linux) and trying to think if there are any funny corner > cases. I also spent a lot of time a few years ago > trying to > work something like this into the connection object and > ended > up giving up but I forgot why until just now. > Anyway, I found a problem related to sending data via > send(). > The problem is that send() will block, even if > select() says > it won't, if you give it a buffer larger than a certain > value > (the value depends on your platform and isn't at all > portable). Linux allows you to set the MSG_DONTWAIT flag > which fixes the issue but MSG_DONTWAIT isn't a POSIX > thing and > so isn't portable to other platforms. See > > http://www.opengroup.org/onlinepubs/009695399/functions/send.html > for example. > > I think the only safe way to get this to work is to > create the > socket in non-blocking mode to begin with. Then we > don't have > to worry about functions blocking when hidden buffer size > limits are hit. So I think that would mean making a new > object that explicitly represented a non-blocking socket. > I'm not in any dire need for non-blocking sockets so I > probably won't be implementing this any time soon. > You might also want to check out the asio library > (http://think-async.com/Asio/). It has a whole lot of > support > for varous kinds of networking modes. It is also, in all > probability, the networking library that will > eventually make > it into C++ standard library. So it might be worth > learning > just for that reason :) > > Cheers, > Davis > > On Fri, Apr 17, 2009 at 7:35 PM, miguelg50 > <mig...@ve... <mailto:mig...@ve...> > <mailto:mig...@ve... <mailto:mig...@ve...>> > <mailto:mig...@ve... > <mailto:mig...@ve...> <mailto:mig...@ve... > <mailto:mig...@ve...>>>> > > wrote: > > Davis, > > Attached is the patch for the non-blocking socket > changes I've > made. I hope > it is useful. > > Miguel > > > > > > > > |
|
From: Davis K. <dav...@us...> - 2009-05-25 17:59:09
|
Cool. I just merged in your patch and set it up like this. The changes are in subversion and also up at http://davis.sytes.net/~davis/release if you want to take a look. Cheers, Davis On Sat, May 23, 2009 at 10:23 PM, Miguel Grinberg <mig...@ve...>wrote: > Sure, a timeout on read() works as well. Thanks! > > Miguel > > Davis King wrote: > >> Indeed, that's what dlib::timeout does. >> >> How about I just add the timeout directly to the read() function? It >> sounds like that is all you need. And maybe in the future we can setup >> some kind of nonblocking_connection object with full support for using >> select on multiple connections and all that good stuff. >> Cheers, >> Davis >> >> On Sat, May 23, 2009 at 2:06 PM, Miguel Grinberg <mig...@ve...<mailto: >> mig...@ve...>> wrote: >> >> Well, the problem is not that the call to read blocks, it is that >> it blocks forever. The readable() method I added has a timeout, so >> with that I can control for how long I want to block while waiting >> for data. It is a much cleaner way than using dlib::timeout, which >> if I understand it correctly would close the connection when the >> timeout expires. >> >> Miguel >> >> Davis King wrote: >> >> Yeah, I think you are right about the non-blocking reading. >> Right now the only way to implement a timeout on a read >> operation is to use the dlib::timeout class which is sort of a >> heavyweight solution. So having non-blocking reading seems >> like it would be a nice alternative. >> What do you usually do when you aren't blocking on a call to >> read? You have to be blocking on a call to something else >> right? sleep() maybe? Either that or you are spinning in a >> loop and killing CPU time. >> >> Cheers, >> Davis >> >> On Sat, May 23, 2009 at 2:21 AM, Miguel Grinberg >> <mig...@ve... <mailto:mig...@ve...> >> <mailto:mig...@ve... <mailto:mig...@ve...>>> >> wrote: >> >> Hi Davis, >> >> I guess for the write side this change is more of a >> "ready_to_send" function. A non-blocking operation cannot be >> guaranteed, the only thing you can ensure is that at least >> part of >> your data buffer will get through right away. >> >> I'm only using the non-blocking read function right now, >> that one >> doesn't seem to have any side effects, it seems to me that for >> read with the use of select you can achieve true non-blocking >> behavior. >> >> In my experience non-blocking writing isn't all that common >> anyway, I normally use non-blocking I/O to prevent my >> application >> from blocking while waiting for the other end to send data, but >> when I'm the one sending I don't mind blocking. >> >> Thanks for your email. >> >> Miguel >> >> Davis King wrote: >> >> I have been testing out this patch for a while (on >> windows and >> linux) and trying to think if there are any funny corner >> cases. I also spent a lot of time a few years ago >> trying to >> work something like this into the connection object and >> ended >> up giving up but I forgot why until just now. >> Anyway, I found a problem related to sending data via >> send(). >> The problem is that send() will block, even if >> select() says >> it won't, if you give it a buffer larger than a certain >> value >> (the value depends on your platform and isn't at all >> portable). Linux allows you to set the MSG_DONTWAIT flag >> which fixes the issue but MSG_DONTWAIT isn't a POSIX >> thing and >> so isn't portable to other platforms. See >> >> http://www.opengroup.org/onlinepubs/009695399/functions/send.html >> for example. >> >> I think the only safe way to get this to work is to >> create the >> socket in non-blocking mode to begin with. Then we >> don't have >> to worry about functions blocking when hidden buffer size >> limits are hit. So I think that would mean making a new >> object that explicitly represented a non-blocking socket. >> I'm not in any dire need for non-blocking sockets so I >> probably won't be implementing this any time soon. >> You might also want to check out the asio library >> (http://think-async.com/Asio/). It has a whole lot of >> support >> for varous kinds of networking modes. It is also, in all >> probability, the networking library that will >> eventually make >> it into C++ standard library. So it might be worth >> learning >> just for that reason :) >> >> Cheers, >> Davis >> >> On Fri, Apr 17, 2009 at 7:35 PM, miguelg50 >> <mig...@ve... <mailto:mig...@ve...> >> <mailto:mig...@ve... <mailto:mig...@ve...>> >> <mailto:mig...@ve... >> <mailto:mig...@ve...> <mailto:mig...@ve... >> <mailto:mig...@ve...>>>> >> >> wrote: >> >> Davis, >> >> Attached is the patch for the non-blocking socket >> changes I've >> made. I hope >> it is useful. >> >> Miguel >> >> >> >> >> >> >> >> >> > > |