<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="Generator" content="Microsoft Word 14 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:Wingdings;
        panose-1:5 0 0 0 0 0 0 0 0 0;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri","sans-serif";
        mso-fareast-language:EN-US;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri","sans-serif";
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri","sans-serif";
        mso-fareast-language:EN-US;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:72.0pt 72.0pt 72.0pt 72.0pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-GB" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span lang="IS">Hi there.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS">That is to say:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS">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.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS">For example, this code from stacklesslib.locks.Event:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="IS">def wait(self, timeout=None):<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS">        with atomic():<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS">            if self._is_set:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS">                return True<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS">            lock_channel_wait(self.chan, timeout)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS">            return self._is_set<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="IS">    def set(self):<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS">        with atomic():<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS">            self._is_set = True<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS">            for i in range(-self.chan.balance):<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS">                self.chan.send(None)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="IS">the atomic() context manager is used here to ensure consistency of state.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="IS">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 _<i>is</i>_set test, but before the wait, causing a lost wakeup bug.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="IS">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
</span><span lang="IS" style="font-family:Wingdings">J</span><span lang="IS"><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="IS"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="IS">K<o:p></o:p></span></p>
</div>
</body>
</html>