all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Davis Herring <herring@lanl.gov>
To: Eli Zaretskii <eliz@gnu.org>
Cc: Stefan Monnier <monnier@iro.umontreal.ca>, emacs-devel@gnu.org
Subject: Re: Lisp object that refers to a C struct
Date: Wed, 17 Oct 2012 10:59:06 -0600	[thread overview]
Message-ID: <507EE3DA.8030302@lanl.gov> (raw)
In-Reply-To: <83k3up2iem.fsf@gnu.org>

> Then the code that GC's this new Lisp object will have to be entirely
> specific to the layout of the struct I'm using, right?  It won't be
> suitable even for the similar-but-different inotify code, right?  If
> so, it's too bad: I hoped I could come up with some Lisp object that
> could be a wrapper for an arbitrary C struct, so that any similar
> feature that will need to pass opaque objects to Lisp could do that,
> instead of adding yet another object type.
> 
> If it's possible to do this in some generic way, could you please
> explain how?

Python addresses this with the CObject API.  (It is being supplanted by
a newer Capsule API, but it's nice and simple as a comparison point.)
http://docs.python.org/c-api/cobject.html

Basically, you make your single new Lisp type contain a pair of
pointers: the first points to your struct, and the other points to a
function that frees the struct and does whatever other cleanup.  This
latter can also be used as a type tag (so that you can't accidentally
use this to cast a eli_file_watcher_struct* to a
stefan_smie_cache_struct* and turn a Lisp bug into a crash in C),
although that might involve creating several wrappers for free() in the
trivial case.  (The CObjects use a third pointer that can be used to
disambiguate; either way works.)

The advantage of this approach is that the pointer marshaling code (and
the object-printing code and so forth) need only be written once, and
only one true Lisp type is used.  The disadvantage is of course that two
layers of type checking must be performed: the usual CONSP variety, and
then you check the function pointer (or other tag) once you know that
it's a struct-wrapper of some sort.

>> If you make sure there's at most 1 file-watcher object per C struct,
>> then you can easily zero-out its pointer-field after freeing the
>> C struct, so you can make sure you protect yourself from
>> dangling pointers.  And if you make sure the GC calls you back when
>> freeing the file-watcher, then you can make sure that you don't leak the
>> C structs.
> 
> You mean, have the free_my_object function (to be called by GC) call
> my own code?  Or is there a more generic way?

Yet another approach is to make sure that your code keeps a reference to
the struct-wrapper Lisp object and frees that reference only when it
destroys the underlying thread.  Then if the thread is alive, the struct
is; you can have a field in the struct (again like the killed buffer)
that means "this has no thread, so you can't use it from Lisp anymore".
 Then when the Lisp client gives up and drops their reference, the
struct is freed.

(Of course, you could do it the other way around: have GC destroy the
thread when the last reference to the struct-wrapper dies.  Then client
Lisp merely drops their references to the wrapper when they're done,
although there is some nondeterminism about when GC will happen.)

Davis

-- 
This product is sold by volume, not by mass.  If it appears too dense or
too sparse, it is because mass-energy conversion has occurred during
shipping.



  reply	other threads:[~2012-10-17 16:59 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-10-15 21:24 Lisp object that refers to a C struct Eli Zaretskii
2012-10-16  1:07 ` Stefan Monnier
2012-10-16  3:53   ` Eli Zaretskii
2012-10-16 13:11     ` Stefan Monnier
2012-10-16 17:22       ` Eli Zaretskii
2012-10-16 21:43         ` Stefan Monnier
2012-10-17  4:05           ` Eli Zaretskii
2012-10-17  6:21             ` Stephen J. Turnbull
2012-10-17 15:50               ` Eli Zaretskii
2012-10-17 17:45                 ` Stephen J. Turnbull
2012-10-17 13:34             ` Stefan Monnier
2012-10-17 16:08               ` Eli Zaretskii
2012-10-17 20:23                 ` Stefan Monnier
2012-10-17 20:46                   ` Eli Zaretskii
2012-10-17 22:08                     ` Paul Eggert
2012-10-18  0:22                       ` Stefan Monnier
2012-10-18  3:43                         ` Stephen J. Turnbull
2012-10-18  4:50                       ` Eli Zaretskii
2012-10-18  7:20                         ` Paul Eggert
2012-10-18 11:09                           ` Eli Zaretskii
2012-10-18 16:42                             ` Paul Eggert
2012-10-18 17:21                               ` Eli Zaretskii
2012-10-18  8:52                         ` Juanma Barranquero
2012-10-18 11:17                           ` Eli Zaretskii
2012-10-18 12:33                             ` Stefan Monnier
2012-10-18 17:16                               ` Eli Zaretskii
2012-10-18 22:09                                 ` Stefan Monnier
2012-10-19  7:14                                   ` Eli Zaretskii
2012-10-19 14:44                                     ` Stefan Monnier
2012-10-19 18:54                                       ` Eli Zaretskii
2012-10-19 21:35                                         ` Stefan Monnier
2012-10-19 22:35                                           ` Eli Zaretskii
2012-10-20  1:52                                             ` Stefan Monnier
2012-10-20  8:34                                               ` Eli Zaretskii
2012-10-17 16:05           ` Eli Zaretskii
2012-10-17 16:59             ` Davis Herring [this message]
2012-10-17 20:27             ` Stefan Monnier
2012-10-17 21:02               ` Eli Zaretskii
2012-10-18  0:23                 ` Stefan Monnier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=507EE3DA.8030302@lanl.gov \
    --to=herring@lanl.gov \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.