automatic service startup (including test app 'ghostcall') and documentation updates

This commit is contained in:
20kdc 2018-04-22 19:40:08 +01:00
parent 3d399dc047
commit 981ea559c6
9 changed files with 136 additions and 23 deletions

1
.gitignore vendored
View File

@ -23,4 +23,5 @@ repobuild/*/*/*
inst.lua inst.lua
com2/code.tar.bd com2/code.tar.bd
upldr.sh upldr.sh
upldr-dev.sh
repository/inst.lua repository/inst.lua

View File

@ -14,11 +14,19 @@ local targsDH = {} -- data disposal
local todo = {} local todo = {}
local onEverest = {} -- Specific registration callbacks
local onReg = {}
local everestWindows = {} local everestWindows = {}
local nexus local nexus
local theEventHandler
local function addOnReg(p, f)
onReg[p] = onReg[p] or {}
table.insert(onReg[p], f)
end
local function resumeWF(...) local function resumeWF(...)
local ok, e = coroutine.resume(...) local ok, e = coroutine.resume(...)
if not ok then if not ok then
@ -26,22 +34,29 @@ local function resumeWF(...)
neo.emergency(e) neo.emergency(e)
nexus.startDialog(e, "ice") nexus.startDialog(e, "ice")
end end
return ok return ok, e
end end
nexus = { nexus = {
createNexusThread = function (f, ...) createNexusThread = function (f, ...)
local t = coroutine.create(f) local t = coroutine.create(f)
if not resumeWF(t, ...) then return end local ok, cbi = resumeWF(t, ...)
local early = neo.requestAccess("x.neo.pub.window") if not ok then return end
local early = neo.requestAccess("x.neo.pub.window", theEventHandler)
if early then if early then
onEverest[#onEverest] = nil local r = onReg["x.neo.pub.window"]
resumeWF(t, early) -- r should not be nil here
onReg["x.neo.pub.window"] = nil
for k, v in ipairs(r) do
v()
end
end end
return function () return function ()
for k, v in ipairs(onEverest) do local r = onReg["x.neo.pub.window"]
if v == t then if not r then return end
table.remove(onEverest, k) for k, v in ipairs(r) do
if v == cbi then
table.remove(r, k)
return return
end end
end end
@ -49,8 +64,11 @@ nexus = {
end, end,
create = function (w, h, t) create = function (w, h, t)
local thr = coroutine.running() local thr = coroutine.running()
table.insert(onEverest, thr) local function cb()
local everest = coroutine.yield() coroutine.resume(thr, neo.requestAccess("x.neo.pub.window"))
end
addOnReg("x.neo.pub.window", cb)
local everest = coroutine.yield(cb)
local dw = everest(w, h, title) local dw = everest(w, h, title)
everestWindows[dw.id] = thr everestWindows[dw.id] = thr
return dw return dw
@ -232,11 +250,27 @@ local function wrapWASS(perm, req)
if paP then if paP then
permAct = appAct:sub(1, #appAct - #paP) permAct = appAct:sub(1, #appAct - #paP)
end end
pcall(neo.executeAsync, appAct) -- Prepare for success
neo.scheduleTimer(0) onReg[perm] = onReg[perm] or {}
table.insert(todo, function () table.insert(onReg[perm], function ()
req(res) req(res)
req = nil
end) end)
pcall(neo.executeAsync, "svc-" .. appAct)
-- Fallback "quit now"
local time = os.uptime() + 30
neo.scheduleTimer(time)
local f
function f()
if req then
if os.uptime() >= time then
req(res)
else
table.insert(todo, f)
end
end
end
table.insert(todo, f)
return return
end end
end end
@ -253,7 +287,7 @@ rootAccess.securityPolicy = function (pid, proc, perm, req)
if neo.dead then if neo.dead then
return backup(pid, proc, perm, req) return backup(pid, proc, perm, req)
end end
req = wrapWASS(req) req = wrapWASS(perm, req)
local def = proc.pkg:sub(1, 4) == "sys-" local def = proc.pkg:sub(1, 4) == "sys-"
local secpol, err = require("sys-secpolicy") local secpol, err = require("sys-secpolicy")
if not secpol then if not secpol then
@ -273,8 +307,8 @@ rootAccess.securityPolicy = function (pid, proc, perm, req)
end) end)
end end
while true do function theEventHandler(...)
local ev = {coroutine.yield()} local ev = {...}
if ev[1] == "k.procdie" then if ev[1] == "k.procdie" then
local _, pkg, pid, reason = table.unpack(ev) local _, pkg, pid, reason = table.unpack(ev)
if targsDH[pid] then if targsDH[pid] then
@ -294,11 +328,11 @@ while true do
end end
end end
elseif ev[1] == "k.registration" then elseif ev[1] == "k.registration" then
if ev[2] == "x.neo.pub.window" then if onReg[ev[2]] then
local nt = onEverest local tmp = onReg[ev[2]]
onEverest = {} onReg[ev[2]] = nil
for _, v in ipairs(nt) do for _, v in ipairs(tmp) do
coroutine.resume(v, neo.requestAccess("x.neo.pub.window")) v()
end end
end end
elseif ev[1] == "x.neo.pub.window" then elseif ev[1] == "x.neo.pub.window" then
@ -311,3 +345,7 @@ while true do
end end
end end
end end
while true do
theEventHandler(coroutine.yield())
end

View File

@ -0,0 +1,8 @@
-- This is released into the public domain.
-- No warranty is provided, implied or otherwise.
-- app-ghostcall.lua : Who are you gonna call?
-- Authors: 20kdc
local g = neo.requireAccess("x.svc.ghostie", "ghosts")
g()

View File

@ -0,0 +1,36 @@
-- This is released into the public domain.
-- No warranty is provided, implied or otherwise.
-- svc-ghostie.lua : Ghostie the test ghost!
-- Authors: 20kdc
-- Since this should expect to be started on-demand,
-- take precautions here.
-- Specifically, register as soon as possible.
-- While not required, security dialogs can cause a timeout.
local r = neo.requireAccess("r.svc.ghostie", "ghost registration")
local waiting = 0
r(function (pkg, pid, sendSig)
-- just totally ignore the details
return function ()
neo.scheduleTimer(os.uptime() + 5 + (math.random() * 10))
waiting = waiting + 1
end
end)
local computer = neo.requireAccess("k.computer", "scare system")
while true do
local ev = coroutine.yield()
if ev == "k.timer" then
-- boo!
computer.beep(440, 1)
waiting = waiting - 1
if waiting == 0 then
return
end
end
end

View File

@ -60,4 +60,18 @@ return {
"apps/app-nprt2018.lua" "apps/app-nprt2018.lua"
}, },
}, },
["svc-ghostie"] = {
desc = "Application that schedules a scare after a random time to test svc autostart",
v = 0,
deps = {
"neo"
},
dirs = {
"apps"
},
files = {
"apps/svc-ghostie.lua",
"apps/app-ghostcall.lua"
},
},
} }

