35#if GREENLET_BROKEN_THREAD_LOCAL_CLEANUP_JUST_LEAK
47 if (!MarkGreenletDeadIfNeeded(state)) {
53 if (!PyInterpreterState_Head()) {
61 AddToCleanupQueue(state);
77 LockGuard cleanup_lock(*mod_globs->thread_states_to_destroy_lock);
78 if (state->has_main_greenlet()) {
84 PyGreenlet* p(state->borrow_main_greenlet().borrow());
85 assert(p->pimpl->thread_state() == state || p->pimpl->thread_state() ==
nullptr);
86 dynamic_cast<MainGreenlet*
>(p->pimpl)->thread_state(
nullptr);
93 AddToCleanupQueue(ThreadState*
const state)
95 assert(state && state->has_main_greenlet());
105 LockGuard cleanup_lock(*mod_globs->thread_states_to_destroy_lock);
107 mod_globs->queue_to_destroy(state);
108 if (mod_globs->thread_states_to_destroy.size() == 1) {
121 int result = AddPendingCall(
122 PendingCallback_DestroyQueue,
127 "greenlet: WARNING: failed in call to Py_AddPendingCall; "
128 "expect a memory leak.\n");
134 PendingCallback_DestroyQueue(
void* UNUSED(arg))
140 ThreadState* to_destroy;
142 LockGuard cleanup_lock(*mod_globs->thread_states_to_destroy_lock);
143 if (mod_globs->thread_states_to_destroy.empty()) {
146 to_destroy = mod_globs->take_next_to_destroy();
149 assert(to_destroy->has_main_greenlet());
153 DestroyOne(to_destroy);
159 DestroyOne(
const ThreadState*
const state)
164 assert(state->has_main_greenlet());
165 PyGreenlet* main(state->borrow_main_greenlet());
171 dynamic_cast<MainGreenlet*
>(main->pimpl)->thread_state(
nullptr);
177 static int AddPendingCall(
int (*func)(
void*),
void* arg)
187 if (Py_IsFinalizing()) {
189 if (_Py_IsFinalizing()) {
195 "greenlet: WARNING: Interpreter is finalizing. Ignoring "
196 "call to Py_AddPendingCall; \n");
200 return Py_AddPendingCall(func, arg);