[gnome-builder] build-result: add IdeBuildResult::log signal
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-builder] build-result: add IdeBuildResult::log signal
- Date: Tue, 22 Dec 2015 09:23:38 +0000 (UTC)
commit 96eafc44448a5b57e81aaf14da081c04436a6da7
Author: Christian Hergert <chergert redhat com>
Date: Tue Dec 22 01:22:52 2015 -0800
build-result: add IdeBuildResult::log signal
This adds a signal that is emitted when a new log line is received from
stderr or stdout. I'm not hugely fond of this design (since signals are
pretty lock-heavy), but I rather like the API. It makes it very simple
for a build result observer to track things. We'll always be in the main
loop anyway, so contention should be low.
We should be able to use this signal to move errorformat extraction out
of IdeBuildResult too.
libide/Makefile.am | 1 +
libide/ide-build-result.c | 74 +++++++++++++++++++++++++++++++++++---------
libide/ide-build-result.h | 13 +++++++-
libide/ide-enums.c.in | 1 +
4 files changed, 72 insertions(+), 17 deletions(-)
---
diff --git a/libide/Makefile.am b/libide/Makefile.am
index 86ba1cf..f2ab9ed 100644
--- a/libide/Makefile.am
+++ b/libide/Makefile.am
@@ -482,6 +482,7 @@ glib_enum_c = ide-enums.c
glib_enum_headers = \
doap/ide-doap.h \
ide-buffer.h \
+ ide-build-result.h \
ide-diagnostic.h \
ide-highlighter.h \
ide-indent-style.h \
diff --git a/libide/ide-build-result.c b/libide/ide-build-result.c
index ca37b64..9e4b7ae 100644
--- a/libide/ide-build-result.c
+++ b/libide/ide-build-result.c
@@ -22,6 +22,7 @@
#include <libpeas/peas.h>
#include "ide-build-result.h"
+#include "ide-enums.h"
#include "ide-file.h"
#include "ide-source-location.h"
@@ -45,8 +46,9 @@ typedef struct
typedef struct
{
- IdeBuildResult *self;
- GOutputStream *writer;
+ IdeBuildResult *self;
+ GOutputStream *writer;
+ IdeBuildResultLog log;
} Tail;
G_DEFINE_TYPE_WITH_PRIVATE (IdeBuildResult, ide_build_result, IDE_TYPE_OBJECT)
@@ -60,6 +62,7 @@ enum {
enum {
DIAGNOSTIC,
+ LOG,
LAST_SIGNAL
};
@@ -255,9 +258,10 @@ _ide_build_result_open_log (IdeBuildResult *self,
}
static void
-_ide_build_result_log (IdeBuildResult *self,
- GOutputStream *stream,
- const gchar *message)
+_ide_build_result_log (IdeBuildResult *self,
+ IdeBuildResultLog log,
+ GOutputStream *stream,
+ const gchar *message)
{
g_autofree gchar *buffer = NULL;
@@ -272,11 +276,35 @@ _ide_build_result_log (IdeBuildResult *self,
* like date/time, but I didn't think it was necessary in the long
* run. Would be nice to remove the printf as well. We need to do the
* write as a single item in case we have multiple threads appending.
+ *
+ * We could probably replace the \0 with \n and pass string lengths
+ * around, but it would be nice for the callers to have a valid
+ * copy of the string.
+ *
+ * However, even worse, is that the signal emit may result in a
+ * string copy anyway. We could get around this by using an
+ * intermediate structure such as "IdeBuildResultEvent" or
+ * similar.
*/
buffer = g_strdup_printf ("%s\n", message);
- g_output_stream_write_all (stream, buffer, strlen (buffer),
- NULL, NULL, NULL);
+ g_output_stream_write_all (stream, buffer, strlen (buffer), NULL, NULL, NULL);
+
+ /*
+ * XXX:
+ *
+ * This is rather non-ideal today. Signal emission requires a global lock
+ * to access the signal information. However, we'll be in the Gtk main loop
+ * at this point, and signals generally aren't used in other threads. So
+ * the lock should most likely be non-contended. Still feels a bit heavy
+ * though since @message will get strdup()'d in most cases.
+ *
+ * I'm also non-plus'd at our use of read_line_async() to get the next line.
+ * It results in re-entering the main loop for ever log message in the build
+ * result. We already have IdeLineReader, which could help us lower the cost
+ * while doing larger buffered reads.
+ */
+ g_signal_emit (self, signals [LOG], 0, log, buffer);
}
void
@@ -297,7 +325,7 @@ ide_build_result_log_stdout (IdeBuildResult *self,
msg = g_strdup_vprintf (format, args);
va_end (args);
- _ide_build_result_log (self, priv->stdout_writer, msg);
+ _ide_build_result_log (self, IDE_BUILD_RESULT_LOG_STDOUT, priv->stdout_writer, msg);
}
}
@@ -319,7 +347,7 @@ ide_build_result_log_stderr (IdeBuildResult *self,
msg = g_strdup_vprintf (format, args);
va_end (args);
- _ide_build_result_log (self, priv->stderr_writer, msg);
+ _ide_build_result_log (self, IDE_BUILD_RESULT_LOG_STDERR, priv->stderr_writer, msg);
}
}
@@ -402,7 +430,7 @@ ide_build_result_tail_cb (GObject *object,
if (line)
{
- _ide_build_result_log (tail->self, tail->writer, line);
+ _ide_build_result_log (tail->self, tail->log, tail->writer, line);
g_data_input_stream_read_line_async (reader,
G_PRIORITY_DEFAULT,
NULL,
@@ -418,9 +446,10 @@ ide_build_result_tail_cb (GObject *object,
}
static void
-ide_build_result_tail_into (IdeBuildResult *self,
- GInputStream *reader,
- GOutputStream *writer)
+ide_build_result_tail_into (IdeBuildResult *self,
+ IdeBuildResultLog log,
+ GInputStream *reader,
+ GOutputStream *writer)
{
g_autoptr(GDataInputStream) data_reader = NULL;
Tail *tail;
@@ -434,6 +463,7 @@ ide_build_result_tail_into (IdeBuildResult *self,
tail = g_slice_alloc0 (sizeof *tail);
tail->self = g_object_ref (self);
tail->writer = g_object_ref (writer);
+ tail->log = log;
g_data_input_stream_read_line_async (data_reader,
G_PRIORITY_DEFAULT,
@@ -459,11 +489,17 @@ ide_build_result_log_subprocess (IdeBuildResult *self,
stderr_stream = g_subprocess_get_stderr_pipe (subprocess);
if (stderr_stream)
- ide_build_result_tail_into (self, stderr_stream, priv->stderr_writer);
+ ide_build_result_tail_into (self,
+ IDE_BUILD_RESULT_LOG_STDERR,
+ stderr_stream,
+ priv->stderr_writer);
stdout_stream = g_subprocess_get_stdout_pipe (subprocess);
if (stdout_stream)
- ide_build_result_tail_into (self, stdout_stream, priv->stdout_writer);
+ ide_build_result_tail_into (self,
+ IDE_BUILD_RESULT_LOG_STDOUT,
+ stdout_stream,
+ priv->stdout_writer);
}
static void
@@ -565,6 +601,14 @@ ide_build_result_class_init (IdeBuildResultClass *klass)
NULL, NULL, NULL,
G_TYPE_NONE, 1, IDE_TYPE_DIAGNOSTIC);
+ signals [LOG] =
+ g_signal_new ("log",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (IdeBuildResultClass, log),
+ NULL, NULL, NULL,
+ G_TYPE_NONE, 2, IDE_TYPE_BUILD_RESULT_LOG, G_TYPE_STRING);
+
errorformats = g_ptr_array_new ();
ide_build_result_add_error_format ("(?<filename>[a-zA-Z0-9\\-\\.]+):"
diff --git a/libide/ide-build-result.h b/libide/ide-build-result.h
index db3e4ce..dac13be 100644
--- a/libide/ide-build-result.h
+++ b/libide/ide-build-result.h
@@ -30,12 +30,21 @@ G_BEGIN_DECLS
G_DECLARE_DERIVABLE_TYPE (IdeBuildResult, ide_build_result, IDE, BUILD_RESULT, IdeObject)
+typedef enum
+{
+ IDE_BUILD_RESULT_LOG_STDOUT,
+ IDE_BUILD_RESULT_LOG_STDERR,
+} IdeBuildResultLog;
+
struct _IdeBuildResultClass
{
IdeObjectClass parent;
- void (*diagnostic) (IdeBuildResult *self,
- IdeDiagnostic *diagnostic);
+ void (*diagnostic) (IdeBuildResult *self,
+ IdeDiagnostic *diagnostic);
+ void (*log) (IdeBuildResult *self,
+ IdeBuildResultLog log,
+ const gchar *message);
};
GInputStream *ide_build_result_get_stdout_stream (IdeBuildResult *result);
diff --git a/libide/ide-enums.c.in b/libide/ide-enums.c.in
index ccdac74..4b782b4 100644
--- a/libide/ide-enums.c.in
+++ b/libide/ide-enums.c.in
@@ -6,6 +6,7 @@
#include "ide-enums.h"
#include "ide-buffer.h"
+#include "ide-build-result.h"
#include "ide-diagnostic.h"
#include "ide-doap.h"
#include "ide-highlighter.h"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]