[Stackless] stacklesssocket.py

Richard Tew richard.m.tew at gmail.com
Sun Aug 22 11:03:42 CEST 2010

On Sun, Aug 22, 2010 at 4:12 PM, Alejandro Castillo <pyalec at gmail.com> wrote:
> I would like to know more about the inconsistencies when dealing with
> Threads in Stackless.
> I think I have bumped into one or more of them.

First the obvious facts:
- Tasklets are bound to the thread they are created on.
- Each thread has its own scheduler.
- Channels support sends and receives between tasklets that belong to
different threads.

There is code that will forceably reawaken the main tasklet for a
thread, if the last tasklet in the scheduler for that thread is
involved in a blocking operation, to prevent deadlock.  You can
optionally disable this for a specific thread's scheduler by passing
in threadblock=1 when you run the scheduler on that thread.  Now,
there has not been a lot of usage of the channel-related threading
support that Stackless offers, and at first getting it stabilising it
was driven by my own usage and issues I experiences.  Christian at
that point already had a pretty good base.  There's been further work
by both Kristjan Valur and myself since then.

The particular problem case I experienced was:
1. Have a tasklet A on the thread A (the main thread) that awakens
sleeping tasklets after a number of seconds which they specified.
2. Have a tasklet B (the main tasklet) on thread B (a secondary
thread) that needs a result blocks on a channel.
3. Before tasklet B blocks on the results channel, create a new
tasklet C to invoke the sleep and to then send an exception into the
results channel to awaken tasklet B if it is still blocked on there.

The sequence of tasklet operations that resulted was:
1. Tasklet B on thread B creates tasklet C on thread B.
2. Tasklet B on thread B blocks on a channel.
3. Tasklet C on thread B runs and is subsequently blocked on tasklet A
on thread A's sleep channel.
4. Tasklet A on thread A wakes up Tasklet C on thread B.
5. Tasklet C on thread B exits.
6. The tear down of tasklet C on thread B finds tasklet B on thread B
(the main tasklet for that thread) blocked on the results channel,
when it finds no other tasklets in the scheduler to switch to and
tries to reawaken  its main tasklet.
7. Tasklet B on thread B (its main tasklet) is awoken with an
unexpected StopIteration (the main tasklet is receiving without a
sender available).
8. The application these threads and tasklets are running within, is
more confused, than you are trying to read this confusing description.

Anyway, the inconsistency is that you can block a non-main thread when
the main tasklet does a channel operation.  But when the main tasklet
is on a channel, and another tasklet on the scheduler exits, the main
channel has to be reawakened.  This is completely in line with this
not having had enough usage to finalise the needs it has to meet.


More information about the Stackless mailing list