last_unref (was: Re: Inlining pixbufs)



On 27 Jun 2000, Federico Mena Quintero wrote:

> Havoc Pennington <hp@redhat.com> writes:

> Also, if you feel like playing with GdkPixbuf stuff, could you please
> implement Tim's idea for the last_unref handler?  We do need that
> before gdk-pixbuf can go 1.0, and Nautilus needs it.

i've finally settled on an API for this on the GTypeClass level, after
reading up owen's thoughts about cache/GC schemes, and consulting a
couple of other sources.
bascially i decided to go for simplicity in the API, rather than
extraordinary flexibility (such as providing an extra callback function
for a ref() call after a class was exposed to the cache chain).
so the GTypeClass API is now:

/*< public >*/
gpointer g_type_class_ref               (GType                   type);
gpointer g_type_class_peek              (GType                   type);
void     g_type_class_unref             (gpointer                g_class);
gpointer g_type_class_peek_parent       (gpointer                g_class);

typedef gboolean (*GTypeClassCacheFunc)      (gpointer         cache_data,
                                              GTypeClass      *g_class);

/*< private >*/ /* or "obscure", for what it's worth ;) */
void             g_type_add_class_cache_func    (gpointer            cache_data,
                                                 GTypeClassCacheFunc cache_func);
void             g_type_remove_class_cache_func (gpointer            cache_data,
                                                 GTypeClassCacheFunc cache_func);
void             g_type_class_unref_uncached    (gpointer            g_class);

with the new functions described in ChangeLog:

  g_type_add_class_cache_func(): provide a cache_func/data pair to be
  called  prior to a type nodes last_unref() function, this can be used
  to prevent premature class destruction. multiple installed cache_func()
  will be chained upon last_unref() untill one of them returns TRUE.
  the cache_func()s have to check the class id passed in to figure whether
  they actually want to cache the class of this type (since all classes
  are routed through the cache_func() chain).

  g_type_remove_class_cache_func(): remove a previously installed
  cache_func/data pair. the cache maintained by this function has to be
  clear when calling g_type_remove_class_cache_func() to avoid leaks.

  g_type_class_unref_uncached(): class unref function for cache_func()
  implementations, unreferences a class omitting the cache chain (and
  therefore unref->cache->unref->... loops).


internally, that amounts to:

void
g_type_class_unref (gpointer g_class)
{
  [...]
    type_data_unref (node, FALSE);
  [...]
}

void
g_type_class_unref_uncached (gpointer g_class)
{
  [...]
    type_data_unref (node, TRUE);
  [...]
}

static inline void
type_data_unref (TypeNode *node,
                 gboolean  uncached)
{
  [...]
  if (node->data->common.ref_count > 1)
    node->data->common.ref_count -= 1;
  else
    {
      [...]
      type_data_last_unref (NODE_TYPE (node), uncached);
    }
}

static void
type_data_last_unref (GType    type,
                      gboolean uncached)
{
  [...]
  if (node->is_classed && node->data && node->data->class.class)
    {
      guint i;

      for (i = 0; i < n_class_cache_funcs; i++)
        if (class_cache_funcs[i].cache_func (class_cache_funcs[i].cache_data, node->data->class.class))
          break;
    }

  if (node->data->common.ref_count > 1) /* may have been re-referenced meanwhile */
    node->data->common.ref_count -= 1;
  else
    [ finalize class ]
}
  
> 
> Thanks,
> 
>   Federico
> 

---
ciaoTJ





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