-
Notifications
You must be signed in to change notification settings - Fork 195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix fatal Bug with coroutine.yield #431
Conversation
This is one of those bugs I've never been able to reproduce, so I'd appreciate someone else chiming in here: Has anyone been able to diagnose the root cause of this issue? Whilst infinite loops are inevitably going to block other computers from running, there shouldn't ever be a time when they stop them executing forever. On a side note, does this occur with #163? It fixed some issues with yield prevention, so it might also fix this. |
@SquidDev the infinite loop is not actually required to do this. Simplest reproduction steps:
Symptoms:
Conclusion: The infinite loop has nothing to do with it. Something about replacing coroutine.yield with a blank function does. |
Sadly this fix isn't going to fix everything - overriding One problem seems to be the lock on
Of course, the real issue is why the Lua thread isn't being interrupted correctly. |
function coroutine.yield( sFilter ) | ||
return nativeyield( sFilter ) | ||
end | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why override coroutine.yield itself??? Is that not simply overhead without any benefit?
-- Install lua parts of the os api | ||
function os.version() | ||
return "CraftOS 1.8" | ||
end | ||
|
||
function os.pullEventRaw( sFilter ) | ||
return coroutine.yield( sFilter ) | ||
return nativeyield( sFilter ) | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
os.pullEventRaw = nativeyield
maybe
@@ -683,15 +688,15 @@ local nativeShutdown = os.shutdown | |||
function os.shutdown() | |||
nativeShutdown() | |||
while true do | |||
coroutine.yield() | |||
nativeyield() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could consider setting a "neverResume" filter, or somesuch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally os.shutdown
would just terminate/suspend the VM there, meaning we didn't need this code at all.
I've done a little bit more debugging, and come up with the following reproduction case: local co = coroutine.create(function()
while true do end
end)
while coroutine.status(co) ~= "dead" do
coroutine.resume(co)
end As we're not calling any CC methods and we never yield, we won't ever get a timeout error, instead we'll just hit the debug hook: ComputerCraft/src/main/java/dan200/computercraft/core/lua/LuaJLuaMachine.java Lines 76 to 80 in fd8837c
This'll cause our coroutine to yield into the parent loop, which just resumes the thread again - thus nothing is terminated. Changing the hook to execute every instruction by changing this line to be 1 seems to fix this particular instance, but may cause problems elsewhere. Of course, we could always use Cobalt instead :p. It'd be nice if @dan200 could chime in on this, as I'm not entirely sure why the timeout code is structured the way it is. |
@Wilma456 This is a bad fix and doesn't resolve the actual problem (computers that infinite loop and timeout aren't allowing other computers to resume afterwards). Please fix that instead. @SquidDev The timeout code is 5 years old at this point, so forgive me for not remembering the details. It sounds like you're on the right track though. |
It is possible to froze all Computers in the world by running this code:
To only Way to break the freeze is to rejoin the world. With this fix, the Computer who run this code will crash after a few seconds and everything works normal.