Jiri Moskovcak
2013-08-28 11:13:34 UTC
Signed-off-by: Jiri Moskovcak <jmoskovc-H+wXaHxf7aLQT0dZR+***@public.gmane.org>
---
src/daemon/abrt-upload-watch.c | 39 +++++++++++++++++++++++++++++++++++----
1 file changed, 35 insertions(+), 4 deletions(-)
diff --git a/src/daemon/abrt-upload-watch.c b/src/daemon/abrt-upload-watch.c
index 3ed2854..41d2ba6 100644
--- a/src/daemon/abrt-upload-watch.c
+++ b/src/daemon/abrt-upload-watch.c
@@ -29,6 +29,7 @@
#define DEFAULT_CACHE_MIB_SIZE 4
static int g_signal_pipe[2];
+static sig_atomic_t got_sigusr;
struct queue
{
@@ -123,11 +124,29 @@ handle_new_path(struct process *proc, char *name)
}
}
-static void
-decrement_child_count(struct process *proc)
+static gboolean
+print_stats(struct process *proc)
{
- --proc->children;
+ /* there is a race, because we run this function from 2 different places
+ * 1st when a child dies
+ * 2nd as idle source from mainloop
+ * if it happens the stats will be printed twice, which I think
+ * is not a big deal, because it's only for debug and tests
+ */
+ if (got_sigusr == 1)
+ {
+ got_sigusr = 0;
+ /* this is meant only for debugging, so not marking it as translatable */
+ fprintf(stderr, "%i archives to process, %i active workers\n", g_queue_get_length(&proc->queue.q), proc->children);
+ }
+
+ /* don't remove this source from glib */
+ return true;
+}
+static void
+process_next_in_queue(struct process *proc)
+{
char *name = queue_pop(&proc->queue);
if (!name)
{
@@ -140,6 +159,13 @@ decrement_child_count(struct process *proc)
}
static void
+handle_sigusr(int signo)
+{
+ /* just set the flag and process it synchronously */
+ got_sigusr = 1;
+}
+
+static void
handle_signal(int signo)
{
int save_errno = errno;
@@ -185,7 +211,9 @@ handle_signal_pipe_cb(GIOChannel *gio, GIOCondition condition, gpointer user_dat
{
while (safe_waitpid(-1, NULL, WNOHANG) > 0)
{
- decrement_child_count(proc);
+ --proc->children;
+ process_next_in_queue(proc);
+ print_stats(proc);
}
}
}
@@ -338,6 +366,7 @@ main(int argc, char **argv)
close_on_exec_on(g_signal_pipe[1]);
ndelay_on(g_signal_pipe[0]);
ndelay_on(g_signal_pipe[1]);
+ signal(SIGUSR1, handle_sigusr);
signal(SIGTERM, handle_signal);
signal(SIGINT, handle_signal);
signal(SIGCHLD, handle_signal);
@@ -347,6 +376,7 @@ main(int argc, char **argv)
handle_signal_pipe_cb,
&proc);
+ int status_callback_source_id = g_idle_add((GSourceFunc)print_stats, &proc);
VERB2 log("Starting glib main loop");
g_main_loop_run(proc.main_loop);
@@ -354,6 +384,7 @@ main(int argc, char **argv)
VERB2 log("Glib main loop finished");
g_source_remove(channel_signal_source_id);
+ g_source_remove(status_callback_source_id);
GError *error = NULL;
g_io_channel_shutdown(channel_signal, FALSE, &error);
---
src/daemon/abrt-upload-watch.c | 39 +++++++++++++++++++++++++++++++++++----
1 file changed, 35 insertions(+), 4 deletions(-)
diff --git a/src/daemon/abrt-upload-watch.c b/src/daemon/abrt-upload-watch.c
index 3ed2854..41d2ba6 100644
--- a/src/daemon/abrt-upload-watch.c
+++ b/src/daemon/abrt-upload-watch.c
@@ -29,6 +29,7 @@
#define DEFAULT_CACHE_MIB_SIZE 4
static int g_signal_pipe[2];
+static sig_atomic_t got_sigusr;
struct queue
{
@@ -123,11 +124,29 @@ handle_new_path(struct process *proc, char *name)
}
}
-static void
-decrement_child_count(struct process *proc)
+static gboolean
+print_stats(struct process *proc)
{
- --proc->children;
+ /* there is a race, because we run this function from 2 different places
+ * 1st when a child dies
+ * 2nd as idle source from mainloop
+ * if it happens the stats will be printed twice, which I think
+ * is not a big deal, because it's only for debug and tests
+ */
+ if (got_sigusr == 1)
+ {
+ got_sigusr = 0;
+ /* this is meant only for debugging, so not marking it as translatable */
+ fprintf(stderr, "%i archives to process, %i active workers\n", g_queue_get_length(&proc->queue.q), proc->children);
+ }
+
+ /* don't remove this source from glib */
+ return true;
+}
+static void
+process_next_in_queue(struct process *proc)
+{
char *name = queue_pop(&proc->queue);
if (!name)
{
@@ -140,6 +159,13 @@ decrement_child_count(struct process *proc)
}
static void
+handle_sigusr(int signo)
+{
+ /* just set the flag and process it synchronously */
+ got_sigusr = 1;
+}
+
+static void
handle_signal(int signo)
{
int save_errno = errno;
@@ -185,7 +211,9 @@ handle_signal_pipe_cb(GIOChannel *gio, GIOCondition condition, gpointer user_dat
{
while (safe_waitpid(-1, NULL, WNOHANG) > 0)
{
- decrement_child_count(proc);
+ --proc->children;
+ process_next_in_queue(proc);
+ print_stats(proc);
}
}
}
@@ -338,6 +366,7 @@ main(int argc, char **argv)
close_on_exec_on(g_signal_pipe[1]);
ndelay_on(g_signal_pipe[0]);
ndelay_on(g_signal_pipe[1]);
+ signal(SIGUSR1, handle_sigusr);
signal(SIGTERM, handle_signal);
signal(SIGINT, handle_signal);
signal(SIGCHLD, handle_signal);
@@ -347,6 +376,7 @@ main(int argc, char **argv)
handle_signal_pipe_cb,
&proc);
+ int status_callback_source_id = g_idle_add((GSourceFunc)print_stats, &proc);
VERB2 log("Starting glib main loop");
g_main_loop_run(proc.main_loop);
@@ -354,6 +384,7 @@ main(int argc, char **argv)
VERB2 log("Glib main loop finished");
g_source_remove(channel_signal_source_id);
+ g_source_remove(status_callback_source_id);
GError *error = NULL;
g_io_channel_shutdown(channel_signal, FALSE, &error);
--
1.8.3.1
1.8.3.1