Re: tooltips and refcounts




Tim Janik <timj@gtk.org> writes:

> On 2 Sep 1998, Owen Taylor wrote:
> 
> > Tim Janik <timj@gtk.org> writes:
> > 
> > > On Mon, 10 Aug 1998, George wrote:
> >  
> > > > ok .. this is kind of weird (I think so) ...
> > 
> > > > adding a tooltip to a widget increases it's refcount ...  this
> > > > doesn't make sense to me really ... the tooltip doesn't own the
> > > > widget but just the opposite ... the tooltip should bind the
> > > > widgets destroy signal and die when the object is destroyed ...
> > 
> > > > I thought refcounts were an owner->slave relationship ...
> >  
> > > hm, that's not perfectly true. you increase the ref count for a widget
> > > if you are keeping a reference to it, which is what the tooltip does.
> > 
> > But, the point George is trying to make is that the application
> > writer does not want to know that the tooltips is keeping
> > around a pointer to the tooltips. 
> 
> as i stated in an even older mail on this subject, the *actuall* ref count
> is not of the application writers bussiness. whether its the widgets tooltip
> or GLE or an interpreter or some gtk internal code, e.g. a long lasting
> timeout, who's holding a pending refcount on an object is really of no
> interest to an application. that's because ref_counts only care about the
> widget's memory allocation and should have nothing to do with their
> actuall on-screen appearance. that's why containers destroy widgets
> explicitely upon their destruction and don't just decrement a refcount.

The actual value of the ref count should not matter, but an
application should be entitled to assume if that there are
mystical forces holding reference counts to its widgets,
then those mystical forces want to keep the widget around.

GTK should have no:

 gtk_widget_detach_genies()

call.
 
> > Generally, one assumes that one drops the last refcount to a widget,
> > it should go away, without needing to also destroy it. Once
> > you've set a tooltip on a widget, this no longer works, and it
> > will not go away until you destroy it explicitely.
> 
> this assumption is false, refcounting.txt describes this in a detailed
> manner, refcounting cares about the finalization stage of an object, it
> just happens that this implies the explicit destruction as well, which
> is why a not yet destroyed object gets destroyed when the last refcount
> drops.
> if you want a widget to "go away", i.e. take visual action on screen,
> you have to gtk_widget_destroy() it.

No, removing a widget from it's parent will always cause visual
action to appear on the screen.

> > But, the root point is that there is _no need_ for the tooltips
> > to reference the widget - since they connect to the "destroy"
> > signal, if we don't ref the widget, then the behavior will
> > be that the tip will persist as long as the widget exists
> > and then go away. (If you are paranoid, you could check for
> > !GTK_OBJECT_DESTROYED() when setting the tip)
> > 
> > This is a classical "weak reference".
> 
> you are right that the tooltip's ref count on widgets is redundant, but
> even though it may short-time-cure the panels problems, that's just fighting
> symptoms. if the panel relies on certain refcounts, that behaviour is
> _conceptually_ wrong. maybe its currently just the tooltips that cause
> this assumption to fail, but you can soon encounter different problems
> wrt refcounting with such behaviour, e.g. if you use GLE or if we someday
> decide to implement some kind of global GC for gtk.

My opinion on this matter is:

 * If we had global GC, then we would also have a weak-reference
   mechanism, and GLE would be using that weak-reference
   mechanism.

 * Destruction is a hack, because we cannot implement global GC
   properly, and thus cannot detect circular links, we need
   to have a "break all links" operation.

 * We currently need to encourage people to destroy() the
   widgets they create, when in doubt, because double destruction is
   safe, and we cannot expect people to understand the details
   of the refcounting logic.

 * But, we cannot expect people to always know when they 
   should be in doubt, and therefore should try extremely hard
   not to keep extra refcounts around.
 
> > > > this tooltip thing actually makes things complicated ... in the panel for
> > > > example I have a lot of widgets for which I set tooltips ...
> > > > 
> > > > I have put a "set tooltip to NULL function" in the applet clean up code ...
> > > > however that code isn't allways called ... for example when I remove a panel
> > > > (a drawer) ... I rely on getting the destroy signal from the applet ...
> > > > which however never comes .. as when the widget is unparented it still has
> > > > a refcount hanging around .. and the widget will stay and eat up ram (plus
> > > > I can't do cleanup) .... manually going in and setting all tooltips to NULL
> > > > seems like a VERY UGLY solution ...
> >  
> > > you most probably don't do the right thing in your code then.
> > > you either just want to reparent a widget from one window to another (and
> > > in this case there is no reason for gtk to implicitely remove the actual tip
> > > you have set for this widget), or you want to destroy it, in which case the
> > > tip will be removed. but either way, if you want widgets to be destroyed,
> > > call gtk_widget_destroy (widget) on 'em, but don't unparent or remove
> > > a widget and then wait for its destruction.
> > 
> > Yet you _should_ be able to do that. One big point of the
> > refcounting scheme is to make things easy on interpreted languages.
> > The interpreted language ref's and sinks the widget upon creation.
> > If, when the interpreted language loses its last refcount to
> > the widget, the widget should be freed if it is not in the
> > widget heirarchy.
> > 
> > There is a reason why we don't just create widgets with a reference
> > count of 1 and decrement on destruction. But you seem to
> > be saying that that would be OK behavior - i.e.:
> > 
> >  * A widget won't be freed until someone calls gtk_widget_destroy()
> > 
> > Ugh.
 
> this is actually the case for toplevels, you can sink() and ref()+unref()
> on a gtkwindow anyway you want, it won't get destroyed untill you explicitely
> state so. most other objects actually get destroyed on their initial sink()
> call if not ref()ed before, but that's just because destruction is an implicit
> requirement for finalization, which is what refcounts are really about.
> 
> so the baseline is, if you want a widget to disappear: destroy it, unparentation
> will immediatedly be taken care off, memory deallocation is handled at
> finalization stage which might get delayd for reasons not apparent to the
> application/programmer.

Toplevels are a special case. I don't think any GTK+ programmer
would be suprised to hear that a toplevel won't be destroyed
until you call gtk_widget_destroy() on it.

The bottom line is - I don't mind changing the panel to explicitely
destroy the widgets it is done with, since that is the prudent
thing for an application to do. But I really would like to
see the excess refcount in tooltips disappear. There will always
be sufficiently complicated cases so that applications may
forget to destroy widgets, and in those cases, if we can get
it right, we should get it right.

Regards,
                                        Owen



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]