lua-users home
lua-l archive

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


Le lun. 1 juin 2020 à 05:52, Gé Weijers <ge@weijers.org> a écrit :
On Sun, May 31, 2020 at 11:20 AM Joseph C. Sible <josephcsible@gmail.com> wrote:

I'm not sure, though, whether this is a bug in Lua, or just that
you're not supposed to use lua_resume on the main thread.


You can only resume a coroutine that's in the right state, it either should not have started yet, or it should have yielded. You cannot resume a thread that resumed another one, a thread that resumes another one will only restart if the thread it resumed yields or exits.

This last statement is contestable: when a thread resumes another one, it is instantly paused. So it instantly waits to be resumed, and it can be resumed from any active thread that yields to it:

thread A yields to thread B. Then thread B yields to thread C. Both A and B are waiting. thread C can yield to either A or B by resuming them: Threads can be cycled, but there's no predefined backward order for resuming and there should be none so that threads can be scheduled on different resume conditions: priorities, time, number of locks that can be unlocked (to limit the number of fatal deadlocks), error handling...

When a thread yields, there's no condition for which it could be resumed, except that as much as possible, the resumeing may be able to retrive the retrieve the expected return value transmitted by the yielding thread. If the thread exits, there's no return value, the awaiting thread will just retrieve a nil value or an error to detect that. But many threads are yielding without transmitting any value and the awaiting thread does not even expect a return value (if there's one, it is ignored/discarded), notably threads that just yield to be resumed at any time, only to allow other threads to compete.
Many blocking I/O are also yeilding and may return before the I/O is ready after a timeout expired: they will receive the error condition, but may still detect it, allowing to continue doing something else before yielding again, they don't care at all about a value to be returned on a blocking I/O that they can retry to query when the expected data is not there, or they an choose to do something else.

And most timeouts are indicative, not precise times: the resumed thread may be awaken before, and may want to check the current time at which they were awaken again.

How would you then program a main thread implementing an event loop if it is used to schedule many children threads without expecting any precise value from a single thread? The main thread is typically used to perform serialized I/O: it can be awkaen with variosu types of events trasmitted by any child thread and all child threads will yeild to the same main thread to allow the main thread to make and serialize their I/O.

A call like "response=yield(query)" may return various types of responses: the response must still be tested and can come from any other thread that could reply to the query, which could be chained. You never indicate in "response=yield(query)" which thread will reply with a response object! The "replying" thread will jsut be anyone that will explicitly resume the awaiting thread.

So if a thread A resumes a thread B, transmitting a response to it, A does not expect any value from B; A is just paused to let B do what it wants with the response and eventually resume another thread indicated in the first response object, which could be any one. A does not expect anything and can be awaken under any condition, without receiveing any error.