From: Axel S. <A....@ke...> - 2005-11-02 13:10:38
|
On Wed, 2005-11-02 at 12:33 +0000, Duncan Coutts wrote: > Clearly the gc is no longer retained by the end of the event handler so > the garbage collecor should clean it up. So perhaps we've got a bug with > our reference counting. > > gcNew calls makeNewGObject which is defined like so: > > makeNewGObject :: GObjectClass obj => > (ForeignPtr obj -> obj) -> IO (Ptr obj) -> IO obj > makeNewGObject constr generator = do > objPtr <- generator > objectRef objPtr > obj <- newForeignPtr objPtr (objectUnref objPtr) > return $ constr obj > > http://developer.gnome.org/doc/API/2.0/gobject/gobject-memory.html > states: > The reference count is, unsurprisingly, initialized to one by > g_object_new which means that the caller is currenly the sole > owner of the newly-created reference. When the reference count > reaches zero, that is, when g_object_unref is called by the last > client holding a reference to the object, the dispose and the > finalize class methods are invoked. Yes, I made a bit of a mistake here. The only solution is probably to: - create a new function refGObject :: GObjectClass obj => (ForeignPtr obj -> obj) -> Ptr obj -> IO obj (note that I dropped the "IO" from the pointer argument, in the hope that most places where we need this pass something like (return ptr) ) - go through the 200+ usages of makeNewGObject and see if it should be replaced by refGObject. The minority should. This is definitely a new todo-item. > So we can see that the above code is supicious at least. When objPtr > points to an object that was newly constructed it's reference count is > already 1. So we should not be objectRef'ing (but attaching objectUnref > as a ForeignPtr finaliser is correct). > > However this code is correct for when we obtain a pointer to an object > that was not freshly constructed. In that case to keep the object alive > we must ref and unref it. > > So the constructor case is special. > > We get away with doing the same thing for fresh and non-fresh GtkObject > pointers because of the "floating reference" (though we could > distinguish the cases and avoid the call to objectSink). True. In the GtkObject case the initial reference count is 0 with the floating bit set. I simply copied to code from GtkObject to GObject and removed floating bit. Sorry about this, will fix, Axel. |