[Top][All Lists]
[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
- [PATCH] Doc: protecting procedure->pointer pointers from GC,
Neil Jerram <=