unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* [PATCH] Doc: protecting procedure->pointer pointers from GC
@ 2012-01-30 21:32 Neil Jerram
  2012-01-31  9:44 ` Andy Wingo
  0 siblings, 1 reply; 5+ messages in thread
From: Neil Jerram @ 2012-01-30 21:32 UTC (permalink / raw)
  To: guile-devel

[-- Attachment #1: Type: text/plain, Size: 192 bytes --]

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


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Doc-protecting-procedure-pointer-pointers-from-GC.patch --]
[-- Type: text/x-diff, Size: 2392 bytes --]

From 02d80ad14c3bb8f89d7ba807dac658be6dd06df1 Mon Sep 17 00:00:00 2001
From: Neil Jerram <neil@ossau.homelinux.net>
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 voil@`a!
 
+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:
+
+@example
+(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)))
+@end 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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-02-03  8:56 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-30 21:32 [PATCH] Doc: protecting procedure->pointer pointers from GC Neil Jerram
2012-01-31  9:44 ` Andy Wingo
2012-01-31 23:06   ` Neil Jerram
2012-02-02 21:21     ` Ludovic Courtès
2012-02-03  8:56       ` Neil Jerram

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).