Hi there.
Working on stuff to spawn off work for actual worker threads, I realized that
there was no good way to to synchronize between two tasklets on two threads.
That is to say:
When sending data between two tasklet on the same thread, usually it is
sufficient to use tasklet.set_atomic() to disable tasklet interrupts (that
rarely happen anyway, only when using stackless.run() with non-zero values) to
ensure atomicity.
For example, this code from stacklesslib.locks.Event:
def wait(self, timeout=None):
with atomic():
if self._is_set:
return True
lock_channel_wait(self.chan, timeout)
return self._is_set
def set(self):
with atomic():
self._is_set = True
for i in range(-self.chan.balance):
self.chan.send(None)
the atomic() context manager is used here to ensure consistency of state.
However, I realized that when using the Event to set or wait for events between
threads, that is, when one tasklet was waiting and another, on a different
thread, was setting the event, this approach doesn't work. A thread switch can
happen anywhere, for example, in wait after the initial _is_set test, but
before the wait, causing a lost wakeup bug.
The solution is to make "atomic" also suspend automatic thread switching while
in progress. I've implemented this for our patched CCP version of stackless
and wanted to mention this here before rolling it into the distribution. One
thing that only slightly worries me is that this approach assumes a GIL-like
implementation. But stackless being so specialized, we are unlikely to see a
non-GIL version any time soon :)
K
_______________________________________________
Stackless mailing list
[email protected]
http://www.stackless.com/mailman/listinfo/stackless