guile-devel
[Top][All Lists]
Advanced

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

[PATCH] Doc: protecting procedure->pointer pointers from GC


From: Neil Jerram
Subject: [PATCH] Doc: protecting procedure->pointer pointers from GC
Date: Mon, 30 Jan 2012 21:32:52 +0000
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux)

Following debugging of a strange issue where oFono appeared to be
sending a D-Bus signal from the wrong object, but I eventually realised
that the problem was in my own code...

        Neil

>From 02d80ad14c3bb8f89d7ba807dac658be6dd06df1 Mon Sep 17 00:00:00 2001
From: Neil Jerram <address@hidden>
Date: Mon, 30 Jan 2012 21:12:37 +0000
Subject: [PATCH] Doc: protecting procedure->pointer pointers from GC

* doc/ref/api-foreign.texi (Dynamic FFI): New text covering when pointers
  need to be retained.
---
 doc/ref/api-foreign.texi |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/doc/ref/api-foreign.texi b/doc/ref/api-foreign.texi
index 6ece7f8..19d6b29 100644
--- a/doc/ref/api-foreign.texi
+++ b/doc/ref/api-foreign.texi
@@ -961,6 +961,39 @@ function can be made accessible to Scheme (@pxref{Array 
Sort Function,
 
 And address@hidden
 
+If you use @code{procedure->pointer} to pass a Scheme procedure as a
+callback for a C library to invoke asynchronously later --- for example,
+as a handler for a D-Bus signal --- you must somehow keep a reference to
+the pointer that @code{procedure->pointer} returns, for as long as the C
+library might invoke the callback.  Otherwise the pointer can be
+prematurely garbage collected, leading to unsafe and arbitrary behaviour
+if the now-invalid callback is called.
+
+This example, which registers a Scheme procedure as a handler for a
+GObject signal, uses @code{make-object-property} to do that:
+
address@hidden
+(define gobject-signal-handlers (make-object-property))
+
+(define (gobject-connect object signal proc)
+  (let ((ptr (procedure->pointer void
+                                 (lambda (...C callback args...)
+                                   (proc ...Scheme args...))
+                                 (list ...C callback types...))))
+    ;; Protect the pointer from being prematurely collected.
+    (set! (gobject-signal-handlers object)
+          (acons signal
+                 ptr
+                 (or (gobject-signal-handlers object) '())))
+    ;; Register the handler.
+    (g_signal_connect_data object
+                           (string->pointer signal)
+                           ptr
+                           %null-pointer
+                           %null-pointer
+                           0)))
address@hidden example
+ 
 Note that @code{procedure->pointer} is not supported (and not defined)
 on a few exotic architectures.  Thus, user code may need to check
 @code{(defined? 'procedure->pointer)}.  Nevertheless, it is available on
-- 
1.7.8.3


reply via email to

[Prev in Thread] Current Thread [Next in Thread]