[Stackless] Semantic of schedule_remove

Jeff Senn senn at maya.com
Thu May 22 02:58:50 CEST 2008


On May 21, 2008, at 5:46 PM, Alberto Ganesh Barbati wrote:

> Jeff Senn ha scritto:
>> Hi Alberto-
>> Check the doc string for stackless.schedule_remove
>> import stackless
>> print stackless.schedule_remove.__doc__
>
> Thanks Jeff for the explanation. I believe that the doc, which I had  
> read, is defective. It says "switch to the next runnable tasklet and  
> remove self". However if the next runnable tasklet is self, the  
> function clearly cannot perform both tasks. In this corner case, I  
> find it more obvious to perform the remove rather than the  
> (degenerate) schedule, but apparently what is happening is the  
> opposite. All in all, you might say, the function is called  
> schedule_remove()! Maybe it would be interesting to have a function  
> named remove_schedule() with the opposite semantic, which is a much  
> more useful behaviour IMHO. Or am I missing something obvious that  
> might make such a function impossible to implement?

Well, I think it is that way only for historical reasons (from the  
days when there
was not really even a scheduler and you needed someplace to pass  
control to)  --
you might also argue that you should be able to do:
stackless.getcurrent().remove()  though, sadly, that does not work  
either
(also for reasons having to do with history and the specific  
implementation)...

>
>
> In any case, I believe this case should be described explicitly in  
> the doc.

Yep. Probably true.

>
>
>> And then run this slightly modified example and see
>> if the behavior is more obvious to you.  (Note: that
>> the "next runnable tasklet" could be yourself!
>> I suppose this boundary condition might be considered
>> a bit "astonishing".... :-)
>> -------
>> import stackless
>> def run(name):
>> print name, "start"
>> myself = stackless.getcurrent()
>> if stackless.schedule_remove() == myself:
>>    print "No one else to switch to! Continuing..."
>
> The fact is that I do not want it to continue! I am using  
> schedule_remove() to implement a cheap sort of blocking call without  
> using a channel. In the complete example (the one I posted is just  
> an excerpt, for sake of explanation) the tasklet calls  
> schedule_remove() after requesting data which are going to be  
> provided at a later time by the main tasklet. Once the main tasklet  
> has the data available, it re-inserts the blocked tasklet in the  
> runnable queue so that it can continue. If the block doesn't happen,  
> I am in big trouble because the code would try to access data that  
> is not yet available.
>
> Sure I can use a channel, but that approach requires an extra object  
> (the channel itself) which is actually unnecessary.

Yep. I understand.

Channels are pretty cheap...

Or you can obviously work-around by making sure you have another  
tasklet to pass to...

   if stackless.getruncount() > 1:
      # theoretically if you are using the timeout feature of  
stackless.run() to
      # simulate pre-emption there could be a race condition here!
      # so in that case you might always want the branch below even  
though it's more expensive
      stackless.schedule_remove()
   else:
      #workaround: spawn a tasket just to remove me
      def remove_it(a):
        a.remove()
      stackless.tasklet(remove_it)(stackless.getcurrent()).run()

Hope that helps (at least with the pragmatics!) :-)

-Jas

>
>
> Cheers,
>
> Ganesh
>
>
> _______________________________________________
> Stackless mailing list
> Stackless at stackless.com
> http://www.stackless.com/mailman/listinfo/stackless
>





More information about the Stackless mailing list