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 694253 - occasional /gdbus/unref-pending test failure
occasional /gdbus/unref-pending test failure
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gobject
unspecified
Other All
: Normal normal
: ---
Assigned To: gtkdev
gtkdev
: 682066 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2013-02-20 10:41 UTC by Allison Karlitskaya (desrt)
Modified: 2013-03-28 16:09 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
signals: No need to use atomics for Handler refcount (1.39 KB, patch)
2013-02-21 15:08 UTC, Alexander Larsson
accepted-commit_now Details | Review
signals: Ensure we ref handler in emission fast path (2.44 KB, patch)
2013-02-21 15:08 UTC, Alexander Larsson
accepted-commit_now Details | Review

Description Allison Karlitskaya (desrt) 2013-02-20 10:41:28 UTC
I'm seeing an occasional failure in /gdbus/unref-pending test.  Happens maybe 1 time in 100.

(/home/desrt/code/glib/gio/tests/.libs/lt-gdbus-close-pending:27884): GLib-GObject-CRITICAL **: g_closure_ref: assertion `closure->ref_count > 0' failed

Maybe this is related to bug 692034
Comment 1 Allison Karlitskaya (desrt) 2013-02-20 10:53:50 UTC
(gdb) thread apply all bt

Thread 1 (Thread 0x7ffff7fcd7c0 (LWP 23399))

  • #0 g_logv
    at gmessages.c line 981
  • #1 g_log
    at gmessages.c line 1010
  • #2 g_return_if_fail_warning
    at gmessages.c line 1019
  • #3 g_closure_ref
    at gclosure.c line 532
  • #4 _g_closure_invoke_va
    at gclosure.c line 818
  • #5 g_signal_emit_valist
    at gsignal.c line 3225
  • #6 g_signal_emit
    at gsignal.c line 3370
  • #7 g_cancellable_cancel
    at gcancellable.c line 507
  • #8 _g_dbus_worker_close
    at gdbusprivate.c line 1718
  • #9 g_dbus_connection_close
    at gdbusconnection.c line 1472
  • #10 g_dbus_connection_close
    at gdbusconnection.c line 1452
  • #11 g_dbus_connection_close_sync
    at gdbusconnection.c line 1567
  • #12 test_once
    at gdbus-close-pending.c line 352
  • #13 test_many_times
    at gdbus-close-pending.c line 380
  • #14 test_case_run
    at gtestutils.c line 1714
  • #15 g_test_run_suite_internal
    at gtestutils.c line 1767
  • #16 g_test_run_suite_internal
    at gtestutils.c line 1778
  • #17 g_test_run_suite
    at gtestutils.c line 1823
  • #18 g_test_run
    at gtestutils.c line 1324
  • #19 main
    at gdbus-close-pending.c line 394

Comment 2 Allison Karlitskaya (desrt) 2013-02-20 10:56:35 UTC
Backtrace seems to implicate bug 118536 instead.
Comment 3 Allison Karlitskaya (desrt) 2013-02-21 10:43:42 UTC
Pretty sure this is actually due to insufficient refcounting when dropping the signal lock in the 'fastpath' va-args case in gsignal...
Comment 4 Alexander Larsson 2013-02-21 15:08:52 UTC
Created attachment 237046 [details] [review]
signals: No need to use atomics for Handler refcount

handler_ref and handler_unref_R are always called with the signal
lock held. This is obvious for handler_unref_R as it even sometimes
drops this lock, and can be verified quickly for handler_ref by looking
at all call sites.

This improves the performace about 1% on the emit-handled and the
emit-handled-generic tests.
Comment 5 Alexander Larsson 2013-02-21 15:08:55 UTC
Created attachment 237047 [details] [review]
signals: Ensure we ref handler in emission fast path

We need to keep a reference to the handler in the fast path, just like
in the slow path, otherwise if another thread disconnects the handler
we may destroy the closure while we're using it without the lock held.

We also move the freeing of the instance to after the emission is totally
done as the handler_unref_R (and the tracepoint) reference it.
Comment 6 Alexander Larsson 2013-02-21 15:13:47 UTC
Ugh, i miscalculated the performance increase, its about 6%.
The performance losses with the second patch is < 1% at worst (due to the first patch making ref/unref cheap).
Comment 7 Allison Karlitskaya (desrt) 2013-02-21 15:16:26 UTC
Review of attachment 237046 [details] [review]:

This looks fine.

Might be worth taking a peek at http://git.gnome.org/browse/glib/commit/?id=39ea11ce6b107bf3969a2f94807675b458a5a887 for other possible cases to improve.
Comment 8 Allison Karlitskaya (desrt) 2013-02-21 15:18:05 UTC
Review of attachment 237047 [details] [review]:

::: gobject/gsignal.c
@@ +3275,3 @@
 	  TRACE(GOBJECT_SIGNAL_EMIT_END(signal_id, detail, instance, instance_type));
 
+          if (closure != NULL)

Why is this needed?

In the case that the closure is from a handler, the handler ref will keep the closure alive.  If emission hook, we won't be on the fast path.  If a class closure handler (or C vtable pointer) then it can't possibly be removed...
Comment 9 Alexander Larsson 2013-02-21 15:19:15 UTC
Review of attachment 237047 [details] [review]:

::: gobject/gsignal.c
@@ +3275,3 @@
 	  TRACE(GOBJECT_SIGNAL_EMIT_END(signal_id, detail, instance, instance_type));
 
+          if (closure != NULL)

It unrefs the instance...
Comment 10 Alexander Larsson 2013-02-21 15:30:50 UTC
Also, i've been running the original /gdbus/unref-pending test for a looong time now and i don't get the critical anymore.
Comment 11 Allison Karlitskaya (desrt) 2013-02-21 15:40:26 UTC
Review of attachment 237047 [details] [review]:

::: gobject/gsignal.c
@@ +3275,3 @@
 	  TRACE(GOBJECT_SIGNAL_EMIT_END(signal_id, detail, instance, instance_type));
 
+          if (closure != NULL)

lol.  Sorry.

But why does that need to be all the way out here?  ie: what are you trying to fix by moving it?
Comment 12 Alexander Larsson 2013-02-21 15:44:57 UTC
Review of attachment 237047 [details] [review]:

::: gobject/gsignal.c
@@ +3275,3 @@
 	  TRACE(GOBJECT_SIGNAL_EMIT_END(signal_id, detail, instance, instance_type));
 
+          if (closure != NULL)

The handler_unref_R call passes the instance, so we need to be below that. Additionally the tracepoing passes the instance too, so better also be after that.
Comment 13 Allison Karlitskaya (desrt) 2013-02-21 15:46:45 UTC
Review of attachment 237047 [details] [review]:

Ok.  You got me.  I was just looking for a way to avoid looking lazy by ACKing both of your patches without comment.
Comment 14 Alexander Larsson 2013-02-21 15:49:13 UTC
pushed both.
Comment 15 Allison Karlitskaya (desrt) 2013-03-28 16:09:21 UTC
*** Bug 682066 has been marked as a duplicate of this bug. ***