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 583909 - drop sinkfuncs by using the new stuff in glib instead
drop sinkfuncs by using the new stuff in glib instead
Status: RESOLVED FIXED
Product: pygobject
Classification: Bindings
Component: gobject
Git master
Other Linux
: Normal normal
: ---
Assigned To: Nobody's working on this now (help wanted and appreciated)
Python bindings maintainers
: 622436 (view as bug list)
Depends on:
Blocks:
 
 
Reported: 2009-05-26 16:31 UTC by Tomeu Vizoso
Modified: 2010-06-23 07:01 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
drop sinkfuncs (2.05 KB, patch)
2009-05-26 16:38 UTC, Tomeu Vizoso
needs-work Details | Review
addresses Paul's concern (2.41 KB, patch)
2009-05-28 13:23 UTC, Tomeu Vizoso
rejected Details | Review
passes the tests (4.24 KB, patch)
2009-05-31 14:55 UTC, Tomeu Vizoso
none Details | Review
[PATCH] Drop sinkfuncs. Fixes bug #583909 (3.49 KB, patch)
2010-05-18 16:51 UTC, johnp
needs-work Details | Review
Drop sinkfuncs. Fixes bug #583909 (4.89 KB, patch)
2010-06-09 18:19 UTC, johnp
committed Details | Review
Fall back to use the floating references API in glib if there isn't a sinkfunc defined. (18.01 KB, patch)
2010-06-21 14:57 UTC, Tomeu Vizoso
committed Details | Review

Description Tomeu Vizoso 2009-05-26 16:31:51 UTC
Now that we have floating reference support in glib, we don't need for bindings to register their own sinkfuncs.

