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

Reply via email to