From 228f7846fcfab6d8e16e4a2d4cba767367648449 Mon Sep 17 00:00:00 2001 From: findstr Date: Wed, 10 Jul 2024 17:00:02 +0800 Subject: [PATCH] add signal support --- Makefile | 1 + lualib-src/lualib-core.c | 19 ++++++++++ lualib-src/lualib-logger.c | 9 +++++ lualib/core.lua | 77 +++++++++++++++++++++++++++++++++++--- lualib/core/logger.lua | 26 +++++++++---- silly-src/main.c | 6 +-- silly-src/silly.h | 17 ++++++--- silly-src/silly_daemon.c | 23 ------------ silly-src/silly_daemon.h | 1 - silly-src/silly_log.c | 27 ++++++++++++- silly-src/silly_log.h | 2 + silly-src/silly_run.c | 26 +------------ silly-src/silly_signal.c | 44 ++++++++++++++++++++++ silly-src/silly_signal.h | 8 ++++ silly-src/silly_worker.c | 2 +- 15 files changed, 216 insertions(+), 72 deletions(-) create mode 100644 silly-src/silly_signal.c create mode 100644 silly-src/silly_signal.h diff --git a/Makefile b/Makefile index 88d7202c..4793117c 100644 --- a/Makefile +++ b/Makefile @@ -63,6 +63,7 @@ SRC_FILE = \ silly_queue.c \ silly_worker.c \ silly_timer.c \ + silly_signal.c \ silly_run.c \ silly_daemon.c \ silly_malloc.c \ diff --git a/lualib-src/lualib-core.c b/lualib-src/lualib-core.c index e594189e..9b438d69 100644 --- a/lualib-src/lualib-core.c +++ b/lualib-src/lualib-core.c @@ -19,6 +19,7 @@ #include "silly_socket.h" #include "silly_malloc.h" #include "silly_timer.h" +#include "silly_signal.h" static void dispatch(lua_State *L, struct silly_message *sm) @@ -74,6 +75,10 @@ dispatch(lua_State *L, struct silly_message *sm) lua_pushinteger(L, tosocket(sm)->ud); args += 3; break; + case SILLY_SIGNAL: + lua_pushinteger(L, tosignal(sm)->signum); + args += 1; + break; default: silly_log_error("[silly.core] callback unknow message type:%d\n", sm->type); @@ -177,6 +182,19 @@ ltimercancel(lua_State *L) return 1; } +static int +lsignal(lua_State *L) +{ + int signum = luaL_checkinteger(L, 1); + int err = silly_signal_watch(signum); + if (err != 0) { + lua_pushstring(L, strerror(err)); + } else { + lua_pushnil(L); + } + return 1; +} + //socket struct multicasthdr { uint32_t ref; @@ -509,6 +527,7 @@ luaopen_core_c(lua_State *L) {"dispatch", ldispatch}, {"timeout", ltimeout}, {"timercancel", ltimercancel}, + {"signal", lsignal}, {"genid", lgenid}, {"tostring", ltostring}, {"getpid", lgetpid}, diff --git a/lualib-src/lualib-logger.c b/lualib-src/lualib-logger.c index b369f1a7..f7d21d24 100644 --- a/lualib-src/lualib-logger.c +++ b/lualib-src/lualib-logger.c @@ -185,6 +185,14 @@ llog(lua_State *L, enum silly_log_level log_level) return 0; } +static int +lopenfile(lua_State *L) +{ + const char *path = luaL_checkstring(L, 1); + silly_log_openfile(path); + return 0; +} + static int lgetlevel(lua_State *L) { @@ -229,6 +237,7 @@ int luaopen_core_logger_c(lua_State *L) { luaL_Reg tbl[] = { + {"openfile", lopenfile}, {"getlevel", lgetlevel}, {"setlevel", lsetlevel}, {"debug", ldebug}, diff --git a/lualib/core.lua b/lualib/core.lua index 4bce4028..14fef8e6 100644 --- a/lualib/core.lua +++ b/lualib/core.lua @@ -1,5 +1,5 @@ local c = require "core.c" -local logger = require "core.logger" +local logger = require "core.logger.c" local core = {} local type = type @@ -7,9 +7,7 @@ local pairs = pairs local assert = assert local xpcall = xpcall local tostring = tostring -local tonumber = tonumber local smatch = string.match -local sformat = string.format local tremove = table.remove local tpack = table.pack local tunpack = table.unpack @@ -22,12 +20,10 @@ local log_error = assert(logger.error) local readctrl = assert(c.readctrl) local trace_new = assert(c.trace_new) local trace_set = assert(c.trace_set) -local trace_get = assert(c.trace_get) local trace_span = assert(c.trace_span) core.pid = c.getpid() core.genid = c.genid -core.getpid = c.getpid core.gitsha1 = c.gitsha1() core.version = c.version() core.tostring = c.tostring @@ -37,6 +33,52 @@ core.socket_read_ctrl = function (sid, ctrl) return readctrl(sid, ctrl == "enable") end +--signal +local signal = c.signal +local signal_dispatch = {} +local signal_map = {} +do + local sig_list = { + SIGINT = 2, -- Interactive attention signal. + SIGILL = 4, -- Illegal instruction. + SIGABRT = 6, -- Abnormal termination. + SIGFPE = 8, -- Erroneous arithmetic operation. + SIGSEGV = 11, -- Invalid access to storage. + SIGTERM = 15, -- Termination request. + + --Historical signals specified by POSIX. + SIGHUP = 1, -- Hangup. + SIGQUIT = 3, -- Quit. + SIGTRAP = 5, -- Trace/breakpoint trap. + SIGKILL = 9, -- Killed. + SIGBUS = 10, -- Bus error. + SIGSYS = 12, -- Bad system call. + SIGPIPE = 13, -- Broken pipe. + SIGALRM = 14, -- Alarm clock. + + --New(er) POSIX signals (1003.1-2008, 1003.1-2013). + + SIGURG = 16, -- Urgent data is available at a socket. + SIGSTOP = 17, -- Stop, unblockable. + SIGTSTP = 18, -- Keyboard stop. + SIGCONT = 19, -- Continue. + SIGCHLD = 20, -- Child terminated or stopped. + SIGTTIN = 21, -- Background read from control terminal. + SIGTTOU = 22, -- Background write to control terminal. + SIGPOLL = 23, -- Pollable event occurred (System V). + SIGXCPU = 24, -- CPU time limit exceeded. + SIGXFSZ = 25, -- File size limit exceeded. + SIGVTALRM = 26, -- Virtual timer expired. + SIGPROF = 27, -- Profiling timer expired. + SIGUSR1 = 30, -- User-defined signal 1. + SIGUSR2 = 31, -- User-defined signal 2. + } + for k, v in pairs(sig_list) do + signal_map[k] = v + signal_map[v] = k + end +end + --coroutine --state migrate(RUN (WAIT->READY)/SLEEP RUN) local task_status = setmetatable({}, weakmt) @@ -260,6 +302,15 @@ function core.timercancel(session) end end +function core.signal(sig, f) + local s = assert(signal_map[sig], sig) + local err = signal(s) + assert(not err, err) + local old = signal_dispatch[s] + signal_dispatch[s] = f + return old +end + function core.start(func) local t = task_create(func) task_resume(t) @@ -448,7 +499,17 @@ end, else log_info("[sys.core] SILLY_UDP fd:", fd, "closed") end -end +end, +[7] = function(signum) --SILLY_ERROR = 7 + local fn = signal_dispatch[signum] + if fn then + local t = task_create(fn) + task_resume(t, signal_map[signum]) + return + end + log_info("[sys.core] signal", signum, "received") + core.exit(0) +end, } --fd, message, portid/errno, addr @@ -460,5 +521,9 @@ end c.dispatch(dispatch) +core.signal("SIGINT", function(_) + core.exit(0) +end) + return core diff --git a/lualib/core/logger.lua b/lualib/core/logger.lua index a6e0c2c9..9225520d 100644 --- a/lualib/core/logger.lua +++ b/lualib/core/logger.lua @@ -1,4 +1,10 @@ +local core = require "core" +local env = require "core.env" local c = require "core.logger.c" + +local function nop() +end + local logger = { --const from silly_log.h DEBUG = 0, @@ -8,10 +14,10 @@ local logger = { --logger function export getlevel = c.getlevel, setlevel = nil, - debug = nil, - info = nil, - warn = nil, - error = nil, + debug = nop, + info = nop, + warn = nop, + error = nop, } local func_level = { @@ -21,10 +27,6 @@ local func_level = { error = logger.ERROR, } -local function nop() -end - - local function refresh(visiable_level) for name, level in pairs(func_level) do if level >= visiable_level then @@ -43,4 +45,12 @@ function logger.setlevel(level) c.setlevel(level) end +core.signal("SIGUSR1", function(_) + local path = env.get("logpath") + if not path then + return + end + c.openfile(path) +end) + return logger diff --git a/silly-src/main.c b/silly-src/main.c index ec86d60d..e3c05e93 100644 --- a/silly-src/main.c +++ b/silly-src/main.c @@ -153,11 +153,11 @@ int main(int argc, char *argv[]) print_help(config.selfname); return -1; } - silly_trace_init(); - silly_log_init(); - silly_timer_init(); strncpy(config.bootstrap, argv[1], ARRAY_SIZE(config.bootstrap) - 1); parse_args(&config, argc, argv); + silly_trace_init(); + silly_log_init(&config); + silly_timer_init(); status = silly_run(&config); silly_log_info("%s exit, leak memory size:%zu\n", argv[0], silly_memused()); diff --git a/silly-src/silly.h b/silly-src/silly.h index cd6ad06c..f5be34a5 100644 --- a/silly-src/silly.h +++ b/silly-src/silly.h @@ -26,6 +26,7 @@ #define tocommon(msg) ((struct silly_message *)(msg)) #define totexpire(msg) ((struct silly_message_texpire *)(msg)) #define tosocket(msg) ((struct silly_message_socket *)(msg)) +#define tosignal(msg) ((struct silly_message_signal *)(msg)) #define COMMONFIELD struct silly_message *next; enum silly_message_type type; @@ -47,12 +48,13 @@ struct silly_config { enum silly_message_type { - SILLY_TEXPIRE = 1, + SILLY_TEXPIRE = 1, //timer expire SILLY_SACCEPT = 2, //new connetiong - SILLY_SCLOSE, //close from client - SILLY_SCONNECTED, //async connect result - SILLY_SDATA, //data packet(raw) from client - SILLY_SUDP, //data packet(raw) from client(udp) + SILLY_SCLOSE = 3, //close from client + SILLY_SCONNECTED = 4, //async connect result + SILLY_SDATA = 5, //data packet(raw) from client + SILLY_SUDP = 6, //data packet(raw) from client(udp) + SILLY_SIGNAL = 7, //signal }; struct silly_message { @@ -75,6 +77,11 @@ struct silly_message_socket { //socket accept uint8_t *data; }; +struct silly_message_signal { //signal + COMMONFIELD + int signum; +}; + static inline void silly_message_free(struct silly_message *msg) { diff --git a/silly-src/silly_daemon.c b/silly-src/silly_daemon.c index 98f57315..e90a401d 100644 --- a/silly-src/silly_daemon.c +++ b/silly-src/silly_daemon.c @@ -64,21 +64,6 @@ pidfile_delete(const struct silly_config *conf) return ; } -static inline void -logfileopen(const struct silly_config *conf) -{ - int fd; - fd = open(conf->logpath, O_CREAT | O_WRONLY | O_APPEND, 00666); - if (fd >= 0) { - dup2(fd, 1); - dup2(fd, 2); - close(fd); - setvbuf(stdout, NULL, _IOFBF, LOG_BUF_SIZE); - setvbuf(stderr, NULL, _IOLBF, LOG_BUF_SIZE); - - } -} - void silly_daemon_start(const struct silly_config *conf) { @@ -93,14 +78,6 @@ silly_daemon_start(const struct silly_config *conf) exit(0); } pidfile_write(); - logfileopen(conf); - return ; -} - -void -silly_daemon_sigusr1(const struct silly_config *conf) -{ - logfileopen(conf); return ; } diff --git a/silly-src/silly_daemon.h b/silly-src/silly_daemon.h index 69c157fb..3dbff4ba 100644 --- a/silly-src/silly_daemon.h +++ b/silly-src/silly_daemon.h @@ -2,7 +2,6 @@ #define _SILLY_DAEMON_H void silly_daemon_start(const struct silly_config *conf); -void silly_daemon_sigusr1(const struct silly_config *conf); void silly_daemon_stop(const struct silly_config *conf); diff --git a/silly-src/silly_log.c b/silly-src/silly_log.c index 7dd13edf..98adc535 100644 --- a/silly-src/silly_log.c +++ b/silly-src/silly_log.c @@ -2,14 +2,18 @@ #include #include #include +#include #include #include +#include + #include "silly.h" #include "compiler.h" #include "silly_timer.h" #include "silly_trace.h" #include "silly_log.h" +static int is_daemon = 0; static enum silly_log_level log_level; static __thread struct { char buf[64]; @@ -44,9 +48,30 @@ static char hex[] = { }; void -silly_log_init() +silly_log_openfile(const char *path) +{ + int fd; + if (!is_daemon) { + return; + } + fd = open(path, O_CREAT | O_WRONLY | O_APPEND, 00666); + if (fd >= 0) { + dup2(fd, 1); + dup2(fd, 2); + close(fd); + setvbuf(stdout, NULL, _IOFBF, LOG_BUF_SIZE); + setvbuf(stderr, NULL, _IOLBF, LOG_BUF_SIZE); + + } +} + + +void +silly_log_init(const struct silly_config *config) { log_level = SILLY_LOG_INFO; + is_daemon = config->daemon; + silly_log_openfile(config->logpath); return ; } diff --git a/silly-src/silly_log.h b/silly-src/silly_log.h index 3374ed9a..b56d488d 100644 --- a/silly-src/silly_log.h +++ b/silly-src/silly_log.h @@ -1,6 +1,7 @@ #ifndef _SILLY_LOG_H #define _SILLY_LOG_H +struct silly_config; enum silly_log_level { SILLY_LOG_DEBUG = 0, @@ -10,6 +11,7 @@ enum silly_log_level { }; void silly_log_init(); +void silly_log_openfile(const char *path); void silly_log_setlevel(enum silly_log_level level); enum silly_log_level silly_log_getlevel(); void silly_log_head(enum silly_log_level level); diff --git a/silly-src/silly_run.c b/silly-src/silly_run.c index 6ab3ba1d..7fc5862d 100644 --- a/silly-src/silly_run.c +++ b/silly-src/silly_run.c @@ -16,6 +16,7 @@ #include "silly_socket.h" #include "silly_worker.h" #include "silly_monitor.h" +#include "silly_signal.h" #include "silly_daemon.h" #include "silly_run.h" @@ -134,29 +135,6 @@ thread_create(pthread_t *tid, void *(*start)(void *), void *arg, int cpuid) return ; } -static void -signal_term(int sig) -{ - (void)sig; - R.running = 0; -} - -static void -signal_usr1(int sig) -{ - (void)sig; - silly_daemon_sigusr1(R.conf); -} - -static int -signal_init() -{ - signal(SIGPIPE, SIG_IGN); - signal(SIGTERM, signal_term); - signal(SIGINT, signal_term); - signal(SIGUSR1, signal_usr1); - return 0; -} int silly_run(const struct silly_config *config) @@ -170,7 +148,7 @@ silly_run(const struct silly_config *config) pthread_mutex_init(&R.mutex, NULL); pthread_cond_init(&R.cond, NULL); silly_daemon_start(config); - signal_init(); + silly_signal_init(); err = silly_socket_init(); if (unlikely(err < 0)) { silly_log_error("%s socket init fail:%d\n", config->selfname, err); diff --git a/silly-src/silly_signal.c b/silly-src/silly_signal.c new file mode 100644 index 00000000..7376d8b3 --- /dev/null +++ b/silly-src/silly_signal.c @@ -0,0 +1,44 @@ +#include +#include +#include +#include "compiler.h" + +#include "silly.h" +#include "silly_worker.h" +#include "silly_log.h" + +#include "silly_signal.h" + +static int sigbits = 0; + + +static void +signal_handler(int sig) +{ + struct silly_message_signal *ms; + ms = silly_malloc(sizeof(*ms)); + ms->type = SILLY_SIGNAL; + ms->signum = sig; + silly_worker_push(tocommon(ms)); +} + +int +silly_signal_init() +{ + signal(SIGPIPE, SIG_IGN); + return 0; +} + +int +silly_signal_watch(int signum) +{ + if ((sigbits & (1 << signum)) != 0) { + return 0; + } + if (signal(signum, signal_handler) == SIG_ERR) { + silly_log_error("signal %d ignore fail:%s\n", signum, strerror(errno)); + return errno; + } + sigbits |= 1 << signum; + return 0; +} diff --git a/silly-src/silly_signal.h b/silly-src/silly_signal.h new file mode 100644 index 00000000..4fbb7da7 --- /dev/null +++ b/silly-src/silly_signal.h @@ -0,0 +1,8 @@ +#ifndef _SILLY_SIGNAL_H +#define _SILLY_SIGNAL_H + +int silly_signal_init(); +int silly_signal_watch(int signum); + +#endif + diff --git a/silly-src/silly_worker.c b/silly-src/silly_worker.c index 43659da6..eaa30fab 100644 --- a/silly-src/silly_worker.c +++ b/silly-src/silly_worker.c @@ -145,7 +145,7 @@ fetch_core_start(lua_State *L) lua_getglobal(L, "require"); lua_pushstring(L, "core"); if (lua_pcall(L, 1, 1, 0) != LUA_OK) { - silly_log_error("[worker] require sys.core fail,%s\n", + silly_log_error("[worker] require core fail,%s\n", lua_tostring(L, -1)); exit(-1); }