From b822d3aed8d357aa96e70289c73b598ce4d6d291 Mon Sep 17 00:00:00 2001 From: nirenjan Date: Wed, 27 Jul 2022 12:47:53 -0700 Subject: [PATCH] Move command processing into separate thread This will help in moving a lot of the functionality out of the main thread, and limit the main thread to just signal handling. --- daemon/x52d_command.c | 119 +++++++++++++++++++++++++++++++++++++++--- daemon/x52d_command.h | 3 +- daemon/x52d_main.c | 75 ++------------------------ po/libx52.pot | 117 +++++++++++++++++++++++------------------ po/xx_PL.po | 119 +++++++++++++++++++++++------------------- 5 files changed, 249 insertions(+), 184 deletions(-) diff --git a/daemon/x52d_command.c b/daemon/x52d_command.c index fe81c2d..b34cc7e 100644 --- a/daemon/x52d_command.c +++ b/daemon/x52d_command.c @@ -11,17 +11,20 @@ #include #include #include +#include #include #include #include #include #include +#include #define PINELOG_MODULE X52D_MOD_COMMAND #include "pinelog.h" #include "x52d_const.h" #include "x52d_command.h" #include "x52d_config.h" +#include "x52dcomm-internal.h" #define MAX_CONN (X52D_MAX_CLIENTS + 1) @@ -30,14 +33,9 @@ static int client_fd[X52D_MAX_CLIENTS]; static int active_clients; -void x52d_command_init(void) -{ - for (int i = 0; i < X52D_MAX_CLIENTS; i++) { - client_fd[i] = INVALID_CLIENT; - } - - active_clients = 0; -} +static pthread_t command_thr; +static int command_sock_fd; +static const char *command_sock; static void register_client(int sock_fd) { @@ -507,3 +505,108 @@ int x52d_command_loop(int sock_fd) return 0; } + +static void * x52d_command_thread(void *param) +{ + for (;;) { + if (x52d_command_loop(command_sock_fd) < 0) { + PINELOG_FATAL(_("Error %d during command loop: %s"), + errno, strerror(errno)); + } + } + + return NULL; +} + +int x52d_command_init(const char *sock_path) +{ + int sock_fd; + int len; + struct sockaddr_un local; + int flags; + + for (int i = 0; i < X52D_MAX_CLIENTS; i++) { + client_fd[i] = INVALID_CLIENT; + } + + active_clients = 0; + + command_sock = sock_path; + command_sock_fd = -1; + + len = x52d_setup_command_sock(command_sock, &local); + if (len < 0) { + return -1; + } + + sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock_fd < 0) { + /* Failure creating the socket. Abort early */ + PINELOG_ERROR(_("Error creating command socket: %s"), strerror(errno)); + return -1; + } + + /* Mark the socket as non-blocking */ + flags = fcntl(sock_fd, F_GETFL); + if (flags < 0) { + PINELOG_ERROR(_("Error getting command socket flags: %s"), strerror(errno)); + goto sock_failure; + } + if (fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK) < 0) { + PINELOG_ERROR(_("Error setting command socket flags: %s"), strerror(errno)); + goto sock_failure; + } + + /* Cleanup any existing socket */ + unlink(local.sun_path); + if (bind(sock_fd, (struct sockaddr *)&local, (socklen_t)len) < 0) { + /* Failure binding socket */ + PINELOG_ERROR(_("Error binding to command socket: %s"), strerror(errno)); + goto listen_failure; + } + + if (listen(sock_fd, X52D_MAX_CLIENTS) < 0) { + PINELOG_ERROR(_("Error listening on command socket: %s"), strerror(errno)); + goto listen_failure; + } + + command_sock_fd = sock_fd; + if (command_sock_fd < 0) { + command_sock_fd = -1; + goto listen_failure; + } + + PINELOG_INFO(_("Starting command processing thread")); + pthread_create(&command_thr, NULL, x52d_command_thread, NULL); + + return 0; + +listen_failure: + unlink(local.sun_path); +sock_failure: + if (command_sock_fd >= 0) { + close(command_sock_fd); + command_sock_fd = -1; + } + + return -1; +} + +void x52d_command_exit(void) +{ + PINELOG_INFO(_("Shutting down command processing thread")); + pthread_cancel(command_thr); + + // Close the socket and remove the socket file + if (command_sock_fd >= 0) { + command_sock = x52d_command_sock_path(command_sock); + PINELOG_TRACE("Closing command socket %s", command_sock); + + close(command_sock_fd); + command_sock_fd = -1; + + unlink(command_sock); + command_sock = NULL; + } + +} diff --git a/daemon/x52d_command.h b/daemon/x52d_command.h index 96513a2..b2bc041 100644 --- a/daemon/x52d_command.h +++ b/daemon/x52d_command.h @@ -9,7 +9,8 @@ #ifndef X52D_COMMAND_H #define X52D_COMMAND_H -void x52d_command_init(void); +int x52d_command_init(const char *sock_path); +void x52d_command_exit(void); int x52d_command_loop(int sock_fd); #endif // !defined X52D_COMMAND_H diff --git a/daemon/x52d_main.c b/daemon/x52d_main.c index 497d721..ec543ae 100644 --- a/daemon/x52d_main.c +++ b/daemon/x52d_main.c @@ -14,7 +14,6 @@ #include #include #include -#include #include #include "x52d_clock.h" @@ -197,59 +196,6 @@ static void start_daemon(bool foreground, const char *pid_file) } } -/* Bind and listen to the command socket */ -static int listen_command(const char *command_sock) -{ - int sock_fd; - int len; - struct sockaddr_un local; - int flags; - - len = x52d_setup_command_sock(command_sock, &local); - if (len < 0) { - return -1; - } - - sock_fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock_fd < 0) { - /* Failure creating the socket. Abort early */ - PINELOG_ERROR(_("Error creating command socket: %s"), strerror(errno)); - return -1; - } - - /* Mark the socket as non-blocking */ - flags = fcntl(sock_fd, F_GETFL); - if (flags < 0) { - PINELOG_ERROR(_("Error getting command socket flags: %s"), strerror(errno)); - goto sock_failure; - } - if (fcntl(sock_fd, F_SETFL, flags | O_NONBLOCK) < 0) { - PINELOG_ERROR(_("Error setting command socket flags: %s"), strerror(errno)); - goto sock_failure; - } - - /* Cleanup any existing socket */ - unlink(local.sun_path); - if (bind(sock_fd, (struct sockaddr *)&local, (socklen_t)len) < 0) { - /* Failure binding socket */ - PINELOG_ERROR(_("Error binding to command socket: %s"), strerror(errno)); - goto listen_failure; - } - - if (listen(sock_fd, X52D_MAX_CLIENTS) < 0) { - PINELOG_ERROR(_("Error listening on command socket: %s"), strerror(errno)); - goto listen_failure; - } - - return sock_fd; - -listen_failure: - unlink(local.sun_path); -sock_failure: - close(sock_fd); - return -1; -} - int main(int argc, char **argv) { int verbosity = 0; @@ -260,7 +206,6 @@ int main(int argc, char **argv) const char *pid_file = NULL; const char *command_sock = NULL; int opt; - int command_sock_fd; int rc; sigset_t sigblockset; @@ -366,7 +311,9 @@ int main(int argc, char **argv) // Start device threads x52d_dev_init(); x52d_clock_init(); - x52d_command_init(); + if (x52d_command_init(command_sock) < 0) { + goto cleanup; + } #if defined(HAVE_EVDEV) x52d_io_init(); x52d_mouse_evdev_init(); @@ -379,17 +326,12 @@ int main(int argc, char **argv) errno, strerror(errno)); } - command_sock_fd = listen_command(command_sock); - if (command_sock_fd < 0) { - goto cleanup; - } - // Apply configuration x52d_config_apply(); flag_quit = 0; while(!flag_quit) { - x52d_command_loop(command_sock_fd); + pause(); /* Check if we need to reload configuration */ if (flag_reload) { @@ -412,19 +354,12 @@ cleanup: // Stop device threads x52d_clock_exit(); x52d_dev_exit(); + x52d_command_exit(); #if defined(HAVE_EVDEV) x52d_mouse_evdev_exit(); x52d_io_exit(); #endif - // Close the socket and remove the socket file - if (command_sock_fd >= 0) { - command_sock = x52d_command_sock_path(command_sock); - PINELOG_TRACE("Closing command socket %s", command_sock); - close(command_sock_fd); - unlink(command_sock); - } - // Remove the PID file PINELOG_TRACE("Removing PID file %s", pid_file); unlink(pid_file); diff --git a/po/libx52.pot b/po/libx52.pot index 2b280c2..a50f243 100644 --- a/po/libx52.pot +++ b/po/libx52.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: libx52 0.2.3\n" "Report-Msgid-Bugs-To: https://github.com/nirenjan/libx52/issues\n" -"POT-Creation-Date: 2022-07-27 11:30-0700\n" +"POT-Creation-Date: 2022-07-27 12:45-0700\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -493,17 +493,17 @@ msgstr "" msgid "OK" msgstr "" -#: daemon/x52d_main.c:64 +#: daemon/x52d_main.c:63 #, c-format msgid "Error %d setting log file: %s\n" msgstr "" -#: daemon/x52d_main.c:80 +#: daemon/x52d_main.c:79 #, c-format msgid "Error %d installing handler for signal %d: %s" msgstr "" -#: daemon/x52d_main.c:91 +#: daemon/x52d_main.c:90 #, c-format msgid "" "Usage: %s [-f] [-v] [-q]\n" @@ -512,108 +512,83 @@ msgid "" "\t[-s command-socket-path]\n" msgstr "" -#: daemon/x52d_main.c:123 +#: daemon/x52d_main.c:122 #, c-format msgid "Daemon is already running as PID %u" msgstr "" -#: daemon/x52d_main.c:216 -#, c-format -msgid "Error creating command socket: %s" -msgstr "" - -#: daemon/x52d_main.c:223 -#, c-format -msgid "Error getting command socket flags: %s" -msgstr "" - -#: daemon/x52d_main.c:227 -#, c-format -msgid "Error setting command socket flags: %s" -msgstr "" - -#: daemon/x52d_main.c:235 -#, c-format -msgid "Error binding to command socket: %s" -msgstr "" - -#: daemon/x52d_main.c:240 -#, c-format -msgid "Error listening on command socket: %s" -msgstr "" - -#: daemon/x52d_main.c:317 +#: daemon/x52d_main.c:262 #, c-format msgid "Unable to parse configuration override '%s'\n" msgstr "" -#: daemon/x52d_main.c:345 +#: daemon/x52d_main.c:290 #, c-format msgid "Foreground = %s" msgstr "" -#: daemon/x52d_main.c:345 daemon/x52d_main.c:346 +#: daemon/x52d_main.c:290 daemon/x52d_main.c:291 msgid "true" msgstr "" -#: daemon/x52d_main.c:345 daemon/x52d_main.c:346 +#: daemon/x52d_main.c:290 daemon/x52d_main.c:291 msgid "false" msgstr "" -#: daemon/x52d_main.c:346 +#: daemon/x52d_main.c:291 #, c-format msgid "Quiet = %s" msgstr "" -#: daemon/x52d_main.c:347 +#: daemon/x52d_main.c:292 #, c-format msgid "Verbosity = %d" msgstr "" -#: daemon/x52d_main.c:348 +#: daemon/x52d_main.c:293 #, c-format msgid "Log file = %s" msgstr "" -#: daemon/x52d_main.c:349 +#: daemon/x52d_main.c:294 #, c-format msgid "Config file = %s" msgstr "" -#: daemon/x52d_main.c:350 +#: daemon/x52d_main.c:295 #, c-format msgid "PID file = %s" msgstr "" -#: daemon/x52d_main.c:351 +#: daemon/x52d_main.c:296 #, c-format msgid "Command socket = %s" msgstr "" -#: daemon/x52d_main.c:362 +#: daemon/x52d_main.c:307 #, c-format msgid "Error %d blocking signals on child threads: %s" msgstr "" -#: daemon/x52d_main.c:378 +#: daemon/x52d_main.c:325 #, c-format msgid "Error %d unblocking signals on child threads: %s" msgstr "" -#: daemon/x52d_main.c:396 +#: daemon/x52d_main.c:338 msgid "Reloading X52 configuration" msgstr "" -#: daemon/x52d_main.c:403 +#: daemon/x52d_main.c:345 msgid "Saving X52 configuration to disk" msgstr "" -#: daemon/x52d_main.c:409 +#: daemon/x52d_main.c:351 #, c-format msgid "Received termination signal %s" msgstr "" -#: daemon/x52d_main.c:432 +#: daemon/x52d_main.c:367 msgid "Shutting down X52 daemon" msgstr "" @@ -671,35 +646,73 @@ msgstr "" msgid "Shutting down X52 clock manager thread" msgstr "" -#: daemon/x52d_command.c:53 +#: daemon/x52d_command.c:51 #, c-format msgid "Error accepting client connection on command socket: %s" msgstr "" -#: daemon/x52d_command.c:90 +#: daemon/x52d_command.c:88 #, c-format msgid "Error when polling command socket: FD %d, error %d, len %lu" msgstr "" -#: daemon/x52d_command.c:117 +#: daemon/x52d_command.c:115 #, c-format msgid "Error when polling for command: %s" msgstr "" -#: daemon/x52d_command.c:121 +#: daemon/x52d_command.c:119 msgid "Timed out when polling for command" msgstr "" -#: daemon/x52d_command.c:490 +#: daemon/x52d_command.c:488 #, c-format msgid "Error reading from client %d: %s" msgstr "" -#: daemon/x52d_command.c:501 +#: daemon/x52d_command.c:499 #, c-format msgid "Short write to client %d; expected %d bytes, wrote %d bytes" msgstr "" +#: daemon/x52d_command.c:513 +#, c-format +msgid "Error %d during command loop: %s" +msgstr "" + +#: daemon/x52d_command.c:545 +#, c-format +msgid "Error creating command socket: %s" +msgstr "" + +#: daemon/x52d_command.c:552 +#, c-format +msgid "Error getting command socket flags: %s" +msgstr "" + +#: daemon/x52d_command.c:556 +#, c-format +msgid "Error setting command socket flags: %s" +msgstr "" + +#: daemon/x52d_command.c:564 +#, c-format +msgid "Error binding to command socket: %s" +msgstr "" + +#: daemon/x52d_command.c:569 +#, c-format +msgid "Error listening on command socket: %s" +msgstr "" + +#: daemon/x52d_command.c:579 +msgid "Starting command processing thread" +msgstr "" + +#: daemon/x52d_command.c:597 +msgid "Shutting down command processing thread" +msgstr "" + #: daemon/x52d_config.c:29 #, c-format msgid "Error %d setting configuration defaults: %s" diff --git a/po/xx_PL.po b/po/xx_PL.po index f44b628..36b5fba 100644 --- a/po/xx_PL.po +++ b/po/xx_PL.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: libx52 0.2.3\n" "Report-Msgid-Bugs-To: https://github.com/nirenjan/libx52/issues\n" -"POT-Creation-Date: 2022-07-27 11:30-0700\n" -"PO-Revision-Date: 2022-07-27 11:32-0700\n" +"POT-Creation-Date: 2022-07-27 12:45-0700\n" +"PO-Revision-Date: 2022-07-27 12:45-0700\n" "Last-Translator: Nirenjan Krishnan \n" "Language-Team: Dummy Language for testing i18n\n" "Language: xx_PL\n" @@ -536,17 +536,17 @@ msgstr "Estingtay aracterchay 0x%02x..." msgid "OK" msgstr "OKay" -#: daemon/x52d_main.c:64 +#: daemon/x52d_main.c:63 #, c-format msgid "Error %d setting log file: %s\n" msgstr "Erroray %d ettingsay oglay ilefay: %s\n" -#: daemon/x52d_main.c:80 +#: daemon/x52d_main.c:79 #, c-format msgid "Error %d installing handler for signal %d: %s" msgstr "Erroray %d installingay andlerhay orfay ignalsay %d: %s" -#: daemon/x52d_main.c:91 +#: daemon/x52d_main.c:90 #, c-format msgid "" "Usage: %s [-f] [-v] [-q]\n" @@ -559,108 +559,83 @@ msgstr "" "\t[-c onfigcay-ilefay] [-p idpay-ilefay]\n" "\t[-s ommandcay-ocketsay-athpay]\n" -#: daemon/x52d_main.c:123 +#: daemon/x52d_main.c:122 #, c-format msgid "Daemon is already running as PID %u" msgstr "Aemonday isay alreadyay unningray asay IDPay %u" -#: daemon/x52d_main.c:216 -#, c-format -msgid "Error creating command socket: %s" -msgstr "Erroray eatingcray ommandcay ocketsay: %s" - -#: daemon/x52d_main.c:223 -#, c-format -msgid "Error getting command socket flags: %s" -msgstr "Erroray ettinggay ommandcay ocketsay agsflay: %s" - -#: daemon/x52d_main.c:227 -#, c-format -msgid "Error setting command socket flags: %s" -msgstr "Erroray ettingsay ommandcay ocketsay agsflay: %s" - -#: daemon/x52d_main.c:235 -#, c-format -msgid "Error binding to command socket: %s" -msgstr "Erroray indingbay otay ommandcay ocketsay: %s" - -#: daemon/x52d_main.c:240 -#, c-format -msgid "Error listening on command socket: %s" -msgstr "Erroray isteninglay onay ommandcay ocketsay: %s" - -#: daemon/x52d_main.c:317 +#: daemon/x52d_main.c:262 #, c-format msgid "Unable to parse configuration override '%s'\n" msgstr "Unableay otay arsepay onfigurationcay overrideay '%s'\n" -#: daemon/x52d_main.c:345 +#: daemon/x52d_main.c:290 #, c-format msgid "Foreground = %s" msgstr "Oregroundfay = %s" -#: daemon/x52d_main.c:345 daemon/x52d_main.c:346 +#: daemon/x52d_main.c:290 daemon/x52d_main.c:291 msgid "true" msgstr "uetray" -#: daemon/x52d_main.c:345 daemon/x52d_main.c:346 +#: daemon/x52d_main.c:290 daemon/x52d_main.c:291 msgid "false" msgstr "alsefay" -#: daemon/x52d_main.c:346 +#: daemon/x52d_main.c:291 #, c-format msgid "Quiet = %s" msgstr "Uietqay = %s" -#: daemon/x52d_main.c:347 +#: daemon/x52d_main.c:292 #, c-format msgid "Verbosity = %d" msgstr "Erbosityvay = %d" -#: daemon/x52d_main.c:348 +#: daemon/x52d_main.c:293 #, c-format msgid "Log file = %s" msgstr "Oglay ilefay = %s" -#: daemon/x52d_main.c:349 +#: daemon/x52d_main.c:294 #, c-format msgid "Config file = %s" msgstr "Onfigcay ilefay = %s" -#: daemon/x52d_main.c:350 +#: daemon/x52d_main.c:295 #, c-format msgid "PID file = %s" msgstr "IDPay ilefay = %s" -#: daemon/x52d_main.c:351 +#: daemon/x52d_main.c:296 #, c-format msgid "Command socket = %s" msgstr "Ommandcay ocketsay = %s" -#: daemon/x52d_main.c:362 +#: daemon/x52d_main.c:307 #, c-format msgid "Error %d blocking signals on child threads: %s" msgstr "Erroray %d ockingblay ignalssay onay ildchay eadsthray: %s" -#: daemon/x52d_main.c:378 +#: daemon/x52d_main.c:325 #, c-format msgid "Error %d unblocking signals on child threads: %s" msgstr "Erroray %d unblockingay ignalssay onay ildchay eadsthray: %s" -#: daemon/x52d_main.c:396 +#: daemon/x52d_main.c:338 msgid "Reloading X52 configuration" msgstr "Eloadingray X52 onfigurationcay" -#: daemon/x52d_main.c:403 +#: daemon/x52d_main.c:345 msgid "Saving X52 configuration to disk" msgstr "Avingsay X52 onfigurationcay otay iskday" -#: daemon/x52d_main.c:409 +#: daemon/x52d_main.c:351 #, c-format msgid "Received termination signal %s" msgstr "Eceivedray erminationtay ignalsay %s" -#: daemon/x52d_main.c:432 +#: daemon/x52d_main.c:367 msgid "Shutting down X52 daemon" msgstr "Uttingshay ownday X52 aemonday" @@ -721,37 +696,75 @@ msgstr "Erroray %d initializingay ockclay eadthray: %s" msgid "Shutting down X52 clock manager thread" msgstr "Uttingshay ownday X52 ockclay anagermay eadthray" -#: daemon/x52d_command.c:53 +#: daemon/x52d_command.c:51 #, c-format msgid "Error accepting client connection on command socket: %s" msgstr "Erroray acceptingay ientclay onnectioncay onay ommandcay ocketsay: %s" -#: daemon/x52d_command.c:90 +#: daemon/x52d_command.c:88 #, c-format msgid "Error when polling command socket: FD %d, error %d, len %lu" msgstr "" "Erroray enwhay ollingpay ommandcay ocketsay: FDay %d, erroray %d, enlay %lu" -#: daemon/x52d_command.c:117 +#: daemon/x52d_command.c:115 #, c-format msgid "Error when polling for command: %s" msgstr "Erroray enwhay ollingpay orfay ommandcay: %s" -#: daemon/x52d_command.c:121 +#: daemon/x52d_command.c:119 msgid "Timed out when polling for command" msgstr "Imedtay outay enwhay ollingpay orfay ommandcay" -#: daemon/x52d_command.c:490 +#: daemon/x52d_command.c:488 #, c-format msgid "Error reading from client %d: %s" msgstr "Erroray eadingray omfray ientclay %d: %s" -#: daemon/x52d_command.c:501 +#: daemon/x52d_command.c:499 #, c-format msgid "Short write to client %d; expected %d bytes, wrote %d bytes" msgstr "" "Ortshay itewray otay ientclay %d; expecteday %d ytesbay, otewray %d ytesbay" +#: daemon/x52d_command.c:513 +#, c-format +msgid "Error %d during command loop: %s" +msgstr "Erroray %d uringday ommandcay ooplay: %s" + +#: daemon/x52d_command.c:545 +#, c-format +msgid "Error creating command socket: %s" +msgstr "Erroray eatingcray ommandcay ocketsay: %s" + +#: daemon/x52d_command.c:552 +#, c-format +msgid "Error getting command socket flags: %s" +msgstr "Erroray ettinggay ommandcay ocketsay agsflay: %s" + +#: daemon/x52d_command.c:556 +#, c-format +msgid "Error setting command socket flags: %s" +msgstr "Erroray ettingsay ommandcay ocketsay agsflay: %s" + +#: daemon/x52d_command.c:564 +#, c-format +msgid "Error binding to command socket: %s" +msgstr "Erroray indingbay otay ommandcay ocketsay: %s" + +#: daemon/x52d_command.c:569 +#, c-format +msgid "Error listening on command socket: %s" +msgstr "Erroray isteninglay onay ommandcay ocketsay: %s" + +#: daemon/x52d_command.c:579 +msgid "Starting command processing thread" +msgstr "Artingstay ommandcay ocessingpray eadthray" + +#: daemon/x52d_command.c:597 +msgid "Shutting down command processing thread" +msgstr "Uttingshay ownday ommandcay ocessingpray eadthray" + #: daemon/x52d_config.c:29 #, c-format msgid "Error %d setting configuration defaults: %s"