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 669670 - gasyncqueue: don't use deprecated g_cond_timed_wait()
gasyncqueue: don't use deprecated g_cond_timed_wait()
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: general
unspecified
Other All
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
Depends on:
Blocks:
 
 
Reported: 2012-02-08 13:56 UTC by Dan Winship
Modified: 2012-02-22 16:37 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
gasyncqueue: don't use deprecated g_cond_timed_wait() (1.61 KB, patch)
2012-02-08 13:57 UTC, Dan Winship
none Details | Review
gasyncqueue: deprecate GTimeVal-based methods, add monotonic ones (10.75 KB, patch)
2012-02-10 14:07 UTC, Dan Winship
none Details | Review
gasyncqueue: deprecate GTimeVal-based methods, add relative-delay ones (11.41 KB, patch)
2012-02-10 17:56 UTC, Dan Winship
committed Details | Review
gasyncqueue: fix a 32bit overflow in g_async_queue_timed_pop (2.35 KB, patch)
2012-02-22 13:14 UTC, Dan Winship
committed Details | Review

Description Dan Winship 2012-02-08 13:56:37 UTC
"make check" still passes, but someone might want to double-check the
code... (and then check bug 669329 too while they're at it :)
Comment 1 Dan Winship 2012-02-08 13:57:18 UTC
Created attachment 207099 [details] [review]
gasyncqueue: don't use deprecated g_cond_timed_wait()

Fix it to use g_cond_wait_until() instead.
Comment 2 Allison Karlitskaya (desrt) 2012-02-08 15:00:21 UTC
I don't think we can credibility use such hacks on a non-deprecated API.  We need to deprecate this one and introduce a new one based on either relative or absolute monotonic time (or both).
Comment 3 Colin Walters 2012-02-10 01:14:13 UTC
Review of attachment 207099 [details] [review]:

::: glib/gasyncqueue.c
@@ +418,3 @@
+      if (end_time != NULL)
+	{
+	  wait_time = g_get_monotonic_time () - g_get_real_time ();

I don't really get this...how is there a relationship between the monotonic clock and the wall clock?
Comment 4 Dan Winship 2012-02-10 12:51:46 UTC
(In reply to comment #2)
> I don't think we can credibly use such hacks on a non-deprecated API.

Well, but we already are; All this patch does is basically inline the definition of g_cond_timed_wait() from gthread-deprecated.c rather than calling it.

> We need to deprecate this one and introduce a new one based on either
> relative or absolute monotonic time (or both).

Sure, I suppose that if g_cond_timed_wait() is bad API then it would follow that g_async_queue_timed_pop() is bad too...


(In reply to comment #3)
> I don't really get this...how is there a relationship between the monotonic
> clock and the wall clock?

@end_time is in real time, but g_cond_wait_until() takes a monotonic time. So we need "monotonic_time + (end_time - real_time)". (I guess the way the math is done here is not totally obvious, but that's how it's done in gthread-deprecated.c...)
Comment 5 Dan Winship 2012-02-10 14:07:35 UTC
Created attachment 207255 [details] [review]
gasyncqueue: deprecate GTimeVal-based methods, add monotonic ones

=====

ok, this adds new methods (better names welcome), deprecates the old
ones, etc.
Comment 6 Allison Karlitskaya (desrt) 2012-02-10 15:37:22 UTC
Review of attachment 207255 [details] [review]:

Ya.  This is much better.

about the names: 'timeout' suggests a relative time.  I think following the _until convention may be good here.

pop_until() sounds weird, so maybe try_pop_until()?

We could also add in the relative version which is probably what most people actually want...  try_pop_for()?  try_pop_with_timeout()?

oh names...
Comment 7 Dan Winship 2012-02-10 17:56:06 UTC
Created attachment 207285 [details] [review]
gasyncqueue: deprecate GTimeVal-based methods, add relative-delay ones

=====

Changed to take a length of time rather than an end time. Since Ryan
said the original name suggested a relative time to him, I just kept
that name.
Comment 8 Allison Karlitskaya (desrt) 2012-02-12 04:00:30 UTC
Review of attachment 207285 [details] [review]:

I'm not crazy about the name, but I'm not crazy about any name that I can think of, so this is as good as any.

Everything else is perfect.  Thanks.
Comment 9 Dan Winship 2012-02-13 14:10:36 UTC
Attachment 207285 [details] pushed as dd553a2 - gasyncqueue: deprecate GTimeVal-based methods, add relative-delay ones
Comment 10 Sebastien Bacher 2012-02-22 10:31:28 UTC
That commit seems to have creater a bug, nautilus started hitting those errors for nautilus-dropbox users:

"GLib (gthread-posix.c): Unexpected error from C library during 'Bad argumentt': pthread_cond_timedwait.  Aborting.
Aborted (core dumped)"


Chris Goller (goller) tracked it to this commit on https://bugs.launchpad.net/ubuntu/+source/nautilus-dropbox/+bug/932627/comments/18

"I think I've tracked it down...

http://ftp.gnome.org/pub/gnome/sources/glib/2.31/glib-2.31.18.news

glib did this change
 * g_async_queue_timed_pop has been deprecated in favor of
  the new g_async_queue_timeout_pop, which uses relative
  delays in microseconds instead of a GTimeVal.

and the exact change in g_async_queue_timed_pop

+ if (end_time != NULL)
+ {
+ m_end_time = g_get_monotonic_time () +
+ (end_time->tv_sec * G_USEC_PER_SEC + end_time->tv_usec -
+ g_get_real_time ());
+ }
+ else
+ m_end_time = -1;
+

end_time->tv_sec * G_USEC_PER_SEC + end_time->tv_usec - g_get_real_time () returns a value far less than 0 and it causes
the m_end_time to be less than 0.

Therefore, this sets m_end_time to negative creating an invalid argument to be passed to pthread_cond_wait.

I think just casting end_time->tv_sec to gint64 is all that is needed."
Comment 11 Dan Winship 2012-02-22 13:14:53 UTC
Created attachment 208196 [details] [review]
gasyncqueue: fix a 32bit overflow in g_async_queue_timed_pop

also, add a test for g_async_queue_timed_pop() and
g_async_queue_timeout_pop() to tests/asyncqueue.c

====

It would be nice if someone on a 32bit machine could verify that the
test does crash without the fix, and doesn't crash with the fix. (It
works fine either way on x86_64.)
Comment 12 Colin Walters 2012-02-22 15:48:26 UTC
Review of attachment 208196 [details] [review]:

::: glib/gasyncqueue.c
@@ +603,3 @@
     {
       m_end_time = g_get_monotonic_time () +
+	((gint64)end_time->tv_sec * G_USEC_PER_SEC + end_time->tv_usec -

Looks right.

::: glib/tests/asyncqueue.c
@@ +187,3 @@
+  diff = end - start;
+  g_assert_cmpint (diff, >=, G_USEC_PER_SEC / 10);
+  g_assert_cmpint (diff, <, 1.1 * (G_USEC_PER_SEC / 10));

I don't like having a test case which is going to assert if it happens to run too slowly.  If we were talking human timescales like 30-60 seconds say, that's one thing, but here the failure would happen above 100 milliseconds.  Right?

This kind of thing is tricky because we actually have no documentation about what environment we expect the tests to be run under.  But I could easily imagine if e.g. running them under Linux' idle class schedluing (chrt --idle 0 mytest) you could get that kind of latency.
Comment 13 Sebastien Bacher 2012-02-22 16:31:06 UTC
ok, trying the new test on 2.31.18 before the code patch:

/asyncqueue/timed: GLib (gthread-posix.c): Unexpected error from C library during 'Invalid argument': pthread_cond_timedwait.  Aborting.

then after:

/asyncqueue/timed: OK

that's on a 32 bits ubuntu precise install
Comment 14 Dan Winship 2012-02-22 16:37:05 UTC
after discussion on IRC, pushed the patch with the test changed to
only check that the delay was less than 1 second.

Attachment 208196 [details] pushed as 88182d3 - gasyncqueue: fix a 32bit overflow in g_async_queue_timed_pop