From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Neil Jerram Newsgroups: gmane.lisp.guile.devel Subject: [PATCH] Doc: protecting procedure->pointer pointers from GC Date: Mon, 30 Jan 2012 21:32:52 +0000 Message-ID: <87sjiwq3jv.fsf@neil-laptop.ossau.uklinux.net> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: dough.gmane.org 1327959188 9953 80.91.229.3 (30 Jan 2012 21:33:08 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Mon, 30 Jan 2012 21:33:08 +0000 (UTC) To: guile-devel@gnu.org Original-X-From: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Mon Jan 30 22:33:06 2012 Return-path: Envelope-to: guile-devel@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1RryqW-0000vN-SC for guile-devel@m.gmane.org; Mon, 30 Jan 2012 22:33:05 +0100 Original-Received: from localhost ([::1]:53480 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RryqV-0000iX-Jx for guile-devel@m.gmane.org; Mon, 30 Jan 2012 16:33:03 -0500 Original-Received: from eggs.gnu.org ([140.186.70.92]:41209) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RryqP-0000hn-Df for guile-devel@gnu.org; Mon, 30 Jan 2012 16:33:01 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RryqN-0002tz-C1 for guile-devel@gnu.org; Mon, 30 Jan 2012 16:32:57 -0500 Original-Received: from out1.ip07ir2.opaltelecom.net ([62.24.128.243]:27161) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RryqN-0002se-2C for guile-devel@gnu.org; Mon, 30 Jan 2012 16:32:55 -0500 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ak0JAP8LJ09OlcIu/2dsb2JhbABDrVCBBoEGgXIBLS87FAMBAgo0AQQlFiGHf5h2n2SLKgYBCgICAwYCBAIBBAICT4JjBRVpCAEEBDuDHASnaw X-IronPort-AV: E=Sophos;i="4.71,592,1320624000"; d="scan'208,223";a="22700618" Original-Received: from host-78-149-194-46.as13285.net (HELO arudy) ([78.149.194.46]) by out1.ip07ir2.opaltelecom.net with ESMTP; 30 Jan 2012 21:32:53 +0000 Original-Received: from neil-laptop.ossau.uklinux.net.ossau.homelinux.net (host-78-149-194-46.as13285.net [78.149.194.46]) by arudy (Postfix) with ESMTPA id CF0D938005 for ; Mon, 30 Jan 2012 21:32:52 +0000 (GMT) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 62.24.128.243 X-BeenThere: guile-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Developers list for Guile, the GNU extensibility library" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Original-Sender: guile-devel-bounces+guile-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.devel:13751 Archived-At: --=-=-= 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 --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0001-Doc-protecting-procedure-pointer-pointers-from-GC.patch >From 02d80ad14c3bb8f89d7ba807dac658be6dd06df1 Mon Sep 17 00:00:00 2001 From: Neil Jerram 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 --=-=-=--