diff options
author | Christian Pointner <equinox@helsinki.at> | 2015-05-18 02:53:32 (GMT) |
---|---|---|
committer | Christian Pointner <equinox@helsinki.at> | 2015-05-18 02:53:32 (GMT) |
commit | 8bc4bb5f1273566c704d76ab584276bd5774b9d8 (patch) | |
tree | 56f23ed9aa210fa52727e1db182a407ff66405f7 | |
parent | bb7b67030b8af74123a1a0596e9b5e8acfe3e41f (diff) |
fixed return code after signal or error
-rw-r--r-- | src/Makefile | 1 | ||||
-rw-r--r-- | src/rharchive.c | 48 | ||||
-rw-r--r-- | src/rhmain.c | 73 | ||||
-rw-r--r-- | src/rhmain.h | 46 | ||||
-rw-r--r-- | src/sig_handler.c | 20 | ||||
-rw-r--r-- | src/sig_handler.h | 4 | ||||
-rw-r--r-- | src/writer.c | 5 | ||||
-rw-r--r-- | src/writer.h | 5 |
8 files changed, 177 insertions, 25 deletions
diff --git a/src/Makefile b/src/Makefile index bb4a655..d9b8810 100644 --- a/src/Makefile +++ b/src/Makefile @@ -42,6 +42,7 @@ C_OBJS := log.o \ writer.o \ file_list.o \ sysexec.o \ + rhmain.o \ rharchive.o C_SRCS := $(C_OBJS:%.o=%.c) diff --git a/src/rharchive.c b/src/rharchive.c index 96b6aa9..7014fdd 100644 --- a/src/rharchive.c +++ b/src/rharchive.c @@ -33,6 +33,9 @@ #include <errno.h> #include <string.h> #include <sys/select.h> +#include <sys/types.h> +#include <unistd.h> +#include <signal.h> #include <gst/gst.h> @@ -42,16 +45,17 @@ #include "log.h" #include "sig_handler.h" #include "daemon.h" +#include "rhmain.h" #include "writer.h" static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) { - GMainLoop *loop = (GMainLoop *)data; + RHMainLoop *loop = (RHMainLoop *)data; switch (GST_MESSAGE_TYPE(msg)) { case GST_MESSAGE_EOS: { log_printf(NOTICE, "End of stream"); - g_main_loop_quit(loop); + rhmain_loop_quit(loop, -3); break; } case GST_MESSAGE_INFO: { @@ -73,7 +77,7 @@ static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data) gst_message_parse_error(msg, &error, NULL); log_printf(ERROR, "%s", error->message); g_error_free(error); - g_main_loop_quit(loop); + rhmain_loop_quit(loop, -1); break; } default: @@ -86,22 +90,26 @@ int main_loop(options_t* opt) { log_printf(INFO, "entering main loop"); - GMainLoop *loop; + RHMainLoop loop; GstElement *pipeline, *source; GstBus *bus; writer_t writer; - loop = g_main_loop_new(NULL, FALSE); + if(!rhmain_loop_init(&loop)) { + log_printf(ERROR, "the loop object could not be created. Exiting."); + return -1; + } + pipeline = gst_pipeline_new("rharchive"); - if(!pipeline || !loop) { - log_printf(ERROR, "the pipeline/loop object could not be created. Exiting."); + if(!pipeline) { + log_printf(ERROR, "the pipeline object could not be created. Exiting."); return -1; } - int ret = writer_init(&writer, loop, opt->name_format_, opt->mode_, opt->nocache_, opt->output_dir_, opt->interval_, opt->offset_, opt->post_process_); + int ret = writer_init(&writer, &loop, opt->name_format_, opt->mode_, opt->nocache_, opt->output_dir_, opt->interval_, opt->offset_, opt->post_process_); if(ret) { gst_object_unref(GST_OBJECT(pipeline)); - gst_object_unref(GST_OBJECT(loop)); + rhmain_loop_destroy(&loop); return ret; } @@ -112,14 +120,14 @@ int main_loop(options_t* opt) g_error_free(error); gst_object_unref(GST_OBJECT(writer.sink_)); gst_object_unref(GST_OBJECT(pipeline)); - gst_object_unref(GST_OBJECT(loop)); + rhmain_loop_destroy(&loop); return -1; } gst_bin_add_many(GST_BIN(pipeline), source, writer.sink_, NULL); gst_element_link_many(source, writer.sink_, NULL); bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline)); - gst_bus_add_watch(bus, bus_call, loop); + gst_bus_add_watch(bus, bus_call, &loop); gst_object_unref(bus); log_printf(INFO, "Set State: Paused"); @@ -127,10 +135,10 @@ int main_loop(options_t* opt) log_printf(INFO, "Set State: Playing"); gst_element_set_state(pipeline, GST_STATE_PLAYING); - signal_start(loop); + signal_start(&loop); ret = writer_start(&writer); if(!ret) { - g_main_loop_run(loop); + ret = rhmain_loop_run(&loop); signal_stop(); } @@ -138,6 +146,7 @@ int main_loop(options_t* opt) gst_element_set_state (pipeline, GST_STATE_NULL); writer_stop(&writer); gst_object_unref(GST_OBJECT(pipeline)); + //rhmain_loop_destroy(&loop); return ret; } @@ -247,9 +256,18 @@ int main(int argc, char* argv[]) options_clear(&opt); - log_printf(NOTICE, "rharchive shutdown"); - gst_deinit(); + + if(!ret) + log_printf(NOTICE, "normal shutdown"); + else if(ret < 0) + log_printf(NOTICE, "shutdown after error"); + else { + log_printf(NOTICE, "shutdown after signal"); + log_close(); + kill(getpid(), ret); + } + log_close(); return ret; diff --git a/src/rhmain.c b/src/rhmain.c new file mode 100644 index 0000000..cb8e330 --- /dev/null +++ b/src/rhmain.c @@ -0,0 +1,73 @@ +/* + * rharchive + * + * The Radio Helsinki Archive Daemon + * + * + * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at> + * + * This file is part of rharchive. + * + * rharchive is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * rharchive is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with rharchive. If not, see <http://www.gnu.org/licenses/>. + * + * In addition, as a special exception, the copyright holders hereby + * grant permission for non-GPL-compatible GStreamer plugins to be used + * and distributed together with GStreamer and rharchive. + * This permission goes above and beyond the permissions granted by the + * GPL license rharchive is covered by. + */ + +#include "rhmain.h" + +#include <glib.h> +#include <gst/gst.h> + +gboolean rhmain_loop_init(RHMainLoop* loop) +{ + if(!loop) + return FALSE; + + loop->exit_code = 0; + loop->gloop = g_main_loop_new(NULL, FALSE); + if(!loop->gloop) + return FALSE; + + return TRUE; +} + +void rhmain_loop_destroy(RHMainLoop* loop) +{ + if(!loop) + return; + + gst_object_unref(GST_OBJECT(loop->gloop)); +} + +gint rhmain_loop_run(RHMainLoop* loop) +{ + if(!loop) + return -2; + + g_main_loop_run(loop->gloop); + return g_atomic_int_get(&(loop->exit_code)); +} + +void rhmain_loop_quit(RHMainLoop* loop, gint exit_code) +{ + if(!loop) + return; + + g_main_loop_quit(loop->gloop); + g_atomic_int_set(&(loop->exit_code), exit_code); +} diff --git a/src/rhmain.h b/src/rhmain.h new file mode 100644 index 0000000..bcbdd8e --- /dev/null +++ b/src/rhmain.h @@ -0,0 +1,46 @@ +/* + * rharchive + * + * The Radio Helsinki Archive Daemon + * + * + * Copyright (C) 2009-2015 Christian Pointner <equinox@helsinki.at> + * + * This file is part of rharchive. + * + * rharchive is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * rharchive is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with rharchive. If not, see <http://www.gnu.org/licenses/>. + * + * In addition, as a special exception, the copyright holders hereby + * grant permission for non-GPL-compatible GStreamer plugins to be used + * and distributed together with GStreamer and rharchive. + * This permission goes above and beyond the permissions granted by the + * GPL license rharchive is covered by. + */ + +#ifndef RHARCHIVE_rhmain_h_INCLUDED +#define RHARCHIVE_rhmain_h_INCLUDED + +#include <glib.h> + +typedef struct { + GMainLoop *gloop; + volatile gint exit_code; +} RHMainLoop; + +gboolean rhmain_loop_init(RHMainLoop* loop); +void rhmain_loop_destroy(RHMainLoop* loop); +gint rhmain_loop_run(RHMainLoop* loop); +void rhmain_loop_quit(RHMainLoop* loop, gint exit_code); + +#endif diff --git a/src/sig_handler.c b/src/sig_handler.c index 75ef4f4..aa20a98 100644 --- a/src/sig_handler.c +++ b/src/sig_handler.c @@ -37,6 +37,8 @@ #include <glib.h> #include <errno.h> +#include "rhmain.h" + static GThread *signal_thread; void signal_init() @@ -56,7 +58,7 @@ void signal_init() static gpointer signal_thread_func(gpointer data) { - GMainLoop *loop = (GMainLoop *)data; + RHMainLoop *loop = (RHMainLoop *)data; struct timespec timeout; sigset_t signal_set; @@ -83,7 +85,7 @@ static gpointer signal_thread_func(gpointer data) case SIGINT: case SIGQUIT: { log_printf(NOTICE, "signal %d received, exiting", sig_num); - g_main_loop_quit(loop); + rhmain_loop_quit(loop, sig_num); break; } default: { @@ -97,7 +99,7 @@ static gpointer signal_thread_func(gpointer data) return NULL; } -int signal_start(GMainLoop *loop) +int signal_start(RHMainLoop *loop) { g_assert(!signal_thread); @@ -110,5 +112,15 @@ int signal_start(GMainLoop *loop) void signal_stop() { - // nothing yet.. + sigset_t signal_set; + + sigemptyset(&signal_set); + sigaddset(&signal_set, SIGINT); + sigaddset(&signal_set, SIGQUIT); + sigaddset(&signal_set, SIGHUP); + sigaddset(&signal_set, SIGTERM); + sigaddset(&signal_set, SIGUSR1); + sigaddset(&signal_set, SIGUSR2); + + pthread_sigmask(SIG_UNBLOCK, &signal_set, NULL); } diff --git a/src/sig_handler.h b/src/sig_handler.h index 0d138d2..4847aec 100644 --- a/src/sig_handler.h +++ b/src/sig_handler.h @@ -31,10 +31,10 @@ #ifndef RHARCHIVE_sig_handler_h_INCLUDED #define RHARCHIVE_sig_handler_h_INCLUDED -#include <glib.h> +#include "rhmain.h" void signal_init(); -int signal_start(GMainLoop *loop); +int signal_start(RHMainLoop *loop); void signal_stop(); #endif diff --git a/src/writer.c b/src/writer.c index e434320..ab41eb4 100644 --- a/src/writer.c +++ b/src/writer.c @@ -41,6 +41,7 @@ #include "datatypes.h" #include "log.h" #include "file_list.h" +#include "rhmain.h" static int init_time_boundaries(writer_t* writer) { @@ -98,7 +99,7 @@ static void fdremoved_cb(GstElement* sink, gint fd, gpointer data) file_list_remove(&(writer->files_), fd); } -int writer_init(writer_t* writer, GMainLoop *loop, const char* name_format, mode_t mode, int nocache, const char* output_dir, int interval, int offset, char* post_process) +int writer_init(writer_t* writer, RHMainLoop *loop, const char* name_format, mode_t mode, int nocache, const char* output_dir, int interval, int offset, char* post_process) { if(!writer) return -1; @@ -198,7 +199,7 @@ static gpointer writer_thread_func(gpointer data) } log_printf(NOTICE, "writer thread stopped"); - g_main_loop_quit(writer->loop_); + rhmain_loop_quit(writer->loop_, -1); return NULL; } diff --git a/src/writer.h b/src/writer.h index 79f3a3c..073f805 100644 --- a/src/writer.h +++ b/src/writer.h @@ -36,10 +36,11 @@ #include <time.h> #include <sys/types.h> +#include "rhmain.h" #include "file_list.h" struct writer_struct { - GMainLoop *loop_; + RHMainLoop *loop_; GstElement* sink_; GstClock* clock_; GstClockID clock_id_; @@ -58,7 +59,7 @@ struct writer_struct { }; typedef struct writer_struct writer_t; -int writer_init(writer_t* writer, GMainLoop *loop, const char* name_format, mode_t mode, int nocache, const char* output_dir, int interval, int offset, char* post_process); +int writer_init(writer_t* writer, RHMainLoop *loop, const char* name_format, mode_t mode, int nocache, const char* output_dir, int interval, int offset, char* post_process); int writer_start(writer_t* writer); void writer_stop(writer_t* writer); |