summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Olbrich <m.olbrich@pengutronix.de>2010-06-01 10:42:15 +0200
committerMichael Olbrich <m.olbrich@pengutronix.de>2010-06-03 17:08:13 +0200
commitbb093efc1658fb40a206745d1883e740f6d616a4 (patch)
tree9bbb1f7ecb6a9d558ccde2100349e7f986a359e5
parent110af2a344563c90170eb908ca3937fa62e9ce36 (diff)
downloadjson-dbus-bridge-bb093efc1658fb40a206745d1883e740f6d616a4.tar.gz
json-dbus-bridge-bb093efc1658fb40a206745d1883e740f6d616a4.tar.xz
[src] add graceful shutdown
Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
-rw-r--r--src/bridge.c43
-rw-r--r--src/bridge.h2
2 files changed, 40 insertions, 5 deletions
diff --git a/src/bridge.c b/src/bridge.c
index f12b9c1..1608166 100644
--- a/src/bridge.c
+++ b/src/bridge.c
@@ -21,6 +21,7 @@
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
+#include <signal.h>
#include <dbus/dbus.h>
@@ -190,7 +191,8 @@ void bridge_handle_cgi(evutil_socket_t s, short flags, void *data)
int bridge_init(bridge_t *self, const char *socket_path)
{
DBusError dbus_error;
- struct event *ev;
+
+ self->running = 0;
if (FCGX_Init() != 0) {
fprintf(stdout, "FCGX_Init failed.");
@@ -219,8 +221,8 @@ int bridge_init(bridge_t *self, const char *socket_path)
self->event_base = event_base_new();
- ev = event_new(self->event_base, self->socket, EV_READ|EV_PERSIST, bridge_handle_cgi, self);
- event_add(ev, 0);
+ self->ev = event_new(self->event_base, self->socket, EV_READ|EV_PERSIST, bridge_handle_cgi, self);
+ event_add(self->ev, 0);
if (!dbus_connection_set_watch_functions(self->dbus_connection,
_bridge_add_watch, _bridge_remove_watch,
@@ -247,18 +249,49 @@ int bridge_destroy(bridge_t *self)
for (request = self->head; request; request = next) {
next = request->next;
bridge_request_destroy(request);
+ free(request);
}
+ event_base_free(self->event_base);
+ event_free(self->ev);
return 0;
}
-int bridge_run(bridge_t *self)
+static void sig_handler(int fd, short event, void *arg)
{
+ bridge_t *self = (bridge_t*)arg;
+ (void)fd;
+ (void)event;
- while (1) {
+ self->running = 0;
+ event_base_loopbreak(self->event_base);
+}
+
+int bridge_run(bridge_t *self)
+{
+ struct event *ev_sigint;
+ struct event *ev_sigquit;
+ struct event *ev_sigterm;
+
+ ev_sigquit = event_new(self->event_base, SIGQUIT,
+ EV_SIGNAL|EV_PERSIST, sig_handler, self);
+ event_add(ev_sigquit, 0);
+ ev_sigint = event_new(self->event_base, SIGINT,
+ EV_SIGNAL|EV_PERSIST, sig_handler, self);
+ event_add(ev_sigint, 0);
+ ev_sigterm = event_new(self->event_base, SIGTERM,
+ EV_SIGNAL|EV_PERSIST, sig_handler, self);
+ event_add(ev_sigterm, 0);
+
+ self->running = 1;
+ while (self->running) {
event_base_loop(self->event_base, 0);
while (dbus_connection_dispatch(self->dbus_connection) == DBUS_DISPATCH_DATA_REMAINS);
}
+ event_free(ev_sigquit);
+ event_free(ev_sigint);
+ event_free(ev_sigterm);
+
/*
while(TRUE) {
if (!self->head) {
diff --git a/src/bridge.h b/src/bridge.h
index aaca58a..9e6a332 100644
--- a/src/bridge.h
+++ b/src/bridge.h
@@ -32,6 +32,8 @@ struct bridge {
DBusConnection *dbus_connection;
int socket;
struct event_base *event_base;
+ struct event *ev;
+ int running;
};
int bridge_init(bridge_t *self, const char *socket_path);