This is needed by pybank as the bindings are generated at runtime based on the information available via introspection.
Comment 1 Tomeu Vizoso 2009-05-26 16:38:15 UTC
Created attachment 135388 [details] [review]
drop sinkfuncs
Comment 2 Paul Pogonyshev 2009-05-26 18:16:17 UTC
What happens if someone still registers a sinkfunc?  Bindings won't start leaking like mad once their sinkfuncs are just ignored?
Comment 3 Tomeu Vizoso 2009-05-27 07:39:10 UTC
(In reply to comment #2)
> What happens if someone still registers a sinkfunc?  Bindings won't start
> leaking like mad once their sinkfuncs are just ignored?

Well, the generic implementation proposed in the patch should be equivalent to whatever the bindings were doing in the sinkfuncs, though nothing prevented bindings of doing something else completely different in those.
Comment 4 Paul Pogonyshev 2009-05-27 18:48:10 UTC
Your patch doesn't seem to be completely valid.  As I understand, objects can have a floating reference even if they don't inherit GInitiallyUnowned, even though most/all probably do inherit.  In any case, just calling g_object_ref_sink() should be sufficient judging by documentation, i.e. all those ifs are not needed.
Comment 5 Tomeu Vizoso 2009-05-28 13:23:26 UTC
Created attachment 135496 [details] [review]
addresses Paul's concern
Comment 6 Tomeu Vizoso 2009-05-28 13:24:02 UTC
(In reply to comment #4)
> Your patch doesn't seem to be completely valid.  As I understand, objects can
> have a floating reference even if they don't inherit GInitiallyUnowned, even
> though most/all probably do inherit.  In any case, just calling
> g_object_ref_sink() should be sufficient judging by documentation, i.e. all
> those ifs are not needed.

You are right, just calling g_object_ref_sink seems to be enough.
Comment 7 Paul Pogonyshev 2009-05-30 14:46:19 UTC
I tried to apply the patch.  After it, several testcases start to fail.  I'm not sure what is wrong, but please do run 'make check' before submitting a patch.
Comment 8 Tomeu Vizoso 2009-05-31 14:55:07 UTC
Created attachment 135661 [details] [review]
passes the tests

This one does pass the tests, sorry about that.

You can see that we aren't unconditionally calling g_object_ref_sink(obj) because that would cause an unwanted extra reference in some cases.
Comment 9 Paul Pogonyshev 2009-06-12 20:56:45 UTC
Functions sink_gtkwindow() and sink_gtkinvisible() in PyGTK do something special.  I don't understand what they do and I don't quite feel like removing that: might well break something or cause leaks.
Comment 10 Tomeu Vizoso 2009-06-14 07:15:11 UTC
Any idea about how to verify that? Any test we could add? There are already tests that verify reference counting and the last patch passes them, both in pygtk and pygobject.

Also, if you think the approach is wrong and you can think of a better alternative, please share it.
Comment 11 John Ehresman 2009-06-17 21:33:42 UTC
The sink_gtkwindow() and sink_gtkinvisible() functions are there because the pointer returned is a borrowed reference and not a new reference.  Without them, the Window / Invisible object would never be freed.  I don't know if the generic sink function handles this or not; the last time I looked at this was when I ran into the bug that these functions fix.
Comment 12 Tomeu Vizoso 2010-01-08 13:12:15 UTC
(In reply to comment #11)
> The sink_gtkwindow() and sink_gtkinvisible() functions are there because the
> pointer returned is a borrowed reference and not a new reference.  Without
> them, the Window / Invisible object would never be freed.  I don't know if the
> generic sink function handles this or not; the last time I looked at this was
> when I ran into the bug that these functions fix.

The generic sink function is there to handle this. If it didn't do so, tests wouldn't pass.
Comment 13 John Ehresman 2010-01-08 16:03:54 UTC
Do the tests cover this case?  I don't recall writing tests when the custom sink functions went in years ago (my bad).

Note that I'm not opposed to dropping the custom functions (it's probably a good idea actually), I was just trying to explain why they were added.  I'd like to say I'll look at it, but I don't have the spare cycles to do so right now.
Comment 14 Tomeu Vizoso 2010-01-10 11:19:38 UTC
(In reply to comment #13)
> Do the tests cover this case?  I don't recall writing tests when the custom
> sink functions went in years ago (my bad).

The patch before the last failed in some tests because of refcounting, though a quick grep didn't showed anything specific to sinkfuncs. When I get some time I will apply the old patch and check that the tests that fail are sufficient.
Comment 15 Tomeu Vizoso 2010-01-10 20:32:21 UTC
I don't think we can add a test to check that gtk.Window() is sunk after creation without wrapping GObject.is_floating().

I think it's correct to ask for evidence in such a low level issue, but then someone needs to actually look at it when presented. If the patch is read as well as the implementations of g_object_is_floating, G_IS_INITIALLY_UNOWNED and g_object_ref_sink, it will be clear that this patch is safe and correct.

Also, if you play a bit around the pygobject and pygtk test suites, you will see that they won't pass if you don't either register the sinkfuncs or apply this patch.

For now, I'm going to workaround this issue in Pygi by registering a dummy sinkfunc, but I think that for the sake of keeping pygobject updated, these issues should be given some consideration.
Comment 16 johnp 2010-05-18 16:51:00 UTC
Created attachment 161366 [details] [review]
[PATCH] Drop sinkfuncs. Fixes bug #583909

 gobject/pygobject.c |   42 ++++++++----------------------------------
 gobject/pygobject.h |    1 +
 2 files changed, 9 insertions(+), 34 deletions(-)
Comment 17 johnp 2010-05-18 17:01:49 UTC
New patch moves the call to pygobject_sink back to  pygobject_register_wrapper_full since there are a couple of code paths for wrapping a gobject, all of which call pygobject_register_wrapper_full.

It should be noted that PyGtk's use of special cases for GtkWindow and invisible objects are not needed since the combination of both G_IS_INITIALLY_UNOWNED(obj) and g_object_is_floating(obj) covers all bases.  In the case of GtkWindow G_IS_INITIALLY_UNOWNED(obj) returns true and g_object_is_floating returns false but since we compare the values using or in the conditional we catch that case.
Comment 18 Tomeu Vizoso 2010-05-22 12:12:55 UTC
Sorry, git bz closed this ticket because another commit referenced it with the full url.
Comment 19 Tomeu Vizoso 2010-06-08 11:07:52 UTC
Comment on attachment 135661 [details] [review]
passes the tests

I'm unmarking this patch as obsolete because this actually passes the tests.
Comment 20 Tomeu Vizoso 2010-06-08 11:10:21 UTC
Review of attachment 161366 [details] [review]:

This is not passing the tests here:

......................F.............F..F...........F.........................................................................................................................................................
======================================================================
FAIL: testErrors (test_properties.TestProperty)
----------------------------------------------------------------------
Traceback (most recent call last):
  • File "../tests/test_properties.py", line 245 in testErrors
    self.assertRaises(TypeError, gobject.property, type=GEnum)
AssertionError: TypeError not raised

======================================================================
FAIL: testGCCollection (test_subtype.TestSubType)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "../tests/test_subtype.py", line 146, in testGCCollection
    self.assertEqual(aref(), None)
AssertionError: <gtk.Button object at 0x91a9c0c (GtkButton at 0x9031090)> != None

======================================================================
FAIL: testGObjectUnref (test_subtype.TestSubType)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "../tests/test_subtype.py", line 134, in testGObjectUnref
    self.assertEqual(bref(), None)
AssertionError: <gtk.Button object at 0xb757193c (GtkButton at 0x9031180)> != None

======================================================================
FAIL: testWeakRefCallback (test_subtype.TestSubType)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "../tests/test_subtype.py", line 181, in testWeakRefCallback
    self.assertEqual(self._wr_args, (1, 2, 3))
AssertionError: None != (1, 2, 3)

----------------------------------------------------------------------
Ran 205 tests in 13.424s

FAILED (failures=4)
Comment 21 johnp 2010-06-08 20:18:22 UTC
I'm getting segmentation faults with make check from a clean build
Comment 22 johnp 2010-06-08 22:52:19 UTC
With the patch applied and removing the gio tests which for some reason are crashing me, my patch passes make check
Comment 23 Tomeu Vizoso 2010-06-09 07:52:55 UTC
Maybe we should enter a ticket about your make check failures in a clean build, and once we have that fixed, add to this ticket which errors you get with my patch?
Comment 24 johnp 2010-06-09 18:19:58 UTC
Created attachment 163220 [details] [review]
Drop sinkfuncs. Fixes bug #583909

* use g_object methods to sink floating refs instead of allowing
  custom sink functions to be registered
* we now sink inside of pygobject_new_full to handle cases where
  a library creates its own gobject via g_object_new and just
  needs a python wrapper
  - a previous patch had done the sink when creating the gobject,
    since it needs to call pygobject_new_full to wrap the object,
    this patch handles both cases (e.g. pygobject created object
    and externally created gobject)
Comment 25 Tomeu Vizoso 2010-06-10 10:20:03 UTC
Review of attachment 163220 [details] [review]:

It's failing the pygtk tests :(

.................................................E.............E......
GLib-GObject-CRITICAL **: g_object_get_qdata: assertion `G_IS_OBJECT (object)' failed
aborting...
make[2]: *** [check-local] Trace/breakpoint trap (core dumped)
Comment 26 Tomeu Vizoso 2010-06-10 10:37:51 UTC
(In reply to comment #25)
> Review of attachment 163220 [details] [review]:
> 
> It's failing the pygtk tests :(
> 
> .................................................E.............E......
> GLib-GObject-CRITICAL **: g_object_get_qdata: assertion `G_IS_OBJECT (object)'
> failed
> aborting...
> make[2]: *** [check-local] Trace/breakpoint trap (core dumped)

Looks like a missing _ref() somewhere:

  • #0 IA__g_logv
    at gmessages.c line 545
  • #1 IA__g_log
    at gmessages.c line 569
  • #2 IA__g_return_if_fail_warning
  • #3 IA__g_object_get_qdata
    at gobject.c line 2529
  • #4 pygobject_get_inst_data
    at pygobject.c line 101
  • #5 pygobject_dealloc
    at pygobject.c line 979
  • #6 subtype_dealloc
    at Objects/typeobject.c line 1024
  • #7 frame_dealloc

Comment 27 Tomeu Vizoso 2010-06-10 10:50:14 UTC
We miss a _ref() for python subclasses of GtkWindow and GtkContainer, different codepath?
Comment 28 Tomeu Vizoso 2010-06-10 11:45:02 UTC
Applying this to your patch makes all tests I have to pass:

diff --git a/gobject/gobjectmodule.c b/gobject/gobjectmodule.c
index 69f3597..50a577c 100644
--- a/gobject/gobjectmodule.c
+++ b/gobject/gobjectmodule.c
@@ -2258,9 +2258,9 @@ pygobject_constructv(PyGObject  *self,
         pygobject_init_wrapper_set(NULL);
         if (self->obj == NULL) {
             self->obj = obj;
-            pygobject_sink(obj);
             pygobject_register_wrapper((PyObject *) self);
         }
+        pygobject_sink(obj);
     } else {
         int i;
         for (i = 0; i < n_parameters; ++i)

The idea is that for python subclasses, self->obj won't be NULL anymore after g_object_newv but we also want to sink those.
Comment 29 johnp 2010-06-10 15:21:39 UTC
Ah, ok, I approve the change.  If you approve the rest of the patch I say ship it!!!
Comment 30 Edward Hervey 2010-06-21 09:11:53 UTC
This breaks modules depending on pygobject and that were using the sink functions (namely gst-python, see bug #621632)

Could you re-instate (in addition) the previous behaviour so all those modules don't just break ?

 Marking that API as deprecated would also give dependent modules time to notice there will be a change and accordingly update to use the gobject way.
Comment 31 Tomeu Vizoso 2010-06-21 14:57:31 UTC
Created attachment 164223 [details] [review]
Fall back to use the floating references API in glib if there isn't a sinkfunc defined.

* tests/*: Add ref counting tests for floating objects
* gobject/gobjectmodule.c, gobject/pygobject.c: Fall back to g_object_ref_sink
  or g_object_ref if there isn't a sinkfunc defined. Make sure that
  pygobject_sink gets called only once per GObject instance.
Comment 32 Johan (not receiving bugmail) Dahlin 2010-06-21 15:10:33 UTC
Review of attachment 164223 [details] [review]:

Rest looks good to me, as long as gst-python keeps on working.

::: gobject/pygobject.c
@@ +897,3 @@
  * pygobject_new_full:
  * @obj: a GObject instance.
+ * @sink: whether to sink any floating reference found on the GObject. DEPRECATED.

Warn if someone provides the sink func to get gst-python etc migrated.
Comment 33 Tomeu Vizoso 2010-06-21 15:36:55 UTC
Attachment 164223 [details] pushed as 00a85f6 - Fall back to use the floating references API in glib if there isn't a sinkfunc defined.
Comment 34 Edward Hervey 2010-06-23 07:01:32 UTC
*** Bug 622436 has been marked as a duplicate of this bug. ***