From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Davis Herring Newsgroups: gmane.emacs.devel Subject: Re: Lisp object that refers to a C struct Date: Wed, 17 Oct 2012 10:59:06 -0600 Organization: XCP-1 Message-ID: <507EE3DA.8030302@lanl.gov> References: <83ehkz4edw.fsf@gnu.org> <83bog33wdr.fsf@gnu.org> <837gqq49j7.fsf@gnu.org> <83k3up2iem.fsf@gnu.org> NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit X-Trace: ger.gmane.org 1350493232 15608 80.91.229.3 (17 Oct 2012 17:00:32 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 17 Oct 2012 17:00:32 +0000 (UTC) Cc: Stefan Monnier , emacs-devel@gnu.org To: Eli Zaretskii Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Oct 17 19:00:39 2012 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1TOWyy-00031c-6X for ged-emacs-devel@m.gmane.org; Wed, 17 Oct 2012 19:00:36 +0200 Original-Received: from localhost ([::1]:55591 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TOWyn-0001Ib-VY for ged-emacs-devel@m.gmane.org; Wed, 17 Oct 2012 13:00:25 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:38200) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TOWyf-0001I7-FI for emacs-devel@gnu.org; Wed, 17 Oct 2012 13:00:23 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TOWyY-0006E6-EY for emacs-devel@gnu.org; Wed, 17 Oct 2012 13:00:16 -0400 Original-Received: from proofpoint5.lanl.gov ([204.121.3.53]:53595) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TOWyY-0005tX-53; Wed, 17 Oct 2012 13:00:10 -0400 Original-Received: from mailrelay1.lanl.gov (mailrelay1.lanl.gov [128.165.4.101]) by proofpoint5.lanl.gov (8.14.4/8.14.4) with ESMTP id q9HGx6hO012059; Wed, 17 Oct 2012 10:59:06 -0600 Original-Received: from localhost (localhost.localdomain [127.0.0.1]) by mailrelay1.lanl.gov (Postfix) with ESMTP id DB2C8E82515; Wed, 17 Oct 2012 10:59:06 -0600 (MDT) X-NIE-2-Virus-Scanner: amavisd-new at mailrelay1.lanl.gov Original-Received: from [128.165.123.145] (xray-r10.lanl.gov [128.165.123.145]) by mailrelay1.lanl.gov (Postfix) with ESMTP id C4DE3E824E9; Wed, 17 Oct 2012 10:59:06 -0600 (MDT) User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.18) Gecko/20110717 Lanikai/3.1.11 In-Reply-To: <83k3up2iem.fsf@gnu.org> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:5.7.7855, 1.0.431, 0.0.0000 definitions=2012-10-17_05:2012-10-17, 2012-10-17, 1970-01-01 signatures=0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6, seldom 2.4 (older, 4) X-Received-From: 204.121.3.53 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:154385 Archived-At: > 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.