After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 584284 - g_data_input_stream_read_until_async behaves confusingly different from sync version
g_data_input_stream_read_until_async behaves confusingly different from sync ...
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gio
2.21.x
Other Linux
: High normal
: ---
Assigned To: Allison Karlitskaya (desrt)
gtkdev
Depends on:
Blocks:
 
 
Reported: 2009-05-30 13:53 UTC by Paul Pogonyshev
Modified: 2018-02-02 09:06 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
change the async version (1.33 KB, patch)
2009-11-12 20:04 UTC, Allison Karlitskaya (desrt)
none Details | Review
patch (22.02 KB, patch)
2010-03-18 03:24 UTC, Matthias Clasen
needs-work Details | Review
[PATCH] Add g_data_input_stream_read_upto{,async,finish} (29.04 KB, patch)
2010-03-23 06:17 UTC, Allison Karlitskaya (desrt)
committed Details | Review
gdatainputstream: Deprecate read_until() in favour of read_upto() (4.95 KB, patch)
2018-02-01 16:52 UTC, Philip Withnall
committed Details | Review

Description Paul Pogonyshev 2009-05-30 13:53:16 UTC
I just tried to wrap the function in PyGObject and in unit tests noticed the utterly confusing difference between sync and async versions.  While first "eats" the stopping character out of stream (i.e. advances pointer past it), asynchronous version _doesn't_.  I believe this is so confusing and just wrong (e.g. if you change your program from using synchronous to asynchronous version you need to adjust result handling), that it must be fixed even though this will break backwards compatibility.

A little code from unit tests (I don't attach full code since the wrappers themselves are not pushed into the repository yet):

        self.assertEquals('sentence', self.data_stream.read_until('.!?'))
        self.assertEquals('end of line', self.data_stream.read_until('\n\r'))
        ...
        self.assertEquals('sentence', do_read_until_async('.!?'))
        self.assertEquals('.end of line', do_read_until_async('\n\r'))
                          ^^^

Note that in the first (synchronous) test dot (first stop character) is eaten out of the stream and so doesn't get into the second result.  In the second test dot is not eaten and so appears in the second result.
Comment 1 Paul Pogonyshev 2009-05-30 13:55:08 UTC
I forgot to mention that in both tests the contents of the stream is 'sentence.end of line\nthe rest'.
Comment 2 Paul Pogonyshev 2009-05-30 14:08:50 UTC
Python wrappers and unit tests are attached to bug 584285.  Python can be used to easily to test the described behavior.
Comment 3 Allison Karlitskaya (desrt) 2009-11-12 06:05:06 UTC
i wrote the _async version after the synchronous one already existed, so it's my fault that they are functionally different.

on the other hand, the existing documentation for the synchronous function suggests that the _async() version does the right thing.  specifically: there is absolutely no mention of the stop characters being consumed or 'skipped'.

i agree that this should be resolved.  i'm not certain which way to resolve it.
Comment 4 Paul Pogonyshev 2009-11-12 19:45:05 UTC
Well, a change in the sync version would be a more significant compatibility break, since the function itself is older and because (just guessing) synchronous functions are more widely used.

In either case, this should be done "now or never".  The longer the problem remains unadressed, the larger the compatibility break will be.
Comment 5 Allison Karlitskaya (desrt) 2009-11-12 20:04:32 UTC
Created attachment 147604 [details] [review]
change the async version

for what it's worth, here's an (untested) patch that changes the async version.

i'm going to write to the ML for opinions.  i don't feel comfortable breaking API without some backup.

probably a change to the docs should also go in.
Comment 6 Matthias Clasen 2010-03-18 03:24:01 UTC
Created attachment 156429 [details] [review]
patch
Comment 7 Allison Karlitskaya (desrt) 2010-03-23 05:08:30 UTC
Review of attachment 156429 [details] [review]:

yes.  this is pretty much exactly what i had in mind.

missing gtk-doc symbol additions, plus small fusses noted.

i'll update the patch accordingly.

::: gio/gdatainputstream.c
@@ +835,3 @@
     {
   for (i = 0; checked < available && i < peeked; i++)
+      stop_end = stop_chars + stop_chars_len;

may as well lift this to save the compiler the trouble...

@@ +862,3 @@
+ *
+ * function consumes the stop character (and does not return it).
+ * Note that in contrast to g_data_input_stream_read_upto(), this

a note about future deprecation would be nice

@@ +889,2 @@
   checked = 0;
+  while ((found_pos = scan_for_chars (stream, &checked, stop_chars, strlen (stop_chars))) == -1)

strlen(stop_chars) here is scary.

perhaps read_until() should be implemented by calling read_upto() and then consuming the separator character if it was found...

@@ +1188,1 @@
   g_return_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable));

read_until_async should have pending-deprecation note too.
Comment 8 Allison Karlitskaya (desrt) 2010-03-23 06:17:20 UTC
Created attachment 156832 [details] [review]
[PATCH] Add g_data_input_stream_read_upto{,async,finish}

I think this is OK.
Comment 9 Alexander Larsson 2010-03-23 14:30:30 UTC
looks ok to me
Comment 10 Allison Karlitskaya (desrt) 2010-03-23 14:36:49 UTC
punting to 2.26
Comment 11 Javier Jardón (IRC: jjardon) 2010-09-12 17:39:20 UTC
Ryan, Any news on this?
Comment 12 Allison Karlitskaya (desrt) 2010-09-13 16:12:10 UTC
Ya.  This should have gone in ages ago.
Comment 13 Murray Cumming 2012-09-16 11:15:30 UTC
This change added a documentation comment that g_data_input_stream_read_until() should not be used and would be deprecated in a future version. I guess we've again missed the time to do that, but shouldn't we keep this bug open so we don't forget to do that?
Comment 14 Matthias Clasen 2012-09-16 17:25:04 UTC
Sound good
Comment 15 Philip Withnall 2018-02-01 16:44:06 UTC
Comment on attachment 156832 [details] [review]
[PATCH] Add g_data_input_stream_read_upto{,async,finish}

This was pushed as 2e78d07f86d70de274f126a3ff00bd4af90a5c90 in 2010.
Comment 16 Philip Withnall 2018-02-01 16:52:14 UTC
Created attachment 367762 [details] [review]
gdatainputstream: Deprecate read_until() in favour of read_upto()

g_data_input_stream_read_upto() was introduced in 2.26; now it’s GLib
2.56, we can probably deprecate the old versions (since the handling of
consuming the stop character differs between the sync and async versions
of it).

Signed-off-by: Philip Withnall <withnall@endlessm.com>
Comment 17 Matthias Clasen 2018-02-02 08:33:51 UTC
Review of attachment 367762 [details] [review]:

sure
Comment 18 Philip Withnall 2018-02-02 09:06:23 UTC
Pushed, thanks!

Attachment 367762 [details] pushed as 5ed77c1 - gdatainputstream: Deprecate read_until() in favour of read_upto()