At Mon, 23 Nov 2020 00:14:56 -0600, Nate Griswold wrote:
> Hello. I have a few questions:
> 
> 1) Why do the docs say that racket_eval and racket_apply eval and apply in
> the “initial” or “original” racket thread? I have verified that the thread
> id returned from pthread_self when using racket_apply in c code called from
> a racket place is different from the thread id of the thread i called
> racket_boot on.

The `racket_apply` function was intended for use only in the OS thread
where Racket is booted, and only "outside" to get Racket started. It's
not intended for use in callbacks from Racket.

That's generally true for functions listed in sections 4-6 of "Inside",
and I see that the intent is not remotely clear there. I'll improve the
documentation.

To call back to Racket from C code, you should use the Racket FFI,
where a Racket function that's passed to C gets converted to a function
pointer for the C side. When you call that callback (as a regular C
function call), various bits of Scheme and Racket state get
configured/restored in a consistent way before jumping to the wrapped
Racket code as a callback.

For simple things, it turns out that `Scall0`, etc. would work to
invoke a callback within the Racket context that had called into C, but
there are many pitfalls, so you shouldn't do that.

You definitely should not use `racket_apply` or `racket_eval` from C
that was called from Racket. It will... well, do something. Take the
uncertainly of using `Scall0` and multiply by 100, since functions like
`racket_apply` specifically attempt to interact with the thread
scheduler.

> 2) I noticed that if i racket_eval in c code called by a racket place, i
> can’t evaluate things that would otherwise (in racket code) be available in
> the place’s namespace. What is the correct way to get at things in the
> place’s racket namespace from c code? Is my problem unique to using a
> place, or would i have this problem in a non-place scenario as well?

I think it's probably not just about places, but let me answer the
"correct way" question with the next bullet.

> 3) (related to 2) I want to be able to put and get from a place channel
> from a long-running c function. If i just pass a place channel to the
> function, that is wrong because if i am correct in my thinking (and in what
> i have witnessed) there is a chance that when i go to use that channel in
> the future, it will have been moved by the garbage collector. Is there any
> way to prevent a specific value from being garbage collected, at least for
> the lifetime of my place? This is related to (2) because i actually don’t
> need this functionality if i can just racket_eval to get at the place
> channel from the namespace of the place’s module in the middle of a
> Sactivate_thread / Sdeactivate_thread session.

The best approach here is to hand the C code a callback, which it will
see as plain old C functions. Maybe there's one callback to get from
the channel and another to put to the channel --- where the channel is
in the closure of the function, although the C side has no idea about
closures. If you go that route, then as long as you retain a reference
to the callback closure on the Racket side, the callback function
itself won't move.

Overall, reasoning about the interaction between Racket/Scheme and C
interaction from the C side is very difficult. The more you can arrange
for the C code to oblivious to Racket, the easier things get, because
the Racket-side tools for interacting with C are much better.

> 3) Is there any way to pass a c callback function into racket so that
> racket can call that function? I defined a ctype for the function, but i
> couldn’t think of a way to cast a pointer value passed into racket from c
> to an instance of my ctype (the `cast` function takes existing ctypes and
> not numeric values). Is there any way to manually make a value for my
> function ctype using an existing pointer value?

You can cast from a numeric value by casting from `_intptr` to a
pointer type. For example, this expression creates a function that
tries to jump to address 16 (and crashes, but in gdb you'd see it
crashing with the instruction pointer at address 16):

   (cast 16 _intptr (_fun -> _void))


Matthew

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/20201123060111.3b5%40sirmail.smtps.cs.utah.edu.

Reply via email to