lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


I considered something similar to this a while ago, but it doesn't work if the coroutine has a pcall inside (or if there is a c function on the stack that has called lua_pcall) as the error will be caught there rather than killing the routine.

Thanks,
Kevin

Sent from my iPhone

On 30 Mar 2013, at 06:58, Thijs Schreijer <thijs@thijsschreijer.nl> wrote:

> 
> 
>> -----Original Message-----
>> From: lua-l-bounces@lists.lua.org [mailto:lua-l-bounces@lists.lua.org] On
>> Behalf Of Ross Bencina
>> Sent: zaterdag 30 maart 2013 4:58
>> To: Lua mailing list
>> Subject: Re: Lua and preemptive scheduling for coroutines
>> 
>> 
>> On 29/03/2013 10:25 PM, Thijs Schreijer wrote:
>>>> [Ross Bencina wrote]
>>>> My (completely idiosyncratic) view is that actors with atomic
>>>> run-to-
>>>>> completion actions are a nice model. That way thread switch only
>>>>> happens in the scheduler. Actors can be raw handers or state
>>>>> machines (FSMs, HFSMs) and communicate (only) via non-blocking
>>>>> queues. Miro Samek has a nice practical book on this.
>>>>> 
>>>>> The main problem in implementing this in Lua would be supporting
>>>>> long running computation, (if you need to). Plus you need fully
>>>>> async i/o, but that's not so hard to get these days (eg luvit)
>>> Somethings like this
>> example?https://github.com/Tieske/CopasTimer/blob/tasks_as_coroutines/sour
>> ce/copas/timer.lua#L254
>>> 
>>> 
>>> See the queue:pop() and queue:pause() calls
>>> I'm rewriting the CopasTimer module to work more coroutine oriented.
>>> I think you'll find similar code in the Sierra Wireless scheduler.
>> 
>> 
>> If I understand that code correctly it's running worker tasks at "idle"
>> priority using cooperative scheduling (explicit yeild via queue:pause()).
>> 
>> That certainly solves the "supporting long running computation" problem,
>> but it uses explicit cooperation (queue:pause()), so doesn't quite fit
>> with the discussion of being fail-safe to untrusted code.
> 
> Just did a test. Try this code. The 'checker' will allow to run a coroutine for 1 second. A coroutine 'coro' is scheduled and runs for 2 seconds. It does work, the coro gets interrupted after 1 second and the code terminates.
> 
> local socket = require("socket")
> local t = socket.gettime()
> local i = 0
> local checkcount=0
> 
> local corof1 = function()
>  -- will exit after 2 seconds
>  while t+2>socket.gettime() do
>    i = i + 1
>  end
>  return "Loop completed"
> end
> 
> local checker = function()
>  checkcount = checkcount+1 
>  -- will kill the coro after 1 second
>  if t+1<socket.gettime() then 
>    print("timeout")
>    error("timeout")  
>  end
> end
> 
> local coro = coroutine.create(corof1)
> 
> debug.sethook(coro, checker, "l", 5000)
> print(coroutine.resume(coro))
> 
> How it works: See [1], which states;
>    "Inside a hook, you can call getinfo with level 2 
>    to get more information about the running function 
>    (level 0 is the getinfo function, and level 1 is 
>    the hook function),"
> So this means that the debughook runs on the executionstack of the coroutine. The error thrown by the 'checker' function in case of a timeout will put the coroutine in an "error state" and force it to die.
> 
> What you can't catch, is blocking calls on c level, eg. blocking IO functions.
> 
> I need to find some time, but then I'll wrap this in a general module probably. I certainly have some use for it myself.
> 
> Thijs
> 
> [1] http://www.lua.org/manual/5.1/manual.html#pdf-debug.sethook
>