lua-users home
lua-l archive

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


Well, one can not call yield from a Lua/C function that is being called from a C function. This means that your implementation will have to check explicitly whether there are any C calls on the stack and skip yielding and let the execution continue if there are such calls. This will make the time-out feature depend on the actual contents of the sctipt to the point not working at all in some scripts. You may have overcome this issue in your VM hack, but I was not clear on whether this is the case indeed. Try to use pcall in your main coroutine function like so 

instead of 
    co_1 = coroutine.create(function () person:display() end)
try
     co_1 = coroutine.create(function () pcall(person.display, person) end)
and so on. 

Is the output the same as before?
 
Alex

>-----Original Message-----
>From: wilfried.verachtert@pop3.yucom.be
>[mailto:wilfried.verachtert@pop3.yucom.be]
>Sent: Wednesday, April 14, 2004 6:39 PM
>To: lua@bazar2.conectiva.com.br
>Subject: RE: coroutines & timeout
>
>
>Hi,
>
>Thanks for your input.
>
>> I would think in general this is not such a hot idea for Lua. For
>> instance, this will not work in the middle of a function called under
>> pcall or a metatable. Thus there is no way to enforce it to 
>begin with. 
>
>I'm not quite sure what you mean with that. I did see some 
>similar remarks
>in some other threads (about threads :-) that seem to suggest the same
>thing. I've done a few test using metatable functions and 
>everything seems
>to be working as expected. (I added my script and the output 
>of it at the
>end of this mail) So, I might be lucky or I'm missing 
>something. Since I'm
>pretty new at LUA, I would guess that the latter is more likely but I
>wouldn't know.
>
>Primitive functions written in C, those are not captured by the way I'm
>forcing a 'yield' in the VM. But that's something I could live with. 
>
>> On 
>> the other hand it is hard to imagine the usefullness of this 
>accross the
>> board as it seems from my experience the scripts want to yield in a
>> particular spot, rather than with a given time regularity in 
>the middle of
>> nowhere (imagine driving animation, simulation, state 
>machine, a slide
>> show, etc. for instance). All of them will need yilding occur in some
>> orderly fashion in places dictated by logic rather than 
>time. Using the
>> debug hooks for yeilding have caused more problems for us 
>than it solved
>> as it had been highly unreliable from my experience (this 
>may change in
>> the future)... opcode hooks are especially prone to nasty side
>> effects/bugs when yielded from (at least they were a year or 
>so ago). Line
>> hooks have also suffered from similar dificiencies but to a 
>lesser degree.
>
>That's a valid point, but there are some cases where you would 
>rather have
>some time-out control over child processes. I'm thinking of writing a
>server that can serve multiple clients. (like a web-server, 
>telnet-server,
>...) I would like to have multiple processes running in parallel, but I
>would like to control the 'fairness' of the processing time 
>given to each
>process. I don't want to enforce everybody to put 'yields' at specific
>places in their code. I've worked with such a model in the 
>past, and for
>this kind of code it's a terrible thing to maintain. Having a little
>scheduler that can rely on time-outs is much easier in this case.
>
>In some other cases (like the ones you mention), I would rather use the
>explicit yielding of the child processes.
>
>In short, I would like to have both of them. 
> 
>> I use a number sleep functions in my scheduler and people use them
>> where/how they see fit in their scripts. And we have 
>non-programming staff
>> using Lua on a daily basis with no complaines about this 
>particular aspect
>> of it.
>> 
>> Just my .02
>> Alex
>
>The script:
>
>--------------------------------------------------------------
>function fib(n)
>  if n<2 then
>    return n
>  else
>    return fib(n-1)+fib(n-2)
>  end
>end
>
>object = {}
>
>object.__index = function (a,b)
>  co = coroutine.create(fib)
>  s, v = coroutine.timedresume(co, 1000, 35)
>  print(v)
>  return object[b]
>end
>
>function object:classname ()
>  return "<object>"
>end
>
>function object:displaystring ()
>  return self:classname()
>end
>
>function object:display ()
>  fib(32) -- just to make this function take some time to calculate
>  print(self:displaystring())
>end
>
>person = {}
>setmetatable(person, object)
>
>function person:classname ()
>  return "<person>"
>end
>
>print(">>")
>person:display()
>print("<<")
>
>co_1 = coroutine.create(function () person:display() end)
>co_2 = coroutine.create(function () object:display() end)
>
>repeat
>  s1 = coroutine.timedresume(co_1, 1000)
>  print("-")
>  s2 = coroutine.timedresume(co_2, 1000)
>  print("+")
>until (not s1) and (not s2)
>
>print(coroutine.timedresume(co, 8000))
>print(coroutine.timedresume(co, 8000))
>
>--------------------------------------------------------------
>... and the output ...
>--------------------------------------------------------------
>>>
>nil
>nil
><person>
><<
>nil
>-
>+
>-
>+
>-
>+
>-
><object>
>+
>nil
><person>
>-
>+
>-
>+
>true
>true    9227465
>--------------------------------------------------------------
>
>
>
>--------------------------------------------------------------------
>mail2web - Check your email from the web at
>http://mail2web.com/ .
>
>
>
>