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.
cpp
nirenjan 2022-07-27 12:47:53 -07:00
parent dfa78ff2a9
commit b822d3aed8
5 changed files with 249 additions and 184 deletions

View File

@ -11,17 +11,20 @@
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <pthread.h>
#include <poll.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <fcntl.h>
#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;
}
}

View File

@ -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

View File

@ -14,7 +14,6 @@
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#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);

View File

@ -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 <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\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"

View File

@ -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 <nirenjan@gmail.com>\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"