Gracefully shutdown when quiting

This commit is contained in:
Iwan Timmer
2015-05-18 16:34:02 +02:00
parent 08af7f66a2
commit 41a10d7234
3 changed files with 46 additions and 9 deletions

View File

@@ -18,6 +18,7 @@
*/ */
#include "connection.h" #include "connection.h"
#include "global.h"
#include <stdio.h> #include <stdio.h>
@@ -43,6 +44,7 @@ void connection_connection_started()
void connection_connection_terminated() void connection_connection_terminated()
{ {
quit();
printf("connection_connection_terminated\n"); printf("connection_connection_terminated\n");
} }

View File

@@ -19,6 +19,7 @@
#include "keyboard.h" #include "keyboard.h"
#include "mapping.h" #include "mapping.h"
#include "global.h"
#include "libevdev/libevdev.h" #include "libevdev/libevdev.h"
#include "limelight-common/Limelight.h" #include "limelight-common/Limelight.h"
@@ -28,13 +29,16 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
#include <signal.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/signalfd.h>
#include <fcntl.h> #include <fcntl.h>
#include <poll.h> #include <poll.h>
#include <limits.h> #include <limits.h>
#include <unistd.h> #include <unistd.h>
#include <pthread.h>
struct input_abs_parms { struct input_abs_parms {
int min, max; int min, max;
@@ -75,6 +79,8 @@ static struct udev *udev;
static struct udev_monitor *udev_mon; static struct udev_monitor *udev_mon;
static int udev_fdindex; static int udev_fdindex;
static int sig_fdindex;
static void input_init_parms(struct input_device *dev, struct input_abs_parms *parms, int code) { static void input_init_parms(struct input_device *dev, struct input_abs_parms *parms, int code) {
parms->flat = libevdev_get_abs_flat(dev->dev, code); parms->flat = libevdev_get_abs_flat(dev->dev, code);
parms->min = libevdev_get_abs_minimum(dev->dev, code); parms->min = libevdev_get_abs_minimum(dev->dev, code);
@@ -190,8 +196,8 @@ void input_init(char* mapfile) {
udev_monitor_filter_add_match_subsystem_devtype(udev_mon, "input", NULL); udev_monitor_filter_add_match_subsystem_devtype(udev_mon, "input", NULL);
udev_monitor_enable_receiving(udev_mon); udev_monitor_enable_receiving(udev_mon);
int udev_fdindex = numFds; udev_fdindex = numFds++;
numFds++; sig_fdindex = numFds++;
if (fds == NULL) if (fds == NULL)
fds = malloc(sizeof(struct pollfd)); fds = malloc(sizeof(struct pollfd));
@@ -206,6 +212,17 @@ void input_init(char* mapfile) {
defaultMapfile = mapfile; defaultMapfile = mapfile;
fds[udev_fdindex].fd = udev_monitor_get_fd(udev_mon); fds[udev_fdindex].fd = udev_monitor_get_fd(udev_mon);
fds[udev_fdindex].events = POLLIN; fds[udev_fdindex].events = POLLIN;
main_thread_id = pthread_self();
sigset_t sigset;
sigemptyset(&sigset);
sigaddset(&sigset, SIGHUP);
sigaddset(&sigset, SIGTERM);
sigaddset(&sigset, SIGINT);
sigaddset(&sigset, SIGQUIT);
sigprocmask(SIG_BLOCK, &sigset, NULL);
fds[sig_fdindex].fd = signalfd(-1, &sigset, 0);
fds[sig_fdindex].events = POLLIN | POLLERR | POLLHUP;
} }
void input_destroy() { void input_destroy() {
@@ -464,7 +481,7 @@ static void input_drain(void) {
} }
} }
static void input_poll(bool (*handler) (struct input_event*, struct input_device*)) { static bool input_poll(bool (*handler) (struct input_event*, struct input_device*)) {
while (poll(fds, numFds, -1)) { while (poll(fds, numFds, -1)) {
if (fds[udev_fdindex].revents > 0) { if (fds[udev_fdindex].revents > 0) {
struct udev_device *dev = udev_monitor_receive_device(udev_mon); struct udev_device *dev = udev_monitor_receive_device(udev_mon);
@@ -479,6 +496,17 @@ static void input_poll(bool (*handler) (struct input_event*, struct input_device
} }
udev_device_unref(dev); udev_device_unref(dev);
} }
} else if (fds[sig_fdindex].revents > 0) {
struct signalfd_siginfo info;
read(fds[sig_fdindex].fd, &info, sizeof(info));
switch (info.ssi_signo) {
case SIGINT:
case SIGTERM:
case SIGQUIT:
case SIGHUP:
return false;
}
} }
for (int i=0;i<numDevices;i++) { for (int i=0;i<numDevices;i++) {
if (fds[devices[i].fdindex].revents > 0) { if (fds[devices[i].fdindex].revents > 0) {
@@ -489,7 +517,7 @@ static void input_poll(bool (*handler) (struct input_event*, struct input_device
fprintf(stderr, "Error: cannot keep up\n"); fprintf(stderr, "Error: cannot keep up\n");
else if (rc == LIBEVDEV_READ_STATUS_SUCCESS) { else if (rc == LIBEVDEV_READ_STATUS_SUCCESS) {
if (!handler(&ev, &devices[i])) if (!handler(&ev, &devices[i]))
return; return true;
} }
} }
if (rc == -ENODEV) { if (rc == -ENODEV) {
@@ -501,6 +529,8 @@ static void input_poll(bool (*handler) (struct input_event*, struct input_device
} }
} }
} }
return false;
} }
static void input_map_key(char* keyName, short* key) { static void input_map_key(char* keyName, short* key) {
@@ -508,7 +538,9 @@ static void input_map_key(char* keyName, short* key) {
currentKey = key; currentKey = key;
currentAbs = NULL; currentAbs = NULL;
*key = -1; *key = -1;
input_poll(input_handle_mapping_event); if (!input_poll(input_handle_mapping_event))
exit(1);
usleep(250000); usleep(250000);
input_drain(); input_drain();
} }
@@ -519,7 +551,9 @@ static void input_map_abs(char* keyName, short* abs, bool* reverse) {
currentAbs = abs; currentAbs = abs;
currentReverse = reverse; currentReverse = reverse;
*abs = -1; *abs = -1;
input_poll(input_handle_mapping_event); if (!input_poll(input_handle_mapping_event))
exit(1);
usleep(250000); usleep(250000);
input_drain(); input_drain();
} }
@@ -532,7 +566,9 @@ static void input_map_abskey(char* keyName, short* key, short* abs, bool* revers
*key = -1; *key = -1;
*abs = -1; *abs = -1;
*currentReverse = false; *currentReverse = false;
input_poll(input_handle_mapping_event); if (!input_poll(input_handle_mapping_event))
exit(1);
usleep(250000); usleep(250000);
input_drain(); input_drain();
} }

View File

@@ -72,8 +72,7 @@ static void stream(STREAM_CONFIGURATION* config, const char* address, const char
} }
struct sockaddr_in *addr = (struct sockaddr_in*)res->ai_addr; struct sockaddr_in *addr = (struct sockaddr_in*)res->ai_addr;
LiStartConnection(addr->sin_addr.s_addr, config, NULL, decoder_callbacks, LiStartConnection(addr->sin_addr.s_addr, config, &connection_callbacks, decoder_callbacks, &audio_callbacks, NULL, NULL, 0, client_get_server_version());
&audio_callbacks, NULL, NULL, 0, client_get_server_version());
freeaddrinfo(res); freeaddrinfo(res);
input_loop(); input_loop();