Marshalling NIF calls into BEAM's main thread

I want to build a desktop UI app in Elixir and so I need to call some C code. I’d prefer to use NIFs over other means for performance reasons (not that I’ve measured anything yet, but still…). The problem I’m facing is that desktop UI libraries require the clients to make API calls from the main thread. (AFAIK wxErlang uses ports, Membrane uses C Nodes).

Is there a way to marshall those NIF calls into BEAM’s main thread?

From my understanding, you cannot because any scheduler isn’t run from the main thread. The main thread is running erts_sys_main_thread function that just wait for the process to be closed. You can verify it by yourself with pstack or gdb/lldb.

The above behaviour is different for Darwin. When Erlang is compiled for this OS, the main thread supports “special calls” for wx drivers. If you need access to the main thread only on Darwin, then maybe you can use these “calls” in your code.

If I were you, I would consider available options again - spawning other process from Erlang and control it over I/O should resolve your issue (never tried so I can’t say anything about the performance).

2 Likes

Thanks for the reply, I learned a lot!

For the curious: wxErlang is implemented as a Linked-in Driver (“Port Driver”) - these seem to be predecessors of NIFs. The wx driver steals the main thread on Mac.

For simplicity I’ll start with a C Node or a port and switch if performance really becomes an issue.