This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
squaretrees's profile picture

Too long without yielding error

Started by squaretrees, 14 September 2014 - 11:44 AM
squaretrees #1
Posted 14 September 2014 - 01:44 PM
So I have a pc connected to a monitor with a wired modem and when i run the following code i get this error:

error:

peripheral:sixty-something: Too long without yielding


code:

mon = peripheral.wrap("monitor_2")
while true do
  mon.write("stuff")
end

It seems that this is a peripherals' error so.. is there any other way of doing this?
Lyqyd #2
Posted 14 September 2014 - 06:41 PM
Why do you need it to write "stuff" an infinite number of times?
flaghacker #3
Posted 14 September 2014 - 09:43 PM
The error means that your code isn't yielding.

If you really need to execute that code add sleep(0) in the loop, but it's a better idea to use os.pullEvent so your code only runs when it needs to.
http://computercraft.info/wiki/Os.pullEvent
Bomb Bloke #4
Posted 15 September 2014 - 12:58 AM
When a computer/turtle starts running code, ComputerCraft starts a ten second timer. If that code doesn't yield before that timer ends then ComputerCraft crashes that computer. After each yield, any other systems waiting to run code do so, then after they've all yielded, processing continues with a new time limit.

The reason why is that running your code chews up valuable server processing power, and so it shouldn't be able to monopolise it. In fact, only ONE CC device can run code at a time: While one is doing something, none of the others can do anything until it yields.

Whether or not it takes more than ten seconds for your code to execute has a lot to do with the power of the Minecraft server it's running on, and how often you allow your code to yield. Pulling events (eg getting typed characters or checking timers) triggers a yield, and many commands (eg turtle movements, sleeping, or getting text input from the user) have to pull events to work anyway.

The error itself can occur anywhere in any of the code you're calling. You get the error in the peripheral API because you call the peripheral API without cease. If you called math.random() over and over without pause or variation, odds are it'd be thrown within the math API instead.
flaghacker #5
Posted 15 September 2014 - 04:08 PM
Do you have like a file with a bunch of general answers you can just copy-paste from? That answer seems very familiar :D/>/>
Edited on 15 September 2014 - 02:08 PM
Bomb Bloke #6
Posted 16 September 2014 - 02:18 AM
Not exactly. I've been dumping links to common questions in my profile.
Lyqyd #7
Posted 16 September 2014 - 02:36 AM
For clarity, ComputerCraft kills the offending coroutine when it triggers yield protection, not the entire computer.
Bomb Bloke #8
Posted 16 September 2014 - 02:53 AM
Depends. It will specifically crash the whole computer if it's so inclined (which is great for "clarity", as it makes it next to impossible to read the error!).

Although this doesn't "always" happen, it's not random - it depends on what code you were running at the time.
Lyqyd #9
Posted 16 September 2014 - 02:55 AM
Hmm. You may be right, I haven't tested it extensively. The last time I tested it on purpose was several versions ago, during the development of LyqydOS, just to see the effects. I was pleased to see that the test code I used caused the one coroutine to be terminated, but otherwise did not affect the rest of the computer. I wonder under what circumstances the yield protection kills just the one coroutine versus the entire computer.
natedogith1 #10
Posted 16 September 2014 - 04:10 AM
If I'm reading decompiled source code correctly, this is sort of what happens:

start computer
wait 5000 milliseconds
if (computer is still running) {
  soft abort
  wait 1250 milliseconds
  if (computer is still running) {
	hard abort
	wait 1250 milliseconds
	if (computer is still running) {
	  force kill computer
	}
  }
}
(when it waits, it can exit early if the computer yields)
A soft abort seems to throw an error when you attempt to call a java-defined lua function (so things like turtle, term, and peripheral).
A hard abort seems to just throw an error, not really caring where in the code you are.