gio: use GPollable* to implement fallback read_async/write_async

If a GInputStream does not provide a read_async() implementation, but
does implement GPollableInputStream, then instead of doing
read-synchronously-in-a-thread, just use
g_pollable_input_stream_read_nonblocking() and
g_pollable_input_stream_create_source() to implement an async read in
the same thread. Similarly for GOutputStream.

Remove a bunch of existing read_async()/write_async() implementations
that are basically equivalent to the new fallback method.

https://bugzilla.gnome.org/show_bug.cgi?id=673997
This commit is contained in:
Dan Winship
2012-02-04 16:46:29 -05:00
parent 82ec4dcaed
commit 00ee06e6a3
10 changed files with 153 additions and 892 deletions

View File

@@ -136,95 +136,6 @@ g_socket_output_stream_write (GOutputStream *stream,
cancellable, error);
}
static gboolean
g_socket_output_stream_write_ready (GSocket *socket,
GIOCondition condition,
GSocketOutputStream *stream)
{
GSimpleAsyncResult *simple;
GError *error = NULL;
gssize result;
result = g_socket_send_with_blocking (stream->priv->socket,
stream->priv->buffer,
stream->priv->count,
FALSE,
stream->priv->cancellable,
&error);
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK))
return TRUE;
simple = stream->priv->result;
stream->priv->result = NULL;
if (result >= 0)
g_simple_async_result_set_op_res_gssize (simple, result);
if (error)
g_simple_async_result_take_error (simple, error);
if (stream->priv->cancellable)
g_object_unref (stream->priv->cancellable);
g_simple_async_result_complete (simple);
g_object_unref (simple);
return FALSE;
}
static void
g_socket_output_stream_write_async (GOutputStream *stream,
const void *buffer,
gsize count,
gint io_priority,
GCancellable *cancellable,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSocketOutputStream *output_stream = G_SOCKET_OUTPUT_STREAM (stream);
GSource *source;
g_assert (output_stream->priv->result == NULL);
output_stream->priv->result =
g_simple_async_result_new (G_OBJECT (stream), callback, user_data,
g_socket_output_stream_write_async);
if (cancellable)
g_object_ref (cancellable);
output_stream->priv->cancellable = cancellable;
output_stream->priv->buffer = buffer;
output_stream->priv->count = count;
source = g_socket_create_source (output_stream->priv->socket,
G_IO_OUT | G_IO_HUP | G_IO_ERR,
cancellable);
g_source_set_callback (source,
(GSourceFunc) g_socket_output_stream_write_ready,
g_object_ref (output_stream), g_object_unref);
g_source_attach (source, g_main_context_get_thread_default ());
g_source_unref (source);
}
static gssize
g_socket_output_stream_write_finish (GOutputStream *stream,
GAsyncResult *result,
GError **error)
{
GSimpleAsyncResult *simple;
gssize count;
g_return_val_if_fail (G_IS_SOCKET_OUTPUT_STREAM (stream), -1);
simple = G_SIMPLE_ASYNC_RESULT (result);
g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_socket_output_stream_write_async);
count = g_simple_async_result_get_op_res_gssize (simple);
return count;
}
static gboolean
g_socket_output_stream_pollable_is_writable (GPollableOutputStream *pollable)
{
@@ -233,6 +144,19 @@ g_socket_output_stream_pollable_is_writable (GPollableOutputStream *pollable)
return g_socket_condition_check (output_stream->priv->socket, G_IO_OUT);
}
static gssize
g_socket_output_stream_pollable_write_nonblocking (GPollableOutputStream *pollable,
const void *buffer,
gsize size,
GError **error)
{
GSocketOutputStream *output_stream = G_SOCKET_OUTPUT_STREAM (pollable);
return g_socket_send_with_blocking (output_stream->priv->socket,
buffer, size, FALSE,
NULL, error);
}
static GSource *
g_socket_output_stream_pollable_create_source (GPollableOutputStream *pollable,
GCancellable *cancellable)
@@ -250,19 +174,6 @@ g_socket_output_stream_pollable_create_source (GPollableOutputStream *pollable,
return pollable_source;
}
static gssize
g_socket_output_stream_pollable_write_nonblocking (GPollableOutputStream *pollable,
const void *buffer,
gsize size,
GError **error)
{
GSocketOutputStream *output_stream = G_SOCKET_OUTPUT_STREAM (pollable);
return g_socket_send_with_blocking (output_stream->priv->socket,
buffer, size, FALSE,
NULL, error);
}
#ifdef G_OS_UNIX
static int
g_socket_output_stream_get_fd (GFileDescriptorBased *fd_based)
@@ -286,8 +197,6 @@ g_socket_output_stream_class_init (GSocketOutputStreamClass *klass)
gobject_class->set_property = g_socket_output_stream_set_property;
goutputstream_class->write_fn = g_socket_output_stream_write;
goutputstream_class->write_async = g_socket_output_stream_write_async;
goutputstream_class->write_finish = g_socket_output_stream_write_finish;
g_object_class_install_property (gobject_class, PROP_SOCKET,
g_param_spec_object ("socket",