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.