static void green_dealloc(PyGreenlet* self) { PyObject *error_type, *error_value, *error_traceback; #ifdef GREENLET_USE_GC PyObject_GC_UnTrack((PyObject *)self); Py_TRASHCAN_SAFE_BEGIN(self); #endif /* GREENLET_USE_GC */ if (PyGreenlet_ACTIVE(self) && self->run_info != NULL && !PyGreenlet_MAIN(self)) { /* Hacks hacks hacks copied from instance_dealloc() */ /* Temporarily resurrect the greenlet. */ assert(Py_REFCNT(self) == 0); Py_REFCNT(self) = 1; /* Save the current exception, if any. */ PyErr_Fetch(&error_type, &error_value, &error_traceback); if (kill_greenlet(self) < 0) { PyErr_WriteUnraisable((PyObject*) self); /* XXX what else should we do? */ } /* Check for no resurrection must be done while we keep * our internal reference, otherwise PyFile_WriteObject * causes recursion if using Py_INCREF/Py_DECREF */ if (Py_REFCNT(self) == 1 && PyGreenlet_ACTIVE(self)) { /* Not resurrected, but still not dead! XXX what else should we do? we complain. */ PyObject* f = PySys_GetObject("stderr"); Py_INCREF(self); /* leak! */ if (f != NULL) { PyFile_WriteString("GreenletExit did not kill ", f); PyFile_WriteObject((PyObject*) self, f, 0); PyFile_WriteString("\n", f); } } /* Restore the saved exception. */ PyErr_Restore(error_type, error_value, error_traceback); /* Undo the temporary resurrection; can't use DECREF here, * it would cause a recursive call. */ assert(Py_REFCNT(self) > 0); if (--Py_REFCNT(self) != 0) { /* Resurrected! */ Py_ssize_t refcnt = Py_REFCNT(self); _Py_NewReference((PyObject*) self); Py_REFCNT(self) = refcnt; #ifdef GREENLET_USE_GC PyObject_GC_Track((PyObject *)self); #endif _Py_DEC_REFTOTAL; #ifdef COUNT_ALLOCS --Py_TYPE(self)->tp_frees; --Py_TYPE(self)->tp_allocs; #endif /* COUNT_ALLOCS */ goto green_dealloc_end; } } if (self->weakreflist != NULL) PyObject_ClearWeakRefs((PyObject *) self); Py_CLEAR(self->parent); Py_CLEAR(self->run_info); Py_CLEAR(self->exc_type); Py_CLEAR(self->exc_value); Py_CLEAR(self->exc_traceback); Py_CLEAR(self->dict); Py_TYPE(self)->tp_free((PyObject*) self); green_dealloc_end: #ifdef GREENLET_USE_GC Py_TRASHCAN_SAFE_END(self); #endif /* GREENLET_USE_GC */ return; }
void greenlet_kill(greenlet *gr) { kill_greenlet(gr); }