Functions Used for REPY's Interpreter Stack, which handles interpreter/subinterpreter operations as well as PyThreadState management. More...
Functions | |
| void | REPY_PushInterpreter (REPY_InterpreterIndex interpreter_handle) |
| Pushes an interpreter index to the interpreter stack, and switching the active interpreter if necessary. | |
| void | REPY_PopInterpreter () |
| Pops an interpreter index from the interpreter stack, switching active interpreters if necessary. | |
| REPY_InterpreterIndex | REPY_GetCurrentInterpreter () |
| Gets the interpreter index at the top of the interpreter stack. | |
| REPY_bool | REPY_GetInterpreterAutoDisarm (REPY_InterpreterIndex index) |
| Gets whether or not this subinterpreter should be 'disarmed' when shutting down. | |
| void | REPY_SetInterpreterAutoDisarm (REPY_InterpreterIndex index, REPY_bool value) |
| Sets whether or not this subinterpreter should be 'disarmed' when shutting down. | |
| REPY_InterpreterIndex | REPY_GetHandleInterpreter (REPY_Handle handle_no_release) |
| Gets the index of the interpreter a specific REPY_Handle object is associated with. | |
Functions Used for REPY's Interpreter Stack, which handles interpreter/subinterpreter operations as well as PyThreadState management.
REPY used a free-threaded build of Python, with the traditional Python GIL is a non-factor. However, the CPython still needs to know whether or not a given thread needs access to the interpreter (and when subinterpreters are in use, which interpreter) using an opaque struct in CPython called PyThreadState.
Because the mod developer has no control over what other mods a player may install, and whether these mods use REPY, no single mod can be given responsibility for managing the PyThreadState directly. Therefore, REPY implements something called the Interpreter Stack: If a given mod code thread requires access to the main interpreter, a call to REPY_PushInterpreter tells REPY a mod needs access to a specific interpreter, and a call to REPY_PopInterpreter tells REPY that the previously requested access is no longer needed. Using this, REPY itself manages the PyThreadState of a given N64Recompiled thread, making changes to the state only necessary.
For this reason, it is recommended to call REPY_PushInterpreter at the top of any function that needs Python interpreter access, and to call REPY_PopInterpreter before that function returns. The exception is when REPY_FN macros, as the setup and cleanup macros will automatically do this for you.
waitr* See Interpreter Stack Management for potential performance pitfalls related to Interpreter Stack management.
See Subinterpreters for more information on what they are, and REPY's usage of them.
| REPY_InterpreterIndex REPY_GetCurrentInterpreter | ( | ) |
Gets the interpreter index at the top of the interpreter stack.
Returns REPY_INTERPRETER_STACK_EMPTY when the interpreter stack is empty. See Subinterpreters for more information.
| REPY_InterpreterIndex REPY_GetHandleInterpreter | ( | REPY_Handle | handle_no_release | ) |
Gets the index of the interpreter a specific REPY_Handle object is associated with.
This function will not release Single-Use handles.
| handle_no_release | a REPY_Handle for get the interpreter for. |
| REPY_bool REPY_GetInterpreterAutoDisarm | ( | REPY_InterpreterIndex | index | ) |
Gets whether or not this subinterpreter should be 'disarmed' when shutting down.
This is a workaround for N64Recompiled titles freezing on exit when a subinterpreter has additional threads running. When auto-disarm is set to true, REPY will simply let the subinterpreter leak and be cleaned up by the OS. It's hardly a clean exit, but it's the best solution we have until a proper on_shutdown event is implemented in the N64Recompiled runtime.
| index | The subinterpreter to set this value for. Does nothing for the main interpreter. |
| void REPY_PopInterpreter | ( | ) |
Pops an interpreter index from the interpreter stack, switching active interpreters if necessary.
See Subinterpreters for more information.
| void REPY_PushInterpreter | ( | REPY_InterpreterIndex | interpreter_handle | ) |
Pushes an interpreter index to the interpreter stack, and switching the active interpreter if necessary.
See Subinterpreters for more information.
| interpreter_handle | The index to push to the subinterpreter stack. |
| void REPY_SetInterpreterAutoDisarm | ( | REPY_InterpreterIndex | index, |
| REPY_bool | value ) |
Sets whether or not this subinterpreter should be 'disarmed' when shutting down.
This is a workaround for N64Recompiled titles freezing on exit when a subinterpreter has additional threads running. When auto-disarm is set to true, REPY will simply let the subinterpreter leak and be cleaned up by the OS. It's hardly a clean exit, but it's the best solution we have until a proper on_shutdown event is implemented in the N64Recompiled runtime.
| index | The subinterpreter to set this value for. Does nothing for the main interpreter. |
| value | The new value for auto-disarm. |