[gnome-video-arcade] Make reading of child process output more portable.
- From: Matthew Barnes <mbarnes src gnome org>
- To: svn-commits-list gnome org
- Subject: [gnome-video-arcade] Make reading of child process output more portable.
- Date: Sat, 11 Apr 2009 16:33:11 -0400 (EDT)
commit 8c1a7ba35568e915fd065b520ec8c900e77e4045
Author: Pierre Riteau <pierre riteau gmail com>
Date: Sat Apr 11 19:09:26 2009 +0200
Make reading of child process output more portable.
The code reading the output of the SDLMAME child process was
non-functional on OpenBSD because of differences of behavior from
poll(2). When poll(2) monitors output from a pipe which reaches EOF,
the revents flags returned by poll(2) differ between implementations.
Linux only sets the POLLHUP flag, while OpenBSD sets both the POLLIN and
the POLLHUP flags.
Since the condition variable given as argument to process_stdout_ready
is partially derived from the revents flags, process_stdout_ready on
OpenBSD is called with G_IO_IN|G_IO_HUP when we hit EOF. With these
flags, the event source is not removed, and process_stdout_ready is
called again and again.
Modify the process_read_line function to return the status reported by
g_io_channel_read_line. This makes it possible for process_stdout_ready
and process_stderr_ready to remove the event source when the status is
not G_IO_STATUS_NORMAL.
---
src/gva-process.c | 23 ++++++++++++++++-------
1 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/src/gva-process.c b/src/gva-process.c
index 56ef754..36197bc 100644
--- a/src/gva-process.c
+++ b/src/gva-process.c
@@ -152,7 +152,7 @@ process_exited (GPid pid,
}
}
-static void
+static GIOStatus
process_read_line (GvaProcess *process,
GIOChannel *channel,
GQueue *queue,
@@ -172,6 +172,8 @@ process_read_line (GvaProcess *process,
}
else
process_propagate_error (process, error);
+
+ return status;
}
static gboolean
@@ -179,6 +181,8 @@ process_stdout_ready (GIOChannel *channel,
GIOCondition condition,
GvaProcess *process)
{
+ GIOStatus status;
+
if (condition & G_IO_IN)
{
/* For better performance, keep reading lines as long as
@@ -189,18 +193,20 @@ process_stdout_ready (GIOChannel *channel,
do
{
- process_read_line (
+ status = process_read_line (
process, channel,
process->priv->stdout_lines,
signals[STDOUT_READY]);
- /* Break immediately if we have a G_IO_HUP. */
- condition = (condition & G_IO_HUP) |
+ /* Continue reading as long as data is available
+ * in the internal buffer. */
+ condition =
g_io_channel_get_buffer_condition (channel);
}
while (condition == G_IO_IN);
- return TRUE;
+ if (status == G_IO_STATUS_NORMAL)
+ return TRUE;
}
process->priv->stdout_source_id = 0;
@@ -213,16 +219,19 @@ process_stderr_ready (GIOChannel *channel,
GIOCondition condition,
GvaProcess *process)
{
+ GIOStatus status;
+
if (condition & G_IO_IN)
{
/* Do NOT loop here, as we do for stdout. */
- process_read_line (
+ status = process_read_line (
process, channel,
process->priv->stderr_lines,
signals[STDERR_READY]);
- return TRUE;
+ if (status == G_IO_STATUS_NORMAL)
+ return TRUE;
}
process->priv->stderr_source_id = 0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]