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
com2/code.tar.bd
upldr.sh
upldr-dev.sh
repository/inst.lua

View File

@ -14,11 +14,19 @@ local targsDH = {} -- data disposal
local todo = {}
local onEverest = {}
-- Specific registration callbacks
local onReg = {}
local everestWindows = {}
local nexus
local theEventHandler
local function addOnReg(p, f)
onReg[p] = onReg[p] or {}
table.insert(onReg[p], f)
end
local function resumeWF(...)
local ok, e = coroutine.resume(...)
if not ok then
@ -26,22 +34,29 @@ local function resumeWF(...)
neo.emergency(e)
nexus.startDialog(e, "ice")
end
return ok
return ok, e
end
nexus = {
createNexusThread = function (f, ...)
local t = coroutine.create(f)
if not resumeWF(t, ...) then return end
local early = neo.requestAccess("x.neo.pub.window")
local ok, cbi = resumeWF(t, ...)
if not ok then return end
local early = neo.requestAccess("x.neo.pub.window", theEventHandler)
if early then
onEverest[#onEverest] = nil
resumeWF(t, early)
local r = onReg["x.neo.pub.window"]
-- r should not be nil here
onReg["x.neo.pub.window"] = nil
for k, v in ipairs(r) do
v()
end
end
return function ()
for k, v in ipairs(onEverest) do
if v == t then
table.remove(onEverest, k)
local r = onReg["x.neo.pub.window"]
if not r then return end
for k, v in ipairs(r) do
if v == cbi then
table.remove(r, k)
return
end
end
@ -49,8 +64,11 @@ nexus = {
end,
create = function (w, h, t)
local thr = coroutine.running()
table.insert(onEverest, thr)
local everest = coroutine.yield()
local function cb()
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)
everestWindows[dw.id] = thr
return dw
@ -232,11 +250,27 @@ local function wrapWASS(perm, req)
if paP then
permAct = appAct:sub(1, #appAct - #paP)
end
pcall(neo.executeAsync, appAct)
neo.scheduleTimer(0)
table.insert(todo, function ()
-- Prepare for success
onReg[perm] = onReg[perm] or {}
table.insert(onReg[perm], function ()
req(res)
req = nil
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
end
end
@ -253,7 +287,7 @@ rootAccess.securityPolicy = function (pid, proc, perm, req)
if neo.dead then
return backup(pid, proc, perm, req)
end
req = wrapWASS(req)
req = wrapWASS(perm, req)
local def = proc.pkg:sub(1, 4) == "sys-"
local secpol, err = require("sys-secpolicy")
if not secpol then
@ -273,8 +307,8 @@ rootAccess.securityPolicy = function (pid, proc, perm, req)
end)
end
while true do
local ev = {coroutine.yield()}
function theEventHandler(...)
local ev = {...}
if ev[1] == "k.procdie" then
local _, pkg, pid, reason = table.unpack(ev)
if targsDH[pid] then
@ -294,11 +328,11 @@ while true do
end
end
elseif ev[1] == "k.registration" then
if ev[2] == "x.neo.pub.window" then
local nt = onEverest
onEverest = {}
for _, v in ipairs(nt) do
coroutine.resume(v, neo.requestAccess("x.neo.pub.window"))
if onReg[ev[2]] then
local tmp = onReg[ev[2]]
onReg[ev[2]] = nil
for _, v in ipairs(tmp) do
v()
end
end
elseif ev[1] == "x.neo.pub.window" then
@ -311,3 +345,7 @@ while true do
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"
},
},
["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
directly, called the "tag".
The resulting event:
"k.timer", tag, time, ofs
"k.timer", tag, time
These events are ONLY EVER sent as
a consequence of this function,
and this can be relied on safely.

View File

@ -47,6 +47,10 @@ Main functions:
neoux.create(w, h, title, callback):
Creates a window,
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
with the window "reset" function,
and it is intended that you use
@ -156,6 +160,10 @@ UI framework window API (TODO):
height. Like in the API this wraps,
this is guaranteed to refresh all
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
in us-evrst for details.

View File

@ -17,6 +17,10 @@ The API gives you a function:
(w, h, title) -> 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:
@ -25,6 +29,10 @@ Window fields:
the window, and sends the line
events (even if the size doesn't
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
screen the window is on.
span(x, y, text, bg, fg): Draws a