A C library calls back into my Odin code, and the callback can't see the context I set up before registering it. A proc "c" gets no implicit context, so it has to build one, and runtime.default_context() gives the default allocators, not the arena the registering code had in context.allocator. Anything the callback allocates goes to the heap and is never part of the frame clear.
What I do now is pass the arena through the library's user_data pointer and put it back by hand.
import "base:runtime"
import "core:c"
import "core:mem"
on_event :: proc "c" (user: rawptr, code: c.int) {
context = runtime.default_context()
context.allocator = mem.arena_allocator((^mem.Arena)(user))
handle_event(int(code))
}
It works. The arena pointer has to outlive the registration, which nothing checks. And every callback repeats those two lines. Is there a tidier pattern, or is this just the price of crossing into C?