From: Kenny Tilton
Subject: Lispworks and callbacks?
Date: 
Message-ID: <3E35E226.2060602@nyc.rr.com>
Is anyone using (or know of code which uses) Lispworks in a situation 
where you have to pass /to/ a C function a reference to a Lisp function 
(defined by define-foreign-callable) to be called by the C library at 
some later time?

ACL offers ff:register-foreign-callable, which returns several values, 
the first of which can be passed to a C function for later use as a 
callback.

LW's define-foreign-callable returns just the string name of the 
function defined. I doubted FUNCTION would work, and anyway d-f-c does 
not create anything FUNCTIOn could work off.

Unfortunately the LW example shows how it first defines XXX, a lisp 
function callable from C, but then they get cute and define this "XXX" c 
function to be called from Lisp, so when they call the C XXX they end up 
back in the Lisp XXX. Cute, but it leaves the question of how to 
identify the callback to a C library.

I am starting to think it is time to cut my losses and modify FreeGlut 
to support a get-next-event approach to message/event handling. A 
one-time effort, then UFFI is my savior.


-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore

From: Tim Bradshaw
Subject: Re: Lispworks and callbacks?
Date: 
Message-ID: <fbc0f5d1.0301280120.34c5e299@posting.google.com>
Kenny Tilton <·······@nyc.rr.com> wrote in message news:<················@nyc.rr.com>...
> Is anyone using (or know of code which uses) Lispworks in a situation 
> where you have to pass /to/ a C function a reference to a Lisp function 
> (defined by define-foreign-callable) to be called by the C library at 
> some later time?

Anything that uses the expat XML library will do this at some level. 
There are free expat bindings for LW and ACL, which I have somewhat
modified copies of
(mostly my modifications were better searching for the expat library,
and
stuff to make it work on Windows where encodings matter more).

I don't have a URL for the public versions (or my modified ones) here,
but I can send you them next week when I'm back home.  Mail me if
you're interested.

The expat stuff is somewhat obscure since it has a layer which
isolates the LW/ACL specific parts, but in general I think it's not
that hard.

--tim
From: Jeff Caldwell
Subject: Re: Lispworks and callbacks?
Date: 
Message-ID: <3E36135B.7010605@yahoo.com>
Sample code at:

http://www.jeffcaldwell.com/article.pl?sid=03/01/03/2342225&mode=thread

Follow the link back to the home page, there's a more recent article 
that details a little of the progress I've made since then.

Jeff

Kenny Tilton wrote:
> Is anyone using (or know of code which uses) Lispworks in a situation 
> where you have to pass /to/ a C function a reference to a Lisp function 
> (defined by define-foreign-callable) to be called by the C library at 
> some later time?
> 
> ACL offers ff:register-foreign-callable, which returns several values, 
> the first of which can be passed to a C function for later use as a 
> callback.
> 
> LW's define-foreign-callable returns just the string name of the 
> function defined. I doubted FUNCTION would work, and anyway d-f-c does 
> not create anything FUNCTIOn could work off.
> 
> Unfortunately the LW example shows how it first defines XXX, a lisp 
> function callable from C, but then they get cute and define this "XXX" c 
> function to be called from Lisp, so when they call the C XXX they end up 
> back in the Lisp XXX. Cute, but it leaves the question of how to 
> identify the callback to a C library.
> 
> I am starting to think it is time to cut my losses and modify FreeGlut 
> to support a get-next-event approach to message/event handling. A 
> one-time effort, then UFFI is my savior.
> 
> 
From: Kenny Tilton
Subject: Re: Lispworks and callbacks?
Date: 
Message-ID: <3E361FF0.2090206@nyc.rr.com>
Jeff Caldwell wrote:
> 
> Sample code at:
> 
> http://www.jeffcaldwell.com/article.pl?sid=03/01/03/2342225&mode=thread

ah, there it is, buried in the discussion of make-pointer, but pretty 
well laid out. How did you figure out you had to pass the 
pointer-address of the make-pointer result? It sounds as if make-pointer 
on the callback would give the necessary callback address, but obviously 
not based on your code. Go figger.

Thx much, I'll give it a try.



-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Jeff Caldwell
Subject: Re: Lispworks and callbacks?
Date: 
Message-ID: <3E3691C0.8050004@yahoo.com>
I had asked for help on ········@xanalys.com and Marc Battyani responded 
with a hint about the API. Dave Tarvydas responded with Lisp and C code 
to drive the message loop from a C DLL. The example in the link is 
Lisp/fli only, however.

