Due to an influx of spam, we have had to impose restrictions on new accounts. Please see this wiki page for instructions on how to get full permissions. Sorry for the inconvenience.
Admin message
The migration is almost done, at least the rest should happen in the background. There are still a few technical difference between the old cluster and the new ones, and they are summarized in this issue. Please pay attention to the TL:DR at the end of the comment.
The functions do not have handling for the situation that sub-functions return both a positive number of bytes and an error at the same time.
The problem is discovered in the next lap of the while-loop when the error has not been cleared from the previous lap, and this error print is issued:
"GError set over the top of a previous GError or uninitialized memory."
Designs
Child items ...
Show closed items
Linked items 0
Link issues together to show that they're related.
Learn more.
The proposed patch goes to error not only when returned number of bytes is non-negative but also when err is set.
This change required some rework of the error handling.
The function write_bytes() is aligned to the read_byte() function for handling the case where returned bytes is zero.
What error is being returned in this case where it returns a non-negative number as well?
The returned error is depending on the G_IO_ERROR with GST_RTSP_ESYS as default, as before.
Is this intentional and expected or perhaps a bug in the underlying code in GLib?
Well, the GLib documentation states "the number of bytes ..., or -1 on error" for both the underlying GLib functions (g_pollable_output_stream_write_nonblocking and g_pollable_input_stream_read_nonblocking), so at least one could say that the GLib implementation does not match the GLib documentation.
What error is being returned in this case where it returns a non-negative number as well?
The returned error is depending on the G_IO_ERROR with GST_RTSP_ESYS as
default, as before.
I think the question was what the actual GIO error is that happens here
Is this intentional and expected or perhaps a bug in the underlying code in GLib?
Well, the GLib documentation states "the number of bytes ..., or -1 on
error" for both the underlying GLib functions
(g_pollable_output_stream_write_nonblocking and
g_pollable_input_stream_read_nonblocking), so at least one could say that
the GLib implementation does not match the GLib documentation.
Can you file a bug about that again GLib? This is definitely not correct, both for the given documentation and the behaviour that code relies on everywhere with regards to these functions.
Does this happen with direct TCP connections, or via TLS, or ...?
I working together with Nils and I had another look at this issue. It don't think this is a Glib issue.
The interesting function in this case is
gst-plugins-base/gst-libs/gst/rtsp/gstrtspconnection.c: fill_bytes()
This function may return both data and error in some cases.
It happens when there are leftover bytes and the next call to fill_raw_bytes() fails.
It happens in this order:
out is incremented with leftover bytes
fill_raw_bytes() sets Gerror and returns -1
The function fill_bytes() returns out containing the leftover bytes together with GError set.
In our case GError is: Resource temporarily unavailable
What should happen to the leftover data when the call to fill_raw_bytes() fails?
Based on this information I can think of two alternatives:
In read_bytes() handle the case of both returned leftover bytes and error from fill_bytes()
Change fill_bytes() to always return -1 in case of error (this would discard the leftover data)
Which alternative is preferred in this case?
The function write_bytes() is not affected by this issue. No need to change this function.
In our case GError is: Resource temporarily unavailable
This should cause an immediate retry in this function instead of returning an error upwards.
What should happen to the leftover data when the call to fill_raw_bytes() fails?
If there's a real error (not EWOULDBLOCK, not EINTR/EAGAIN) then it should error out immediately and whatever data was read is discarded.
On EWOULDBLOCK you would return all data and no error (and the next call would directly return EWOULDBLOCK without any data), on EINTR/EAGAIN you would internally retry and never bother the caller with that detail.
I'm not really found of having an internal retry mechanism.
I'm afraid it could cause more harm than good due to added complexity.
It sounds simple to always return leftover data (if any) and discard error.
The caller will call again to read more bytes (implicit retry mechanism) and if error is persistent it will fail again.
Currently the write functions are handling retries internally, I'd prefer to have the read functions work the same for consistency and to keep this kind of problems from happening.