MightyPirates / OpenComputers

Home of the OpenComputers mod for Minecraft.
https://oc.cil.li
Other
1.59k stars 431 forks source link

yield may cause events to be lost #3557

Open pdos95 opened 2 years ago

pdos95 commented 2 years ago

I found that using the yield function directly to back to machine.lua, the event is lost in the event library. This is not the case in the thread, because the thread wraps the pull function and registers the listeners with event. Afterwards it waits for other pull events instead of yield. Isn't this inconsistent.

Perhaps we could add a coroutine after init to solve this problem?

I know this is an unconventional use. But it's supposed to be a bug?

This article is translated using translation software, so please note any inaccuracies in the translation

payonel commented 2 years ago

some of what you are descrbing is by design. however, coroutine.yield() on the main openos init thread returns the signal to me.

example code: for i=1,10 do print(coroutine.yield()) end

This will block until a signal is received, and it prints that signal. Can you demonstrate some code that shows when signals are lost? And how are you executing that code?

pdos95 commented 2 years ago

I just found it when I was looking at the OpenOS code. I did a simple test and this is indeed the case. In my understanding a new process should be isolated from other processes and have no effect on each other. But the reality is that coroutine.yield(), which is at the bottom of the init process, and coroutine.yield() of a new process do not execute with the same result.

Recently I've been looking at the OpenOS code and trying to put together a diagram. But I can't share it because I only know Chinese. I wish there was an official document about the details of the openOS architecture to make it easier to understand the details. a b

pdos95 commented 2 years ago

For reference, I found the code I tested at the time on my home computer:

cat a.lua `local event = require("event") local thread = require("thread") local computer = require("computer")

thread.create(function(...) event.listen("key_up", function(event_name, ...) print("event listen: ", event_name) end) end)

while true do event_name = coroutine.yield() print("main yield: ", event_name) end`

cat b.lua `local event = require("event") local thread = require("thread") local computer = require("computer")

thread.create(function(...) event.listen("key_up", function(event_name, ...) print("event listen: ", event_name) end) while true do event_name = coroutine.yield() print("thread yield: ", event_name) end end)`