View File

@ -305,7 +305,7 @@ The additional things available to
is never touched by the kernel is never touched by the kernel
directly, called the "tag". directly, called the "tag".
The resulting event: The resulting event:
"k.timer", tag, time, ofs "k.timer", tag, time
These events are ONLY EVER sent as These events are ONLY EVER sent as
a consequence of this function, a consequence of this function,
and this can be relied on safely. and this can be relied on safely.

View File

@ -47,6 +47,10 @@ Main functions:
neoux.create(w, h, title, callback): neoux.create(w, h, title, callback):
Creates a window, Creates a window,
including a NeoUX window wrapper. including a NeoUX window wrapper.
NOTE: The width can never be smaller
than 8, under any circumstances.
Trying to will cause the width to be
forced to 8.
The parameter list is compatible The parameter list is compatible
with the window "reset" function, with the window "reset" function,
and it is intended that you use and it is intended that you use
@ -156,6 +160,10 @@ UI framework window API (TODO):
height. Like in the API this wraps, height. Like in the API this wraps,
this is guaranteed to refresh all this is guaranteed to refresh all
the lines of your window. the lines of your window.
NOTE: The width can never be smaller
than 8, under any circumstances.
Trying to will cause the width to be
forced to 8.
getDepth(...): Read the note getDepth(...): Read the note
in us-evrst for details. in us-evrst for details.

View File

@ -17,6 +17,10 @@ The API gives you a function:
(w, h, title) -> window (w, h, title) -> window
This function creates a window. This function creates a window.
NOTE: The width can never be smaller
than 8, under any circumstances.
Trying to will cause the width to be
forced to 8.
Window fields: Window fields:
@ -25,6 +29,10 @@ Window fields:
the window, and sends the line the window, and sends the line
events (even if the size doesn't events (even if the size doesn't
change) change)
NOTE: The width can never be smaller
than 8, under any circumstances.
Trying to will cause the width to be
forced to 8.
getDepth(): Returns the depth of the getDepth(): Returns the depth of the
screen the window is on. screen the window is on.
span(x, y, text, bg, fg): Draws a span(x, y, text, bg, fg): Draws a