#ifndef Py_INTERNAL_ATEXIT_H #define Py_INTERNAL_ATEXIT_H #include "pycore_lock.h" // PyMutex #ifdef __cplusplus extern "C" { #endif #ifndef Py_BUILD_CORE # error "this header requires Py_BUILD_CORE define" #endif //############### // runtime atexit typedef void (*atexit_callbackfunc)(void); struct _atexit_runtime_state { PyMutex mutex; #define NEXITFUNCS 32 atexit_callbackfunc callbacks[NEXITFUNCS]; int ncallbacks; }; //################### // interpreter atexit typedef void (*atexit_datacallbackfunc)(void *); typedef struct atexit_callback { atexit_datacallbackfunc func; void *data; struct atexit_callback *next; } atexit_callback; struct atexit_state { #ifdef Py_GIL_DISABLED PyMutex ll_callbacks_lock; #endif atexit_callback *ll_callbacks; // XXX The rest of the state could be moved to the atexit module state // and a low-level callback added for it during module exec. // For the moment we leave it here. // List containing tuples with callback information. // e.g. [(func, args, kwargs), ...] PyObject *callbacks; }; #ifdef Py_GIL_DISABLED # define _PyAtExit_LockCallbacks(state) PyMutex_Lock(&state->ll_callbacks_lock); # define _PyAtExit_UnlockCallbacks(state) PyMutex_Unlock(&state->ll_callbacks_lock); #else # define _PyAtExit_LockCallbacks(state) # define _PyAtExit_UnlockCallbacks(state) #endif // Export for '_interpchannels' shared extension PyAPI_FUNC(int) _Py_AtExit( PyInterpreterState *interp, atexit_datacallbackfunc func, void *data); #ifdef __cplusplus } #endif #endif /* !Py_INTERNAL_ATEXIT_H */