[gnome-system-log/gnome-3-8] log: use a GCancellable when reading new lines from the log
- From: Cosimo Cecchi <cosimoc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-system-log/gnome-3-8] log: use a GCancellable when reading new lines from the log
- Date: Mon, 15 Apr 2013 21:54:43 +0000 (UTC)
commit 08bfab1d733996350d7e135a3206c3df51ac22c6
Author: Cosimo Cecchi <cosimoc gnome org>
Date: Thu Apr 11 16:34:10 2013 -0400
log: use a GCancellable when reading new lines from the log
So we can cancel the operation when the active log changes. This fixes a
segfault where we would receive a read callback for a log that was
already removed when closing logs in a row.
https://bugzilla.gnome.org/show_bug.cgi?id=697790
src/logview-log.c | 10 ++++++++--
src/logview-log.h | 1 +
src/logview-window.c | 40 +++++++++++++++++++++++++++++++++-------
src/tests/test-reader.c | 2 +-
4 files changed, 43 insertions(+), 10 deletions(-)
---
diff --git a/src/logview-log.c b/src/logview-log.c
index f0c9e8c..292f160 100644
--- a/src/logview-log.c
+++ b/src/logview-log.c
@@ -78,6 +78,7 @@ typedef struct {
GError *err;
const char **lines;
GSList *new_days;
+ GCancellable *cancellable;
LogviewNewLinesCallback callback;
gpointer user_data;
} NewLinesJob;
@@ -253,6 +254,8 @@ new_lines_job_done (gpointer data)
job->callback (job->log, job->lines, job->new_days, job->err, job->user_data);
}
+ g_clear_object (&job->cancellable);
+
g_slist_foreach (job->new_days, (GFunc) logview_utils_day_free, NULL);
g_slist_free (job->new_days);
@@ -290,7 +293,7 @@ do_read_new_lines (GIOSchedulerJob *io_job,
g_ptr_array_remove_index (lines, lines->len - 1);
while ((line = g_data_input_stream_read_line (log->priv->stream, NULL,
- NULL, &err)) != NULL)
+ job->cancellable, &err)) != NULL)
{
g_ptr_array_add (lines, (gpointer) line);
}
@@ -798,6 +801,7 @@ log_setup_load (LogviewLog *log, LogviewCreateCallback callback,
void
logview_log_read_new_lines (LogviewLog *log,
+ GCancellable *cancellable,
LogviewNewLinesCallback callback,
gpointer user_data)
{
@@ -807,6 +811,7 @@ logview_log_read_new_lines (LogviewLog *log,
job = g_slice_new0 (NewLinesJob);
job->callback = callback;
job->user_data = user_data;
+ job->cancellable = (cancellable != NULL) ? g_object_ref (cancellable) : NULL;
job->log = g_object_ref (log);
job->err = NULL;
job->lines = NULL;
@@ -815,7 +820,8 @@ logview_log_read_new_lines (LogviewLog *log,
/* push the fetching job into another thread */
g_io_scheduler_push_job (do_read_new_lines,
job,
- NULL, 0, NULL);
+ NULL, 0,
+ job->cancellable);
}
void
diff --git a/src/logview-log.h b/src/logview-log.h
index 6e69ad8..4f81af1 100644
--- a/src/logview-log.h
+++ b/src/logview-log.h
@@ -90,6 +90,7 @@ void logview_log_create_from_gfile (GFile *file,
LogviewCreateCallback callback,
gpointer user_data);
void logview_log_read_new_lines (LogviewLog *log,
+ GCancellable *cancellable,
LogviewNewLinesCallback callback,
gpointer user_data);
diff --git a/src/logview-window.c b/src/logview-window.c
index 74c1f13..8fd1756 100644
--- a/src/logview-window.c
+++ b/src/logview-window.c
@@ -66,6 +66,8 @@ struct _LogviewWindowPrivate {
gulong monitor_id;
guint search_timeout_id;
+ GCancellable *read_cancellable;
+
guint filter_merge_id;
GList *active_filters;
gboolean matches_only;
@@ -644,12 +646,29 @@ loglist_day_cleared_cb (LogviewLoglist *loglist,
}
static void
+logview_window_schedule_log_read (LogviewWindow *window,
+ LogviewLog *log)
+{
+ if (window->priv->read_cancellable != NULL) {
+ g_cancellable_cancel (window->priv->read_cancellable);
+ g_clear_object (&window->priv->read_cancellable);
+ }
+
+ window->priv->read_cancellable = g_cancellable_new ();
+ logview_log_read_new_lines (log,
+ window->priv->read_cancellable,
+ (LogviewNewLinesCallback) read_new_lines_cb,
+ window);
+}
+
+static void
log_monitor_changed_cb (LogviewLog *log,
gpointer user_data)
{
+ LogviewWindow *window = user_data;
+
/* reschedule a read */
- logview_log_read_new_lines (log, (LogviewNewLinesCallback) read_new_lines_cb,
- user_data);
+ logview_window_schedule_log_read (window, log);
}
static void
@@ -685,10 +704,12 @@ read_new_lines_cb (LogviewLog *log,
gsize len;
if (error != NULL) {
- primary = g_strdup_printf (_("Can't read from \"%s\""),
- logview_log_get_display_name (log));
- logview_window_add_error (window, primary, error->message);
- g_free (primary);
+ if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ primary = g_strdup_printf (_("Can't read from \"%s\""),
+ logview_log_get_display_name (log));
+ logview_window_add_error (window, primary, error->message);
+ g_free (primary);
+ }
return;
}
@@ -793,7 +814,7 @@ active_log_changed_cb (LogviewManager *manager,
if (lines == NULL || logview_log_has_new_lines (log)) {
/* read the new lines */
- logview_log_read_new_lines (log, (LogviewNewLinesCallback) read_new_lines_cb, window);
+ logview_window_schedule_log_read (window, log);
} else {
/* start now monitoring the log for changes */
window->priv->monitor_id = g_signal_connect (log, "log-changed",
@@ -908,6 +929,11 @@ logview_window_finalize (GObject *object)
{
LogviewWindow *logview = LOGVIEW_WINDOW (object);
+ if (logview->priv->read_cancellable != NULL) {
+ g_cancellable_cancel (logview->priv->read_cancellable);
+ g_clear_object (&logview->priv->read_cancellable);
+ }
+
g_clear_object (&logview->priv->filters_placeholder);
pango_font_description_free (logview->priv->monospace_description);
diff --git a/src/tests/test-reader.c b/src/tests/test-reader.c
index 77cc64e..b687ed1 100644
--- a/src/tests/test-reader.c
+++ b/src/tests/test-reader.c
@@ -46,7 +46,7 @@ callback (LogviewLog *log,
{
g_print ("callback! err %p, log %p\n", error, log);
- logview_log_read_new_lines (log, new_lines_cb, NULL);
+ logview_log_read_new_lines (log, NULL, new_lines_cb, NULL);
}
int main (int argc, char **argv)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]