From aea262bfc480c11865a027e911f8a8d3165a48fc Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Wed, 21 Mar 2018 03:07:16 +0000 Subject: [PATCH] lualoader: Add primitive hook module, use it to untangle bogus reference See: comments in the hook module about intended usage, as well as the introduced use for config.reloaded. Use the newly introduced hook module to define a "config.reloaded" hook. This is currently used to register core's clearKernelCache as a reload hook to avoid a circular dependency and fix this functionality- it didn't actually work out, and it isn't immediately obvious how it slipped into src. Other hook types will be introduced into the core lualoader as useful hook points are identified. --- stand/lua/Makefile | 1 + stand/lua/config.lua | 5 ++- stand/lua/core.lua | 5 ++- stand/lua/hook.lua | 84 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 stand/lua/hook.lua diff --git a/stand/lua/Makefile b/stand/lua/Makefile index 924a5a0a7f43..3ff75ca7e26c 100644 --- a/stand/lua/Makefile +++ b/stand/lua/Makefile @@ -8,6 +8,7 @@ FILES= cli.lua \ config.lua \ core.lua \ drawer.lua \ + hook.lua \ loader.lua \ menu.lua \ password.lua \ diff --git a/stand/lua/config.lua b/stand/lua/config.lua index f236817f3053..335cf126447e 100644 --- a/stand/lua/config.lua +++ b/stand/lua/config.lua @@ -29,6 +29,8 @@ -- $FreeBSD$ -- +local hook = require("hook") + local config = {} local modules = {} local carousel_choices = {} @@ -503,7 +505,7 @@ function config.reload(file) modules = {} config.restoreEnv() config.load(file) - core.configReloaded() + hook.runAll("config.reloaded") end function config.loadelf() @@ -523,4 +525,5 @@ function config.loadelf() end end +hook.registerType("config.reloaded") return config diff --git a/stand/lua/core.lua b/stand/lua/core.lua index 87146590cd79..d38822deab5f 100644 --- a/stand/lua/core.lua +++ b/stand/lua/core.lua @@ -30,6 +30,7 @@ -- local config = require("config") +local hook = require("hook") local core = {} @@ -138,7 +139,7 @@ function core.setSafeMode(safe_mode) core.sm = safe_mode end -function core.configReloaded() +function core.clearCachedKernels() -- Clear the kernel cache on config changes, autodetect might have -- changed or if we've switched boot environments then we could have -- a new kernel set. @@ -364,4 +365,6 @@ end if core.isSystem386() and core.getACPIPresent(false) then core.setACPI(true) end + +hook.register("config.reloaded", core.clearCachedKernels) return core diff --git a/stand/lua/hook.lua b/stand/lua/hook.lua new file mode 100644 index 000000000000..2c1b1ffc64fb --- /dev/null +++ b/stand/lua/hook.lua @@ -0,0 +1,84 @@ +-- +-- SPDX-License-Identifier: BSD-2-Clause-FreeBSD +-- +-- Copyright (c) 2018 Kyle Evans +-- All rights reserved. +-- +-- Redistribution and use in source and binary forms, with or without +-- modification, are permitted provided that the following conditions +-- are met: +-- 1. Redistributions of source code must retain the above copyright +-- notice, this list of conditions and the following disclaimer. +-- 2. Redistributions in binary form must reproduce the above copyright +-- notice, this list of conditions and the following disclaimer in the +-- documentation and/or other materials provided with the distribution. +-- +-- THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +-- ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +-- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +-- ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +-- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +-- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +-- OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +-- HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +-- LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +-- OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +-- SUCH DAMAGE. +-- +-- $FreeBSD$ +-- + +local hook = {} + +local registered_hooks = {} + +-- Module exports +-- Register a hook type; these are the names that hooks may be registered for. +-- It is expected that modules will register all of their hook types upon +-- initial load. Other modules may then, at any time, register a hook for these +-- types. +-- +-- Naming convention: hook types should be sensible named, preferably prefixed +-- with the name of the module that registered them. They would also ideally +-- describe an action that may or may not match a function name. +-- e.g. config.reloaded which takes place after config has been reloaded, +-- possibly from a different source. +function hook.registerType(hooktype) + registered_hooks[hooktype] = {} +end + +function hook.register(hooktype, hookfunc) + local selected_hooks = registered_hooks[hooktype] + if selected_hooks == nil then + print("Tried registering a hook for an unknown hook type: " .. + hooktype) + return + end + selected_hooks[#selected_hooks + 1] = hookfunc + registered_hooks[hooktype] = selected_hooks +end + +-- Takes a hooktype and runs all functions associated with that specific hook +-- type in the order that they were registered in. This ordering should likely +-- not be relied upon. +function hook.runAll(hooktype) + local selected_hooks = registered_hooks[hooktype] + if selected_hooks == nil then + -- This message, and the print() above, should only be seen by + -- developers. Hook type registration should have happened at + -- module load, so if this hasn't happened then we have messed + -- up the order in which we've loaded modules and we need to + -- catch that as soon as possible. + print("Tried to run hooks for an unknown hook type: " .. + hooktype) + return 0 + end + if #selected_hooks > 0 then + for _, func in ipairs(selected_hooks) do + func() + end + end + return #selected_hooks +end + +return hook