invoke_signal_func calls Pike code (via apply_svalue). To run Pike code, you need to hold the interpreter lock. But that is not all. You also need to have a Pike stack and a frame pointer, which are thread local. These are kept in a structure called a "Pike_interpreter_struct", which in turn is part of something called a "thread_state". All threads created with thread_create() already has such a state, stored in a lookup table indexed on the thread id. However, a thread created by (say) C-code in an external library will not have such a state created for it.
call_with_interpreter is simply a convenience function used to be able to call Pike code from an unknown context:
* If the running thread already has an entry in the lookup table, then it just takes the interpreter lock, if it wasn't already taken, and calls the function. Then it unlocks the interpreter lock again if it was unlocked before.
* If the running thread does _not_ have an entry in the lookup table, then a new thread_state is created, and made the current interpreter (after taking the lock). The thread_state is also stored in the lookup table, in case the pike code calls the C library back, which then again makes a call into Pike and we reenter call_with_interpreter within the same context. After the Pike code has been executed, the thread_state is removed from the table and discarded.
Like in the case of something in glib adding a timeout for a signal, which calls back into pike, but that is a separate thread not called from pike directly... I see, thanks...
On Tuesday, May 29, 2018, 5:13:08 AM EDT, Marcus Comstedt (ACROSS) (Hail Ilpalazzo!) @ Pike (-) developers forum 10353@lyskom.lysator.liu.se wrote:
invoke_signal_func calls Pike code (via apply_svalue). To run Pike code, you need to hold the interpreter lock. But that is not all. You also need to have a Pike stack and a frame pointer, which are thread local. These are kept in a structure called a "Pike_interpreter_struct", which in turn is part of something called a "thread_state". All threads created with thread_create() already has such a state, stored in a lookup table indexed on the thread id. However, a thread created by (say) C-code in an external library will not have such a state created for it.
call_with_interpreter is simply a convenience function used to be able to call Pike code from an unknown context:
* If the running thread already has an entry in the lookup table, then it just takes the interpreter lock, if it wasn't already taken, and calls the function. Then it unlocks the interpreter lock again if it was unlocked before.
* If the running thread does _not_ have an entry in the lookup table, then a new thread_state is created, and made the current interpreter (after taking the lock). The thread_state is also stored in the lookup table, in case the pike code calls the C library back, which then again makes a call into Pike and we reenter call_with_interpreter within the same context. After the Pike code has been executed, the thread_state is removed from the table and discarded.
pike-devel@lists.lysator.liu.se