GNOME Bugzilla – Bug 626866
g_output_stream_write - docs. vs. impl ...
Last modified: 2011-11-14 23:32:27 UTC
I read g_output_stream_write's documentation: * On success, the number of bytes written to the stream is returned. * It is not an error if this is not the same as the requested size, as it * can happen e.g. on a partial i/o error, or if there is not enough * storage in the stream. All writes either block until at least one byte * is written, so zero is never returned (unless @count is zero). the 'either' is tantalising. IMHO it is lame to have an implementation that hides EAGAIN from the caller on a non-blocking socket: [ ie. go away and wait for space ], so I was sad to read that this method spins / changes the socket from non-blocking to blocking, so zero is never returned ;-) Then of course, I read the impl. in g_unix_output_stream_write it does no such thing - it does the sane-thing I expected, which is returning G_IO_ERROR_WOULD_BLOCK on a non-blocking socket / output stream. ;-) Is it ok to tweak the comment to explain non-blocking streams and the error you can get there if there is no room to write ? :-)
(In reply to comment #0) > the 'either' is tantalising. IMHO it is lame to have an implementation that > hides EAGAIN from the caller on a non-blocking socket: [ ie. go away and wait > for space ], so I was sad to read that this method spins / changes the socket > from non-blocking to blocking, so zero is never returned ;-) It might be good to inform that file descriptors that refer to files on Unix cannot be set non-blocking. If you look into read() syscall manual (man 2 read) in the EAGAIN doc you will read "The file descriptor fd refers to a socket ...". If you nead non-blocking operation consider using the _async() version of those calls along with a GCancellable.
The documentation (minus the spurious "either") is correct. g_unix_output_stream_write is broken-ish (although if you pass in a GCancellable, it does the right thing, by not calling write() until poll() says it's ready). It's true that it's useful to be able to get an EAGAIN sometimes, but g_output_stream_write() is explicitly intended to not ever do that. Perhaps we should add a GPollable interface that would allow for that... (Leaving the bug open because g_unix_output_stream_write() still needs to be fixed...)
(In reply to comment #2) > It's true that it's useful to be able to get an EAGAIN sometimes, but > g_output_stream_write() is explicitly intended to not ever do that. > Perhaps we should add a GPollable interface that would allow for that... bug 634241 now implements this, including g_pollable_output_stream_write_nonblocking(), which is g_output_stream_write() that returns G_IO_ERROR_WOULD_BLOCK instead of blocking.
Someone allowed should close this.
(In reply to comment #2) > (Leaving the bug open because g_unix_output_stream_write() still needs to > be fixed...)
finally fixed the unix streams to always block when they're supposed to. closing.