summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Pointner <equinox@helsinki.at>2015-05-18 02:53:32 (GMT)
committerChristian Pointner <equinox@helsinki.at>2015-05-18 02:53:32 (GMT)
commit8bc4bb5f1273566c704d76ab584276bd5774b9d8 (patch)
tree56f23ed9aa210fa52727e1db182a407ff66405f7 /src
parentbb7b67030b8af74123a1a0596e9b5e8acfe3e41f (diff)
fixed return code after signal or error
Diffstat (limited to 'src')
-rw-r--r--src/Makefile1
-rw-r--r--src/rharchive.c48
-rw-r--r--src/rhmain.c73
-rw-r--r--src/rhmain.h46
-rw-r--r--src/sig_handler.c20
-rw-r--r--src/sig_handler.h4
-rw-r--r--src/writer.c5
-rw-r--r--src/writer.h5
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);