I think you can set up the fli C structs to automatically coerce the 
pointers but that was yet another layer of fli-fighting which I avoided 
by typing the C pointers as unsigned longs and calling pointer-address 
manually. ymmv.

Jeff

Kenny Tilton wrote:
> ah, there it is, buried in the discussion of make-pointer, but pretty 
> well laid out. How did you figure out you had to pass the 
> pointer-address of the make-pointer result? It sounds as if make-pointer 
> on the callback would give the necessary callback address, but obviously 
> not based on your code. Go figger.
> 
> Thx much, I'll give it a try.
> 
> 
> 
From: Alain Picard
Subject: Re: Lispworks and callbacks?
Date: 
Message-ID: <87adhlzo7m.fsf@ibook.optushome.com.au>
Kenny Tilton <·······@nyc.rr.com> writes:

> ah, there it is, buried in the discussion of make-pointer, but pretty
> well laid out. How did you figure out you had to pass the
> pointer-address of the make-pointer result? It sounds as if
> make-pointer on the callback would give the necessary callback
> address, but obviously not based on your code. Go figger.

One more thing; this may be obvious (or it may not) --- you have
to make sure that C calls the lisp function under the control
of Lisp, i.e. not totally asynchronously, from a C thread (say).

If that didn't parse, let me know, and I'll answer at greater
length and clarity.
From: Edi Weitz
Subject: Re: Lispworks and callbacks?
Date: 
Message-ID: <87znplr1tm.fsf@bird.agharta.de>
Alain Picard <·······················@optushome.com.au> writes:

> One more thing; this may be obvious (or it may not) --- you have to
> make sure that C calls the lisp function under the control of Lisp,
> i.e. not totally asynchronously, from a C thread (say).
> 
> If that didn't parse, let me know, and I'll answer at greater length
> and clarity.

Uh, it didn't parse for me at least, so if you could find some time to
add more details I'd be glad.

Thanks in advance,
Edi.
From: Kenny Tilton
Subject: Re: Lispworks and callbacks?
Date: 
Message-ID: <3E368AE1.4000304@nyc.rr.com>
Edi Weitz wrote:
> Alain Picard <·······················@optushome.com.au> writes:
> 
> 
>>One more thing; this may be obvious (or it may not) --- you have to
>>make sure that C calls the lisp function under the control of Lisp,
>>i.e. not totally asynchronously, from a C thread (say).
>>
>>If that didn't parse, let me know, and I'll answer at greater length
>>and clarity.
> 
> 
> Uh, it didn't parse for me at least, so if you could find some time to
> add more details I'd be glad.

My wild stab at it is that I am OK, because I (in Lisp) call C functions 
in the Glut DLL, which then calls back the functions pointers to which I 
earlier passed to Glut.

I gather also that I could still be in trouble if Glut kicked off a 
thread from which callbacks would be made, but I have not noticed 
anything like that in mucho perusal of Glut source.

fwiw.

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Gabe Garza
Subject: Re: Lispworks and callbacks?
Date: 
Message-ID: <87u1ft705l.fsf@ix.netcom.com>
Kenny Tilton <·······@nyc.rr.com> writes:

>
> I gather also that I could still be in trouble if Glut kicked off a
> thread from which callbacks would be made, but I have not noticed
> anything like that in mucho perusal of Glut source.
> 

Hopefully someone more LispWorks savy will jump in if I'm wrong, but
from what I gather LispWorks isn't multiprocessing-safe at all, so it
doesn't necessarily have to be from a different thread.  Any time you
have more then one chunk of Lisp code executing "at the same time" it
could be unsafe.  For example, if you installed a callback for a
button and maintained the Lisp event loop outside of Glut you could be
in dangerous territory.

Gabe Garza
From: Nils Goesche
Subject: Re: Lispworks and callbacks?
Date: 
Message-ID: <ly1y2xi8dy.fsf@cartan.de>
Gabe Garza <·······@ix.netcom.com> writes:

> Kenny Tilton <·······@nyc.rr.com> writes:
> 
> > I gather also that I could still be in trouble if Glut kicked off
> > a thread from which callbacks would be made, but I have not
> > noticed anything like that in mucho perusal of Glut source.
> 
> Hopefully someone more LispWorks savy will jump in if I'm wrong, but
> from what I gather LispWorks isn't multiprocessing-safe at all, so
> it doesn't necessarily have to be from a different thread.  Any time
> you have more then one chunk of Lisp code executing "at the same
> time" it could be unsafe.  For example, if you installed a callback
> for a button and maintained the Lisp event loop outside of Glut you
> could be in dangerous territory.

