PyObject * PyStackless_Schedule(PyObject *retval, int remove) { STACKLESS_GETARG(); PyThreadState *ts = PyThreadState_GET(); PyTaskletObject *prev = ts->st.current, *next = prev->next; PyObject *ret = NULL; if (ts->st.main == NULL) return PyStackless_Schedule_M(retval, remove); Py_INCREF(prev); TASKLET_SETVAL(prev, retval); if (remove) { slp_current_remove(); Py_DECREF(prev); } ret = slp_schedule_task(prev, next, stackless); Py_DECREF(prev); return ret; }
PyObject * PyStackless_Schedule(PyObject *retval, int remove) { STACKLESS_GETARG(); PyThreadState *ts = PyThreadState_GET(); PyTaskletObject *prev = ts->st.current, *next = prev->next; PyObject *ret = NULL; int switched; if (ts->st.main == NULL) return PyStackless_Schedule_M(retval, remove); /* make sure we hold a reference to the previous tasklet */ Py_INCREF(prev); TASKLET_SETVAL(prev, retval); if (remove) { slp_current_remove(); Py_DECREF(prev); if (next == prev) next = 0; /* we were the last runnable tasklet */ } /* we mustn't DECREF prev here (after the slp_schedule_task(). * This could be the last reference, thus * promting emergency reactivation of the tasklet, * and soft switching isn't really done until we have unwound. * Use the delayed release mechanism instead. */ assert(ts->st.del_post_switch == NULL); ts->st.del_post_switch = (PyObject*)prev; ret = slp_schedule_task(prev, next, stackless, &switched); /* however, if this was a no-op (e.g. prev==next, or an error occurred) * we need to decref prev ourselves */ if (!switched) Py_CLEAR(ts->st.del_post_switch); return ret; }