PyObject * PyStackless_RunWatchdogEx(long timeout, int flags) { PyThreadState *ts = PyThreadState_GET(); PyTaskletObject *victim; PyObject *retval; if (ts->st.main == NULL) return PyStackless_RunWatchdog_M(timeout, flags); if (ts->st.current != ts->st.main) RUNTIME_ERROR( "run() must be run from the main tasklet.", NULL); if (timeout <= 0) ts->st.interrupt = NULL; else ts->st.interrupt = interrupt_timeout_return; ts->st.interval = timeout; ts->st.tick_watermark = ts->st.tick_counter + timeout; /* remove main. Will get back at the end. */ slp_current_remove(); Py_DECREF(ts->st.main); /* now let them run until the end. */ ts->st.runflags = flags; retval = slp_schedule_task(ts->st.main, ts->st.current, 0, 0); ts->st.runflags = 0; ts->st.interrupt = NULL; /* retval really should be PyNone here (or NULL). Technically, it is the * tempval of some tasklet that has quit. Even so, it is quite * useless to use. run() must return None, or a tasklet */ Py_XDECREF(retval); if (retval == NULL) /* an exception has occoured */ return NULL; /* * back in main. * We were either revived by slp_tasklet_end or the interrupt. * If we were using hard interrupts (bit 1 in flags not set) * we need to return the interrupted tasklet) */ if (ts->st.runcount > 1 && !(flags & PY_WATCHDOG_SOFT)) { /* remove victim. It is sitting next to us. */ ts->st.current = (PyTaskletObject*)ts->st.main->next; victim = slp_current_remove(); ts->st.current = (PyTaskletObject*)ts->st.main; return (PyObject*) victim; } else Py_RETURN_NONE; }
PyObject * PyStackless_RunWatchdog(long timeout) { PyThreadState *ts = PyThreadState_GET(); PyTaskletObject *victim; PyObject *retval; int err; if (ts->st.main == NULL) return PyStackless_RunWatchdog_M(timeout); if (ts->st.current != ts->st.main) RUNTIME_ERROR( "run() must be run from the main tasklet.", NULL); if (timeout <= 0) { ts->st.interrupt = NULL; } else { ts->st.interrupt = interrupt_timeout_return; } ts->st.interval = timeout; /* remove main. Will get back at the end. */ slp_current_remove(); Py_DECREF(ts->st.main); /* now let them run until the end. */ retval = slp_schedule_task(ts->st.main, ts->st.current, 0); ts->st.interrupt = NULL; err = retval == NULL; if (err) /* an exception has occoured */ return NULL; /* * back in main. * We were either revived by slp_tasklet_end or the interrupt. */ if (ts->st.runcount > 1) { /* remove victim. It is sitting next to us. */ ts->st.current = (PyTaskletObject*)ts->st.main->next; victim = slp_current_remove(); ts->st.current = (PyTaskletObject*)ts->st.main; Py_DECREF(retval); return (PyObject*) victim; } return retval; }