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

Some questions about Top Level Corroutine Override

Started by thecrimulo, 21 September 2016 - 05:13 PM
thecrimulo #1
Posted 21 September 2016 - 07:13 PM
Hello there,
I have some questions, about when to initiate it, how to crash shell/mshell/rednet and some others, here it goes:

1) When I should initiate the TLCO?
This is kinda complex for me. I load my libraries in /vit/sysload (My libraries = My replacements for the majority of the libraries, ask me if more info needed) and its 3 files after /startup. Should I execute it in /startup or anywhere?

2) Initiate the TLCO after or before loading my custom libraries?
It talks by itself, also see (1)

3) How do I do the override?
This resumes to: How do I crash shell, multishell and rednet, and then put it over my TLCO?
Note: I don't plan to use those libraries and I can do a rewrite, there is no need for them running after the TLCO, EXCEPT for copying the old libraries into _G.old (Has to be sandboxed)

4) How does it differ from a Thread Manager? Examples?
KingofGamesYami #2
Posted 21 September 2016 - 07:33 PM
1) Whenever you want. It doesn't matter when you do it at all. In fact, it doesn't matter if you do it or not.

2) See #1

3) IIRC, you can simply queue an invalid "modem_message" event to crash rednet. No idea on multishell / shell though.

4) Well, since Thread Managers are impossible in ComputerCraft and don't exist in it… unless you meant Coroutine Manager, in which case: It is one.
Lyqyd #3
Posted 21 September 2016 - 07:54 PM
TLCO isn't itself a coroutine manager, it's used to kill off the two child coroutines that bios.lua initiates and start any desired custom coroutine manager in their place.
Sewbacca #4
Posted 21 September 2016 - 08:37 PM
Also TLCO won't work in Lua 5.2.
MKlegoman357 #5
Posted 21 September 2016 - 08:52 PM
Also TLCO won't work in Lua 5.2.

There are many TLCO implementations and you could think of many more. It doesn't need to rely on Lua 5.1 features (like getfenv) to operate.
Sewbacca #6
Posted 21 September 2016 - 08:53 PM
Also TLCO won't work in Lua 5.2.

There are many TLCO implementations and you could think of many more. It doesn't need to rely on Lua 5.1 features (like getfenv) to operate.
Oh, i didn't know that. Thanks.
Bomb Bloke #7
Posted 22 September 2016 - 01:11 AM
3) IIRC, you can simply queue an invalid "modem_message" event to crash rednet. No idea on multishell / shell though.

You only need to crash one of the coroutines started by the parallel.waitForAny() call here - hence taking down rednet.run() is sufficient to halt shell / multishell too.

The bios then notices the problem and attempts to use printError() to report it, so the typical TLCO replaces that function pointer so execution of code can continue outside of the parallel API call without the system shutting down.

For example:

-- Back up old printError pointer
local oldPrintError = printError

-- Override
function printError()
  -- Restore old pointer to deal with future errors:
  printError = oldPrintError

  -- New coroutine manager goes here; for a general use-case, you'll initially want it to run shell + rednet.run(), same as the old one
end

-- Perform TLCO by crashing current rednet.run() instance
os.queueEvent("modem_message", 0)  -- Untested, but I think this should do it
valithor #8
Posted 22 September 2016 - 07:06 AM
3) IIRC, you can simply queue an invalid "modem_message" event to crash rednet. No idea on multishell / shell though.

You only need to crash one of the coroutines started by the parallel.waitForAny() call here - hence taking down rednet.run() is sufficient to halt shell / multishell too.

The bios then notices the problem and attempts to use printError() to report it, so the typical TLCO replaces that function pointer so execution of code can continue outside of the parallel API call without the system shutting down.

For example:

-- Back up old printError pointer
local oldPrintError = printError

-- Override
function printError()
  -- Restore old pointer to deal with future errors:
  printError = oldPrintError

  -- New coroutine manager goes here; for a general use-case, you'll initially want it to run shell + rednet.run(), same as the old one
end

-- Perform TLCO by crashing current rednet.run() instance
os.queueEvent("modem_message", 0)  -- Untested, but I think this should do it

I am fairly sure that the rednet bug was fixed in more recent versions of ComputerCraft (may be wrong though). Either way you could always just call the shell.exit function and overwrite os.shutdown (would need to setup it up to where the second time it is called is when the wanted file is ran) instead of printError.


local oldShutDown = os.shutdown

_G.os.shutdown = function()
  _G.os.shutdown = function()
	_G.os.shutdown = oldShutDown
		--# New coroutine manager goes here; for a general use-case, you'll initially want it to run shell + rednet.run(), same as the old one
  end
end

shell.exit()
--# could also os.queueEvent("terminate")

edit:

I had assumed you were doing the rednet bug, but that would have required rednet instead of modem api being used. That would probably work for crashing the rednet coroutine.
Edited on 22 September 2016 - 05:10 AM
Bomb Bloke #9
Posted 22 September 2016 - 07:59 AM
I am fairly sure that the rednet bug was fixed in more recent versions of ComputerCraft (may be wrong though).

I based my event on a quick eye-balling of 1.79's version of the API - when rednet.run() spots a modem_message event, it passes the supposed modem side to isOpen(), which errors if the type isn't a string.