Subject: [clisp-list] RE: Clisp FFI

From: Kick Damien-DKICK1 <[email-masked]>
Date: Tue Nov 5 19:20:05 2002

Thank you, Kaz, for your reply, all of which was very helpful.  There
were a few things in your reply, however, that raised a few new
quetions for me.  No good deed goes unpunished, yes? <smile>

Kaz Kylheku [[email-masked]] wrote:
> On Mon, 4 Nov 2002, Kick Damien-DKICK1 wrote:
> >     TO_LOAD=''
>
> TO_LOAD should be filled in:
> 
>     TO_LOAD='call-foof'
> 
> This will load call-foof.fas (or .lisp if it happens to not be
> compiled).  It's necessary, because you need that .fas in the
> lispinit.mem of the generated linking set, just as much as you need
> your .o files to go into lisp.run.  Without loading the Lisp part of
> it, you don't have the Lisp side of the glue.

Interesting.  My little example seemed to work just fine without it.

    [kick@login0 ~/tmp]% ./base+f00f/lisp.run \
    > -M base+f00f/lispinit.mem -i call-f00f -q
    ;; Loading file /home/kick/tmp/call-f00f.fas ...
    ;; Loaded file /home/kick/tmp/call-f00f.fas
    [1]> (call-f00f::call-f)
    p->i => 5

    [2]> 
    [kick@login0 ~/tmp]% 

Have I wandered into some kind of undefined behavior that fooled me
with the output I was expecting?  Either way, I will be certain to
modify the 'TO_LOAD' in the future.

> > Are there any gotchas one might think would be lurking for me if I
> > try to do this?
> 
> The gotchas are that you have to replicate any struct definitions
> and whatnot using the CLISP FFI language.  [...]

<nod> True.

Here is an example of the kind of potential gotcha about which I was
wondering.  Consider if, for example, the C code I will be calling
from my CLISP process were to 'fork(2)' a child process, as will most
likely be the case with the Expect library.  When one of these child
processes exits and the parent receives SIGCHILD, are any blocking
system calling executing from within CLISP not going to have their
return codes checked for EINTR correctly (though I realize that the
default disposition for SIGCHILD is to be ignored and, thusly, if I'm
remembering correclty, would not interrupt a blocking system call (at
least on Solaris)) as CLISP is not expecting to be 'fork(2)'ed?  I
would imagine that any external module code that was attempting to use
Pthreads would create problems as CLISP currently does not support
threading in a stable release.  I'm just fishing here but I hope this
gives a few examples of the kinds of gotchas about which I'm asking.

--
Damien Kick

---

From: Kaz Kylheku <[email-masked]>
Date: Wed Nov 6 08:21:06 2002

>     ;; Loaded file /home/kick/tmp/call-f00f.fas

Yeah, but you typed ``-i call-f00f'' by yourself! The idea is that
call-f00f should be in the base+f00f/lispinit.mem, because it contains
the Lisp stubs for calling the extra C code you put into
base+f00f/lisp.run. You should just be able to run your customized
Lisp and have everything already be there.

> return codes checked for EINTR correctly (though I realize that the

Not checking for EINTR would just be buggy programming; if you ever
find a problem like that, CLISP will just have to be patched.

> least on Solaris)) as CLISP is not expecting to be 'fork(2)'ed?  I

CLISP most certainly does expect to be forked. A number of features in
the EXT package rely on fork. CLISP supports the launching of a
coprocess connected to a lisp stream, and the running of external
commands. The COMMON-LISP-USER:EDIT function is another one that runs
an external editor.

> threading in a stable release.

My guess would be that if you don't try to reenter any Lisp code with
your extra threads, you will probably be okay. But that kind of
restriction defeats someo of the purpose. I'd also make sure that
all components that go into the Lisp executable are properly built with
gcc -pthread and all that.