# HG changeset patch # User jbe # Date 1496758473 -7200 # Node ID e09654c4a0420bb6755b24acb9ab798b6492567e # Parent d3e77b8edb2aaf414b661bccccb2794fb6e23d0a Allow main handlers to use a poll function that indicates when process termination is requested diff -r d3e77b8edb2a -r e09654c4a042 framework/bin/mcp.lua --- a/framework/bin/mcp.lua Tue Jun 06 12:08:17 2017 +0200 +++ b/framework/bin/mcp.lua Tue Jun 06 16:14:33 2017 +0200 @@ -281,8 +281,12 @@ try_exec(WEBMCP_BASE_PATH .. "env/__init.lua") end +-- signal socket (to catch SIGTERM in main handlers) +local sigterm_socket + -- define post-fork initialization function (including loading of "multirand" library) local function postfork_init() + sigterm_socket = moonbridge_io.signalsocket("TERM") multirand = require "multirand" execute.postfork_initializers() end @@ -336,7 +340,11 @@ This function must be called in a configuration file (in the config/ directory) or in pre-fork initializers (in the app/_prefork/ or app//_prefork/ directories), unless WebMCP is invoked in interactive mode (in which case any calls of listen{...} are ignored). -This function is a variant of Moonbridge's listen{...} function which has been wrapped for WebMCP. No "prepare", "conenct", or "finish" handler can be set. Instead WebMCP automatically dispatches incoming connections. For interval timers, an interval handler may be specified in each listener. +This function is a variant of Moonbridge's listen{...} function which has been wrapped for WebMCP. No "prepare", "conenct", or "finish" handler can be set. Instead WebMCP automatically dispatches incoming connections. For interval timers and main routines, a handler may be specified in each listener. + +Handlers for main routines (proto = "main") get a poll function passed as first and only parameter. This poll function behaves like moonbridge_io.poll(...) with the exeception that the return value is "terminate", "timeout", or "io" depending whether a termination is requested, a timeout happened, or data is ready for I/O. + +No handler or pre-/postfork initializer should use moonbridge_io.signalsocket(...) directly because this can interfere with signal detection for shutdown. --]]-- -- prepare for interactive or listen mode @@ -385,7 +393,20 @@ args.connect = function(socket) if socket.main then request.initialize() - main_handlers[socket.main]() + local function poll(input_set, output_set, timeout) + local input_set_copy = table.new(input_set) + input_set_copy[sigterm_socket] = true + local timeout = not moonbridge_io.poll(input_set_copy, output_set, timeout) + local terminate = #(assert(sigterm_socket:read_nb())) > 0 + if terminate then + return "terminate" + elseif timeout then + return "timeout" + else + return "io" + end + end + main_handlers[socket.main](poll) io.stderr:write('Main handler "' .. socket.main .. '" terminated. Requesting shutdown.\n') return false elseif socket.interval then