/* the special case to remove a specific tasklet */
PyTaskletObject *
slp_channel_remove(PyChannelObject *channel,
                            PyTaskletObject *task,
                            int *dir_out,
                            PyTaskletObject **next)
{
    /* note: we assume that the task is in the channel! */
    int dir = channel->balance > 0 ? 1 : -1;
    assert(channel->balance);
    if (task) {
        assert(PyTasklet_Check(task));
        assert(slp_channel_has_tasklet(channel, task));
    } else {
        task = channel->head;
        assert(PyTasklet_Check(task));
    }
    if (dir_out)
        *dir_out = dir;
    if (next)
        *next = task->next;
    channel->balance -= dir;
    SLP_HEADCHAIN_REMOVE(task, next, prev);
    task->flags.blocked = 0;
    return task;
}
示例#2
0
static int
impl_tasklet_setup(PyTaskletObject *task, PyObject *args, PyObject *kwds)
{
    PyThreadState *ts = PyThreadState_GET();
    PyFrameObject *frame;
    PyObject *func;

    assert(PyTasklet_Check(task));
    if (ts->st.main == NULL) return PyTasklet_Setup_M(task, args, kwds);

    func = task->tempval;
    if (func == NULL)
        RUNTIME_ERROR("the tasklet was not bound to a function", -1);
    if ((frame = (PyFrameObject *)
                 slp_cframe_newfunc(func, args, kwds, 0)) == NULL) {
        return -1;
    }
    if (bind_tasklet_to_frame(task, frame)) {
        Py_DECREF(frame);
        return -1;
    }
    TASKLET_SETVAL(task, Py_None);
    Py_INCREF(task);
    slp_current_insert(task);
    return 0;
}
示例#3
0
文件: channelobject.c 项目: d11/rts
static PyObject *
channel_setstate(PyObject *self, PyObject *args)
{
	PyChannelObject *ch = (PyChannelObject *) self;
	PyTaskletObject *t;
	PyObject *lis;
	int flags, balance;
	int dir;
	Py_ssize_t i, n;

	if (!PyArg_ParseTuple(args, "iiO!:channel",
			      &balance,
			      &flags,
			      &PyList_Type, &lis))
		return NULL;

	channel_clear((PyObject *) ch);
	n = PyList_GET_SIZE(lis);
	*(int *)&ch->flags = flags;
	dir = balance > 0 ? 1 : -1;

	for (i = 0; i < n; i++) {
		t = (PyTaskletObject *) PyList_GET_ITEM(lis, i);

		if (PyTasklet_Check(t) && !t->flags.blocked) {
			Py_INCREF(t);
			slp_channel_insert(ch, t, dir);
		}
	}
	Py_INCREF(self);
	return self;
}
示例#4
0
static PyObject *
tasklet_get_prev(PyTaskletObject *task)
{
    PyObject *ret = Py_None;

    if (task->prev != NULL && PyTasklet_Check(task->prev))
        ret = (PyObject *) task->prev;
    Py_INCREF(ret);
    return ret;
}
示例#5
0
static PyObject *
tasklet_get_next(PyTaskletObject *task)
{
    PyObject *ret = Py_None;

    if (task->next != NULL && PyTasklet_Check(task->next))
        ret = (PyObject *) task->next;
    Py_INCREF(ret);
    return ret;
}
示例#6
0
static TASKLET_RUN_HEAD(impl_tasklet_run)
{
    STACKLESS_GETARG();
    PyThreadState *ts = PyThreadState_GET();

    assert(PyTasklet_Check(task));
    if (ts->st.main == NULL) return PyTasklet_Run_M(task);
    if (PyTasklet_Insert(task))
        return NULL;
    return slp_schedule_task(ts->st.current, task, stackless, 0);
}
示例#7
0
文件: channelobject.c 项目: d11/rts
PyTaskletObject *
slp_channel_remove_specific(PyChannelObject *channel, int dir,
			    PyTaskletObject *task)
{
	/* note: we assume that the task is in the channel! */

	assert(PyTasklet_Check(task));
	channel->balance -= dir;
	SLP_HEADCHAIN_REMOVE(task, next, prev);
	task->flags.blocked = 0;
	return task;
}
示例#8
0
文件: channelobject.c 项目: d11/rts
PyTaskletObject *
slp_channel_remove(PyChannelObject *channel, int dir)
{
	PyTaskletObject *ret = channel->head;

	assert(PyTasklet_Check(ret));

        channel->balance -= dir;
	SLP_HEADCHAIN_REMOVE(ret, next, prev);
	ret->flags.blocked = 0;
        return ret;
};
/* see if a tasklet is queued on a channel */
#ifndef NDEBUG /* currently used only by assert */
static int
slp_channel_has_tasklet(PyChannelObject *channel,
                            PyTaskletObject *task)
{
    PyTaskletObject *t = channel->head;
    while(PyTasklet_Check(t)) {
        if (t == task)
            return 1;
        t = t->next;
    }
    return 0;
}
示例#10
0
static TASKLET_INSERT_HEAD(impl_tasklet_insert)
{
    PyThreadState *ts = PyThreadState_GET();

    assert(PyTasklet_Check(task));
    if (ts->st.main == NULL)
        return slp_current_wrapper(PyTasklet_Insert, task);
    if (task->flags.blocked)
        RUNTIME_ERROR("You cannot run a blocked tasklet", -1);
    if (task->f.frame == NULL && task != ts->st.current)
        RUNTIME_ERROR("You cannot run an unbound(dead) tasklet", -1);
    if (task->next == NULL) {
        Py_INCREF(task);
        slp_current_insert(task);
        /* The tasklet may belong to a different thread, and that thread may
         * be blocked, waiting for something to do!
         */
        slp_thread_unblock(task->cstate->tstate);
    }
    return 0;
}
示例#11
0
static TASKLET_REMOVE_HEAD(impl_tasklet_remove)
{
    PyThreadState *ts = PyThreadState_GET();
    PyTaskletObject *hold = ts->st.current;

    assert(PyTasklet_Check(task));
    if (ts->st.main == NULL) return PyTasklet_Remove_M(task);

    assert(ts->st.current != NULL);
    if (task->flags.blocked)
        RUNTIME_ERROR("You cannot remove a blocked tasklet.", -1);
    if (task == ts->st.current)
        RUNTIME_ERROR("The current tasklet cannot be removed.", -1);
    if (task->next == NULL)
        return 0;
    ts->st.current = task;
    slp_current_remove();
    ts->st.current = hold;
    Py_DECREF(task);
    return 0;
}