emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Lisp object that refers to a C struct


From: Eli Zaretskii
Subject: Re: Lisp object that refers to a C struct
Date: Tue, 16 Oct 2012 19:22:04 +0200

> From: Stefan Monnier <address@hidden>
> Cc: address@hidden
> Date: Tue, 16 Oct 2012 09:11:25 -0400
> 
> >> Otherwise, better define your own type so that its printed
> >> representation can be more helpful, indicating what it's used for
> > How do I define my own type?
> 
> Either by adding one more lisp_misc or one more pseudovector.
> For either of them, you need to add the corresponding new tag to their
> enumeration (Lisp_Misc_Type or pvec_type).  For lisp_misc you
> additionally need to add your entry to the union type (but make sure
> the first word has the same structure as the others, starting with
> a 16bit type and a 1bit markbit) and make sure the overall size of the
> union type is not increased.
> 
> Then you need to add the corresponding switch branches in print.c and in
> alloc.c.

Can I just use PVEC_OTHER instead?

In any case, which one, pseudovector or misc, is better suited for
this particular job, in your opinion?  What would you use?

> > In particular, what to do with gcmarkbit in Lisp_Misc?
> 
> The markbit represents whether or not the object you created was found
> by the tracing GC, so just set it like we do for the other types.
> 
> The other question is "when should we free the C struct to which this
> new lisp_misc points"?  And that depends.  You could have the GC free it
> when it finds your lisp_misc can be freed, or you could have instead
> a notion of "deleted file-watcher" (like we have for
> buffers/windows/...) which is when the underlying C struct has been
> freed (but of course, this state needs to be represented, e.g. by
> setting the pointer to NULL, which means that you need to be able to
> enumerate all the file-watcher objects (or the only one, if you enforce
> there can only be one) corresponding to a particular C struct).

This sounds dangerous in my case.  The struct holds crucial data used
by a separate thread which watches the changes and receives
notifications.  It is unthinkable to let any code outside of the one
specifically written for this to free that struct, because the
associated thread will go down in flames and take Emacs with it.
There's special code (already written and tested) that takes care of
shutting down the watcher thread and freeing the associated resources
in an orderly way.  That code must be run whenever the object is
GC'ed, at the very least.  It would be even better not to leave this
to GC at all, but instead delete the object whenever the watch is
canceled, since otherwise we leave behind a thread that does nothing
except wasting system resources, for a time interval whose length
cannot be predicted or controlled.

Is there a clean way of doing that?

P.S.  I must say that the more I learn about the "make your own
object" path the less I like it.  In the case in point, it sounds like
pure overhead, with no benefits at all.  To do everything I need with
the watcher struct, all I need is a pointer to it, which can easily be
disguised as a Lisp integer.  (This is how the code actually works
now.)  Such a "handle" will be barely visible to Lisp, its only use is
to cancel an existing watch, or examine its associated file name and
the details of the watch request (which _are_ Lisp objects).  There's
no need to manage the struct itself, as it already manages itself.
But look what I need to do just to produce a first-class Lisp object
from it.  And I still don't see what would be the benefits.  E.g., a
Lisp integer prints quite nicely; something like "#<watch 12345678>"
doesn't seem significantly prettier.  What am I missing?



reply via email to

[Prev in Thread] Current Thread [Next in Thread]