Add _g_closure_is_void to check for NULL vfuncs
authorAlexander Larsson <alexl@redhat.com>
Tue, 28 Feb 2012 14:48:20 +0000 (15:48 +0100)
committerAlexander Larsson <alexl@redhat.com>
Fri, 2 Mar 2012 16:13:03 +0000 (17:13 +0100)
https://bugzilla.gnome.org/show_bug.cgi?id=661140

gobject/gclosure.c
gobject/gtype-private.h

index bf79754..4cee41c 100644 (file)
@@ -1025,6 +1025,42 @@ g_type_iface_meta_marshal (GClosure       *closure,
                      callback);
 }
 
+gboolean
+_g_closure_is_void (GClosure *closure,
+                   gpointer instance)
+{
+  GRealClosure *real_closure;
+  GTypeClass *class;
+  gpointer callback;
+  GType itype;
+  guint offset;
+
+  if (closure->is_invalid)
+    return TRUE;
+
+  real_closure = G_REAL_CLOSURE (closure);
+
+  if (real_closure->meta_marshal == g_type_iface_meta_marshal)
+    {
+      itype = (GType) closure->data;
+      offset = GPOINTER_TO_UINT (real_closure->meta_marshal_data);
+
+      class = G_TYPE_INSTANCE_GET_INTERFACE (instance, itype, GTypeClass);
+      callback = G_STRUCT_MEMBER (gpointer, class, offset);
+      return callback == NULL;
+    }
+  else if (real_closure->meta_marshal == g_type_class_meta_marshal)
+    {
+      offset = GPOINTER_TO_UINT (real_closure->meta_marshal_data);
+
+      class = G_TYPE_INSTANCE_GET_CLASS (instance, itype, GTypeClass);
+      callback = G_STRUCT_MEMBER (gpointer, class, offset);
+      return callback == NULL;
+    }
+
+  return FALSE;
+}
+
 static void
 g_type_iface_meta_marshalv (GClosure *closure,
                            GValue   *return_value,
index 9cbea77..04a252b 100644 (file)
@@ -60,6 +60,8 @@ void            _g_type_boxed_init      (GType          type,
                                          GBoxedCopyFunc copy_func,
                                          GBoxedFreeFunc free_func);
 
+gboolean    _g_closure_is_void (GClosure       *closure,
+                               gpointer        instance);
 gboolean    _g_closure_supports_invoke_va (GClosure       *closure);
 void        _g_closure_set_va_marshal (GClosure       *closure,
                                       GVaClosureMarshal marshal);