[perl-Glib-Object-Introspection] Generalize the free-after-call mechanism



commit 33b9471a32f86cece098446b32e51f5c6f94586e
Author: Torsten SchÃnfeld <kaffeetisch gmx de>
Date:   Sat Jul 7 17:32:12 2012 +0200

    Generalize the free-after-call mechanism

 GObjectIntrospection.xs       |    3 +++
 gperl-i11n-invoke-c.c         |   36 +++++++++++++++++++++++++++++++++---
 gperl-i11n-invoke-info.c      |    2 --
 gperl-i11n-marshal-callback.c |    5 ++---
 4 files changed, 38 insertions(+), 8 deletions(-)
---
diff --git a/GObjectIntrospection.xs b/GObjectIntrospection.xs
index 56f4f49..158d988 100644
--- a/GObjectIntrospection.xs
+++ b/GObjectIntrospection.xs
@@ -164,6 +164,9 @@ static gpointer allocate_out_mem (GITypeInfo *arg_type);
 static void handle_automatic_arg (guint pos,
                                   GIArgument * arg,
                                   GPerlI11nInvocationInfo * invocation_info);
+static void free_after_call (GPerlI11nInvocationInfo *iinfo,
+                             GFunc func, gpointer data);
+static void invoke_free_after_call_handlers (GPerlI11nInvocationInfo *iinfo);
 
 /* invocation info */
 static void prepare_c_invocation_info (GPerlI11nInvocationInfo *iinfo,
diff --git a/gperl-i11n-invoke-c.c b/gperl-i11n-invoke-c.c
index 179f42e..1a94227 100644
--- a/gperl-i11n-invoke-c.c
+++ b/gperl-i11n-invoke-c.c
@@ -211,9 +211,8 @@ invoke_c_code (GICallableInfo *info,
 
 	ffi_call (&cif, func_pointer, &return_value, iinfo.args);
 
-	/* free call-scoped callback infos */
-	g_slist_foreach (iinfo.free_after_call,
-	                 (GFunc) release_perl_callback, NULL);
+	/* free call-scoped data */
+	invoke_free_after_call_handlers (&iinfo);
 
 	if (local_error) {
 		gperl_croak_gerror (NULL, local_error);
@@ -368,3 +367,34 @@ allocate_out_mem (GITypeInfo *arg_type)
 		return NULL;
 	}
 }
+
+typedef struct {
+	GFunc func;
+	gpointer data;
+} FreeClosure;
+
+static void
+free_after_call (GPerlI11nInvocationInfo *iinfo, GFunc func, gpointer data)
+{
+	FreeClosure *closure = g_new (FreeClosure, 1);
+	closure->func = func;
+	closure->data = data;
+	iinfo->free_after_call
+		= g_slist_prepend (iinfo->free_after_call, closure);
+}
+
+static void
+invoke_free_closure (FreeClosure *closure)
+{
+	closure->func (closure->data, NULL);
+	g_free (closure);
+}
+
+static void
+invoke_free_after_call_handlers (GPerlI11nInvocationInfo *iinfo)
+{
+	g_slist_foreach (iinfo->free_after_call,
+	                 (GFunc) invoke_free_closure, NULL);
+	g_slist_free (iinfo->free_after_call);
+	iinfo->free_after_call = NULL;
+}
diff --git a/gperl-i11n-invoke-info.c b/gperl-i11n-invoke-info.c
index 968251a..06b97b8 100644
--- a/gperl-i11n-invoke-info.c
+++ b/gperl-i11n-invoke-info.c
@@ -266,8 +266,6 @@ prepare_perl_invocation_info (GPerlI11nInvocationInfo *iinfo,
 static void
 clear_perl_invocation_info (GPerlI11nInvocationInfo *iinfo)
 {
-	g_slist_free (iinfo->free_after_call);
-
 	/* The actual callback infos might be needed later, so we cannot free
 	 * them here. */
 	g_slist_free (iinfo->callback_infos);
diff --git a/gperl-i11n-marshal-callback.c b/gperl-i11n-marshal-callback.c
index 3620f33..5e758a4 100644
--- a/gperl-i11n-marshal-callback.c
+++ b/gperl-i11n-marshal-callback.c
@@ -32,9 +32,8 @@ sv_to_callback (GIArgInfo * arg_info,
 	switch (scope) {
 	    case GI_SCOPE_TYPE_CALL:
 		dwarn ("      Perl callback has scope 'call'\n");
-		invocation_info->free_after_call
-			= g_slist_prepend (invocation_info->free_after_call,
-			                   callback_info);
+		free_after_call (invocation_info,
+		                 (GFunc) release_perl_callback, callback_info);
 		break;
 	    case GI_SCOPE_TYPE_NOTIFIED:
 		dwarn ("      Perl callback has scope 'notified'\n");



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