The question is in which context those installed callbacks are called.
If the only way they are called is that a LispWorks light-weight
thread calls GLUT, and then GLUT, in this same context, calls his
callbacks, everything should be fine, as there is only one Unix thread
operating on the code.

Regards,
-- 
Nils G�sche
"Don't ask for whom the <CTRL-G> tolls."

PGP key ID 0x0655CFA0
From: Alain Picard
Subject: Re: Lispworks and callbacks?
Date: 
Message-ID: <87y954w7n8.fsf@ibook.optushome.com.au>
Nils Goesche <······@cartan.de> writes:

> Gabe Garza <·······@ix.netcom.com> writes:
>
> The question is in which context those installed callbacks are called.
> If the only way they are called is that a LispWorks light-weight
> thread calls GLUT, and then GLUT, in this same context, calls his
> callbacks, everything should be fine, as there is only one Unix thread
> operating on the code.

I don't know what a "LispWorks light-weight thread" is, but if you're
referring ot a LW "process", then, yes, your analysis is correct, as
far as I understand LW.

I once na�vely tried to get a C thread to asynchronously call LW callbacks,
with random consequences; Xanalys support told me I had to let LW drive
the polling loop to call C to call lisp back "on its own thread".

Hope that helps.
From: Kenny Tilton
Subject: Re: Lispworks and callbacks?
Date: 
Message-ID: <3E36B8CD.4010108@nyc.rr.com>
Gabe Garza wrote:
> Kenny Tilton <·······@nyc.rr.com> writes:
> 
> 
>>I gather also that I could still be in trouble if Glut kicked off a
>>thread from which callbacks would be made, but I have not noticed
>>anything like that in mucho perusal of Glut source.
>>
> 
> 
> Hopefully someone more LispWorks savy will jump in if I'm wrong, but
> from what I gather LispWorks isn't multiprocessing-safe at all, so it
> doesn't necessarily have to be from a different thread.  Any time you
> have more then one chunk of Lisp code executing "at the same time" it
> could be unsafe.  For example, if you installed a callback for a
> button and maintained the Lisp event loop outside of Glut you could be
> in dangerous territory.

Good point. I get much diff behavior when I insert a sleep in the 
otherwise tight loop calling glut to handle the next event. I guess then 
that if I do anything in a callback such as break, look out.

We'll see, but thx for the input, I'll keep this in mind if LW does not 
like my shenanigans.

-- 

  kenny tilton
  clinisys, inc
  http://www.tilton-technology.com/
  ---------------------------------------------------------------
"Cells let us walk, talk, think, make love and realize
  the bath water is cold." -- Lorraine Lee Cudmore
From: Kenny Tilton
Subject: Re: Lispworks and callbacks?
Date: 
Message-ID: <f06747e2.0302040814.1e829b9a@posting.google.com>
Jeff Caldwell <·····@yahoo.com> wrote in message news:<················@yahoo.com>...
> Sample code at:
> 
> http://www.jeffcaldwell.com/article.pl?sid=03/01/03/2342225&mode=thread
> 
> Follow the link back to the home page, there's a more recent article 
> that details a little of the progress I've made since then.

In the credit-where-due department, thought I'd swing by this old
thread to say thanks, that did the trick. Here is what I have now on
callbacks:

(defun ff-register-callable (callback-name)
  #+allegro
  (ff:register-foreign-callable callback-name)
  #+lispworks
  (fli:pointer-address
    (fli:make-pointer :symbol-name (symbol-name callback-name)
      :functionp t)))

[the above needs a new name, it just got swept over from the ACL
nomenclature]

(defmacro ff-defun-callable (result-type name args &body body)
  (declare (ignorable result-type))
#+lispworks
  `(fli:define-foreign-callable (,(symbol-name name) :result-type
,result-type)
     (,@args)
     ,@body)
#+allegro
  `(ff:defun-foreign-callable ,name ,args
     ,@body))

BTW, at one point I asked "why call pointer-address?", but when i
slowed down I saw that make-pointer output does indeed need to be
un-boxed to get at the callable address. my bad.

kenny
clinisys