Files
Halyde/halyde/kernel/modules/tsched.lua
T
Ponali f5fcc84903 fixed the "user" kernel module getting the wrong IDs when creating tasks
when the user kernel module creates a task, it used to count the amount
of processes in the system, which can lead to some processes having the
same IDs as another, which causes havoc. this has been fixed by using
the ID counter in the tsched kernel module.
2025-10-30 17:48:16 +01:00

127 lines
3.7 KiB
Lua

local module = {}
module.dependencies = {}
function module.check()
return true
end
function module.init()
_G._PUBLIC.tsched = {}
_G.tsched = {}
_G.tsched.tasks = {}
local component = require("component")
local filesystem = require("filesystem")
local gpu = component.gpu
local log = require("log")
tsched.idCounter = 1
function _G._PUBLIC.tsched.runAsTask(path, ...)
checkArg(1, path, "string")
local args = { ... }
local function taskFunction()
local result, errorMessage = xpcall(function(...)
local args = table.pack(...)
if not filesystem.exists(path) then
error("No such file: " .. path)
end
local handle, data, tmpdata = filesystem.open(path), "", nil
repeat
tmpdata = handle:read(math.huge or math.maxinteger)
data = data .. (tmpdata or "")
until not tmpdata
handle:close()
-- Userland environment definition
local userland = table.copy(_PUBLIC)
userland._G = userland
userland.load = function(chunk, chunkname, mode, env)
if not env or env == _G then
env = userland
end -- if they SOMEHOW get the kernel environment they're not running jack shit
return load(chunk, chunkname, mode, env)
end
userland.require = reqgen(userland.load)
assert(load(data, "=" .. path, "t", userland))(table.unpack(args))
end, function(errorMessage)
return errorMessage .. "\n \n" .. debug.traceback()
end, --[[ path,]] table.unpack(args))
if not result then
if print then
gpu.freeAllBuffers()
print("\n\27[91m" .. errorMessage)
else
error(errorMessage)
end
end
--require(path, table.unpack(args))
end
local _, taskInfo = _PUBLIC.tsched.addTask(taskFunction, string.match(tostring(path), "([^/]+)%.lua$"))
taskInfo.path = path
taskInfo.args = table.copy(args)
end
function _G._PUBLIC.tsched.addTask(func, name)
checkArg(1, func, "function")
checkArg(2, name, "string")
local task = coroutine.create(func)
local taskInfo = { ["task"] = task, ["name"] = name, ["id"] = tsched.idCounter }
if type(tsched.currentTask) == "table" and type(tsched.currentTask.id) == "number" then
taskInfo.parent = tsched.currentTask.id
taskInfo.user = tsched.currentTask.user
end
table.insert(tsched.tasks, taskInfo)
tsched.idCounter = tsched.idCounter + 1
if taskInfo.parent then
log.kernel.info(
("[tsched] Created task %s (PID %d) by parent PID %d as UID %d"):format(
name,
tsched.idCounter - 1,
taskInfo.parent,
taskInfo.user
)
)
else
taskInfo.user = 1 -- It's probably being run from kernel level
log.kernel.info(
string.format("[tsched] Created task %s (PID %d) as UID 1 (no parent found)", name, tsched.idCounter - 1)
)
end
return task, taskInfo
end
function _G._PUBLIC.tsched.removeTask(id)
checkArg(1, id, "number")
-- TODO: Check for user permissions before running
for index, task in pairs(tsched.tasks) do
if task.id == id then
table.remove(tsched.tasks, index)
log.kernel.info(string.format("[tsched] Removed task with PID %d", id))
return true
end
end
log.kernel.warn(string.format("[tsched] Tried to remove task that doesn't exist - PID %d", id))
return false
end
function _G._PUBLIC.tsched.getCurrentTask()
return table.copy(tsched.currentTask)
end
function _G._PUBLIC.tsched.getTasks()
return table.copy(tsched.tasks)
end
end
function module.exit()
-- why would you even want to
_G._PUBLIC.tsched = nil
_G.tsched = nil
_G.tsched.tasks = nil
end
return module