Re: getting instance pointer in weak ref notify



On 13 Aug 2001, Owen Taylor wrote:

> > In this case, the instance pointer is only needed for its value -- it
> > isn't dereferenced.  Unfortunately, this sort of thing is pretty much
> > impossible with the current weak ref code (the current weak ref code
> > doesn't offer much above setting data with a destroy notify).
> > 
> > I propose adding an extra "instance_pointer" parameter to the GWeakNotify
> > function type, so that the notify function can use the pointer value.  I
> > know that you don't want to make it easy for people to shoot themselves in
> > the foot, but leaving this out greatly reduces the usefulness of the API.
> > 
> > Possible ways to decrease the likelyhood of foot shootings could include:
> >   1) call the instance_pointer parameter
> >      "instance_pointer_dont_ref_or_use".
> >   2) set the class pointer in the GObject to NULL while notifying weak
> >      refs, so any of the cast check macros would fail.  This puts the
> >      instance in an inconsistent state though.
> >   3) record the reference count before calling the weak notify function
> >      and comparing the saved value with the actual one after calling, and
> >      spit out a warning if they differ.
> 
> On consideration, I think it's probably better in balance to add the
> objectf pointer back in. If people really want to shoot themselves
> in the foot, they'll do the same thing as they would to work around
> the limitation of not having the object * - create a structure
> holding the object and a pointer to the real data.
> 
> (Or, hold a back pointer to the object from the real data).

after thinking about james' mail for a while (and reconsidering sven's)
i suspected you'd say this ;) and agree.

> I don't think any of these safeguards are really that useful, and
> I think they are dangerous as well -- since we have premature 
> notification of weak references (for, say, gtk_widget_destroy())
> it's perfectly reasonable for _other_ people than the weak reference
> holder to be manipulating the object at that point.

the question is whether such code portions should be triggered from
weak-ref notifiers. note that we already hack the object during
the weak-ref callback invocation:

static void
g_object_real_dispose (GObject *object)
{
  guint ref_count;

  g_signal_handlers_destroy (object);
  g_datalist_id_set_data (&object->qdata, quark_closure_array, NULL);

  /* yes, temporarily altering the ref_count is hackish, but that
   * enforces people not jerking around with weak_ref notifiers
   */
  ref_count = object->ref_count;
  object->ref_count = 0;
  g_datalist_id_set_data (&object->qdata, quark_weak_refs, NULL);
  object->ref_count = ref_count;
}

if weak-refs aren't cleared from g_object_real_dispose(),
i.e. through last-unref, the ref-count will already be 0,
so invoking _ref/_unref from weak-ref notifiers is an error
either way. in g_object_real_dispose() i'm just enforcing that,
since object->ref_count = 0; makes any _ref/_unref call
puke (relying on the g_return_if_ail (o->ref_count>0); in
_ref/_unref to preserve object integrity).

i don't think there are any good reasons to not do the above
temporary ref-count hackery, since removing it will just
masquerade bugs under certain occasions, so i intend to keep that.

> So, the main question in my mind is:
> 
>  typedef GWeakNotify (GObject *object, gpointer data);
> 
> vs.
> 
>  typedef GWeakNotify (gpointer data, GObject *object);

consistency would probably suggest

typedef void (*GWeakNotify) (GObject *object, gpointer data);

however, i tend to think it's more important to preserve
g_object_weak_ref (o, g_free, data); (especially since that's
also the API we had for GtkObject weakrefs) which suggests:

typedef void (*GWeakNotify) (gpointer data, GObject *object);

though that still requires an extra cast for the g_free argument
in the example above.

so personally, i'd prefer:

typedef void (*GWeakNotify) (gpointer data);

and in gobject.c:

static void invoke_weak_ref (GObject *o, GWeakNotify wnotify, gpointer data)
{
  typedef void (*RealWekRef) (gpointer data, GObject *o_pointer);
  RealWekRef func = (RealWekRef) wnotify;
  
  func (data, o);
}

then in the docs we can make a note that people who really need it can
use void my_func (gpointer data, gpointer obj); as weak-ref callback
signature, but that isn't recommended because there's not much they
could do with the object, apart from e.g. using its adress as hash-index
or the like.

that way, only poeple who bothered reading the docs thoroughly can
use the extra object pointer, and can't claim they haven't been warned.

comments?

> 
> Regards,
>                                         Owen
> 

---
ciaoTJ





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