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 127909 - Reference counting of BonoboObject-derived types is broken
Reference counting of BonoboObject-derived types is broken
Status: RESOLVED FIXED
Product: gnome-python
Classification: Deprecated
Component: bonobo
2.0.x
Other Linux
: Normal major
: ---
Assigned To: Python bindings maintainers
Python bindings maintainers
Depends on:
Blocks: 107658
 
 
Reported: 2003-11-25 19:03 UTC by Gustavo Carneiro
Modified: 2004-12-22 21:47 UTC
See Also:
GNOME target: ---
GNOME version: 2.5/2.6


Attachments
example program demonstrating problem (535 bytes, text/plain)
2003-11-25 19:03 UTC, Gustavo Carneiro
  Details
codegen fix to honor the caller-owns-return flag in constructors (726 bytes, patch)
2003-12-04 19:30 UTC, Gustavo Carneiro
none Details | Review
example of usage of new codegen feature in bonobo (499 bytes, patch)
2003-12-04 19:36 UTC, Gustavo Carneiro
none Details | Review
slightly changed test program (474 bytes, text/plain)
2003-12-04 19:36 UTC, Gustavo Carneiro
  Details
full patch to fix all bonobo constructors (10.60 KB, patch)
2003-12-04 21:57 UTC, Gustavo Carneiro
none Details | Review
new codegen patch, a longer but more correct one. (4.36 KB, patch)
2003-12-20 13:02 UTC, Gustavo Carneiro
none Details | Review

Description Gustavo Carneiro 2003-11-25 19:03:10 UTC
The example program I'll attach ilustrates the problem.  My theory on
what is happening follows.

  A BonoboObject contains two reference counters:
    1. the GObject reference count;
    2. the Bonobo::Unknown reference count.

  When a BonoboObject is created, both counters are initialized to 1.  When
the bonobo reference count drops to zero, the 'destroy' signal is fired,
and after that the GObject reference count is decremented.  The reason for
this is that you may want to keep a floating GObject reference, and then
let the (remote) CORBA client manage the lifecycle of the object.  When the
last unref happens, bonobo unrefs the GObject so that it is destroyed.

  Unfortunately, gnome-python is treating BonoboObject like any ordinary
GObject, which it is not.  With BonoboObject, the caller owns the bonobo
reference count, but not the GObject reference count.  Based on this, I see
two possible solutions:
    1. add an extra reference to the GObject in the constructor of
BonoboObject-derived classes, or
    2. keep only a weak link to the GObject.
Comment 1 Gustavo Carneiro 2003-11-25 19:03:51 UTC
Created attachment 21804 [details]
example program demonstrating problem
Comment 2 James Henstridge 2003-11-26 14:34:45 UTC
Been looking through the Bonobo code to get a feel for what the
lifecycle for an individual BonoboObject and the aggregate behave in a
C program.  It is something like this:

1) When a BonoboObject gets created, a BonoboAggregateObject gets
   created with aggregate refcount 1.  The GObject reference count
   is incremented to give a refcount of 2.

2) bonobo_object_add_interface() has the effect of merging the
   BonoboAggregateObjects for each BonoboObject into one (it
   essentially joins the BonoboObject lists in the aggregate and
   fixes up the refcounts).

3) bonobo_object_ref() increments the BonoboObject's aggregate's
   refcount.

4) on bonobo_object_unref(), the aggregate refcount gets decremented.
   If the refcount would hit zero, then bonobo_object_destroy_T()
   gets called first.  This goes through the BonoboObject list for
   the aggregate and emits the "destroy" signal on each one then
   decrements it's GObject reference count.

   If the aggregate doesn't get resurrected by the destructors,
   bonobo_object_finalize_internal_T() gets called which removes
   the BonoboObjects from the aggregate's object list, deactivates
   the servants and decrements the GObject reference count a
   second time.

Some key point is that when you create a BonoboObject, you own the
single aggregate reference count, while the aggregate owns the two
GObject references on the actual BonoboObject.

How do things differ for Python?  We assume that when you construct an
object, you would own the GObject reference to it.  This means that if
the aggregate gets finalised before the Python wrapper for the
BonoboObject does, it will find that the BonoboObject has already hit
refcount==0 (similar will happen for the other order).

The closest we come to this situation in PyGTK is GtkWindows -- when
you create a GtkWindow with gtk_window_new(), you don't actually own
the initial reference.  Things are special cased to g_object_ref()
GtkWindows on construction to work around this.  We could probably do
the same for BonoboObjects.

Does this sound like it might be the cause of the problem?
Comment 3 Gustavo Carneiro 2003-11-26 16:18:36 UTC
  Just so this details aren't lost.  The 2 GObject references are:
    1- the implicit reference created by the constructor;
    2- An additional ref added in bonobo_object_constructor
    
  The g_object_unref's are in:
    bonobo_object_finalize_internal_T
    bonobo_object_finalize_servant

  And I think you have indeed spotted the problem.  PyGTK does not own
the GObject reference owned by BonoboObject constructors, so we need
to add an additional g_object_ref in the python constructors.
Comment 4 Gustavo Carneiro 2003-12-04 19:30:11 UTC
Created attachment 22105 [details] [review]
codegen fix to honor the caller-owns-return flag in constructors
Comment 5 Gustavo Carneiro 2003-12-04 19:36:02 UTC
Created attachment 22107 [details] [review]
example of usage of new codegen feature in bonobo
Comment 6 Gustavo Carneiro 2003-12-04 19:36:37 UTC
Created attachment 22108 [details]
slightly changed test program
Comment 7 Gustavo Carneiro 2003-12-04 19:37:43 UTC
  The extra g_object_ref takes care of problem completely. :-)
Comment 8 Gustavo Carneiro 2003-12-04 21:57:49 UTC
Created attachment 22118 [details] [review]
full patch to fix all bonobo constructors
Comment 9 Gustavo Carneiro 2003-12-20 13:02:30 UTC
Created attachment 22592 [details] [review]
new codegen patch, a longer but more correct one.
Comment 10 Gustavo Carneiro 2003-12-20 13:04:07 UTC
Committed both codegen and gnome-python parts.  Bug should be fixed.