GnuCash  4.14+
Files | Macros


file  gnc-gobject-utils.h
 Gobject helper routines.


 Some macros derived from glib type macros. More...
#define _GNC_DEFINE_TYPE_EXTENDED_BEGIN(TypeName, type_name, TYPE_PARENT, flags)

Gobject Tracking Functions

This set of functions is used to maintain a "database" of objects that are built on top of a GObject (any level of nesting).

This database is simply a hash table of lists. The hash table takes the object name as its key and returns a list of all objects of that type. The object is then added to, deleted from, or looked up in the list. The database can also be queried for a list of all objects of a specified type. This can be used to find pre-existing GncTreeModels, etc. (In this case performing a search for a specific object wouldn't help because the information being inspected is private to the object.)

Any object added to this database during the execution of gnucash should be deleted from it before completion of the program. WHen the program shuts down, a list of all objects still in the database will be dumped out to the logfile. This should help developers find memory leaks in their code where an object is lost, or is not release because it gained an extra reference at some point during its lifetime.

void gnc_gobject_tracking_remember (GObject *object, GObjectClass *klass)
 Tell gnucash to remember this object in the database. More...
void gnc_gobject_tracking_forget (GObject *object)
 Tell gnucash to drop this object from the database. More...
const GList * gnc_gobject_tracking_get_list (const gchar *name)
 Get a list of all known objects of a specified type. More...
void gnc_gobject_tracking_dump (void)
 Dump the entire object tracking database via the g_log() family of functions. More...

Detailed Description

Macro Definition Documentation


static void type_name##_init (TypeName *self, void *class); \
static void type_name##_class_init (TypeName##Class *klass); \
static gpointer type_name##_parent_class = NULL; \
static gint TypeName##_private_offset; \
static inline gpointer \
type_name##_get_instance_private (TypeName *self) \
{ \
return (G_STRUCT_MEMBER_P (self, TypeName##_private_offset)); \
} \
GType \
type_name##_get_type (void) \
{ \
static gsize g_define_type_id_static = 0; \
if (g_once_init_enter (&g_define_type_id_static)) \
{ \
GType g_define_type_id = \
g_type_register_static_simple (TYPE_PARENT, \
g_intern_static_string (#TypeName), \
sizeof (TypeName##Class), \
(GClassInitFunc) type_name##_class_intern_init, \
sizeof (TypeName), \
(GInstanceInitFunc) type_name##_init, \
(GTypeFlags) flags); \
{ /* custom code follows */

Definition at line 129 of file gnc-gobject-utils.h.


/* following custom code */ \
} \
g_once_init_leave (&g_define_type_id_static, g_define_type_id); \
} \
return g_define_type_id_static; \
} /* closes type_name##_get_type() */

Definition at line 160 of file gnc-gobject-utils.h.


{ \
const GInterfaceInfo g_implement_interface_info = { \
(GInterfaceInitFunc)(void (*)(void *, void *)) iface_init, NULL, NULL \
}; \
g_type_add_interface_static (g_define_type_id, TYPE_IFACE, &g_implement_interface_info); \

Some macros derived from glib type macros.

In glib type_name##init function only has one parameter. We need the 2nd class parameter in certain calls. The main difference is static void type_name##_init (TypeName *self, void *class); instead of static void type_name##_init (TypeName *self); this code may need updating in future releases as glib changes.

Definition at line 120 of file gnc-gobject-utils.h.

Function Documentation

◆ gnc_gobject_tracking_dump()

void gnc_gobject_tracking_dump ( void  )

Dump the entire object tracking database via the g_log() family of functions.

This function is only called when gnucash exits, and at that point all of the objects should have been removed from the database and freed. Any object remaining is the result of a memory/object leakage.

Definition at line 104 of file gnc-gobject-utils.c.

105 {
106  GHashTable *table;
108  //printf("Enter %s:\n", G_STRFUNC);
109  table = gnc_gobject_tracking_table();
111  if (g_hash_table_size(table) > 0)
112  {
113  PINFO("The following objects remain alive:");
114  g_hash_table_foreach_remove(table, (GHRFunc)gnc_gobject_dump_list, NULL);
115  }
116  //printf("Leave %s:\n", G_STRFUNC);
117 }
#define PINFO(format, args...)
Print an informational note.
Definition: qoflog.h:256

◆ gnc_gobject_tracking_forget()

void gnc_gobject_tracking_forget ( GObject *  object)

Tell gnucash to drop this object from the database.

objectThe object to be dropped.

Tell gnucash to drop this object from the database.

Definition at line 203 of file gnc-gobject-utils.c.

204 {
205  if (gnc_gobject_tracking_forget_internal(object))
206  g_object_weak_unref(object, gnc_gobject_weak_cb, NULL);
207 }

◆ gnc_gobject_tracking_get_list()

const GList* gnc_gobject_tracking_get_list ( const gchar *  name)

Get a list of all known objects of a specified type.

nameThe type name of the objects to be found. This is the name used when the object type was initialized. If unknown, it can be found by calling G_OBJECT_TYPE_NAME(object).
A GList of objects of the specified type. This list is owned by the tracking code and must not be modified by the caller.

Definition at line 229 of file gnc-gobject-utils.c.

230 {
231  GHashTable *table;
232  GList *list;
234  //printf("Enter %s: name %s\n", G_STRFUNC, name);
235  table = gnc_gobject_tracking_table();
236  list = g_hash_table_lookup(table, name);
237  //printf("Leave %s: list %p\n", G_STRFUNC, list);
238  return list;
239 }

◆ gnc_gobject_tracking_remember()

void gnc_gobject_tracking_remember ( GObject *  object,
GObjectClass *  klass 

Tell gnucash to remember this object in the database.

objectThe object to be tracked. This can be a fully or partially instantiated object.
klassThe class structure for the object. This argument may be NULL if a fully instantiated object is passed in as the first argument. If a partially instantiated object is provided (I.E. a parent class called this function) then this argument is required. This is necessary because the class of the object changes as each of the parent class is instantiated. The class structure, however, status constant and always reflects the fully instantiated object.

Definition at line 123 of file gnc-gobject-utils.c.

124 {
125  GHashTable *table;
126  GList *list;
127  const gchar *name;
129  g_return_if_fail(G_IS_OBJECT(object));
131  /* Little dance here to handle startup conditions. During object
132  * initialization the object type changes as each parent class
133  * is initialized. The class passed to the initialization function
134  * is always the ultimate class of the object. */
135  if (klass == NULL)
136  klass = G_OBJECT_GET_CLASS(object);
137  name = g_type_name(G_TYPE_FROM_CLASS(klass));
139  //printf("Enter %s: object %p of type %s\n", G_STRFUNC, object, name);
140  table = gnc_gobject_tracking_table();
141  list = g_hash_table_lookup(table, name);
143  if (g_list_index(list, object) != -1)
144  {
145  g_critical("Object %p is already in list of %s", object, name);
146  //printf("Leave %s: already in list\n", G_STRFUNC);
147  return;
148  }
150  list = g_list_append(list, object);
151  g_hash_table_insert(table, g_strdup(name), list);
153  g_object_weak_ref(object, gnc_gobject_weak_cb, NULL);
154  //printf("Leave %s:\n", G_STRFUNC);
155 }