mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-01 15:03:39 +02:00
Add pollable input/output streams
When interfacing with APIs that expect unix-style async I/O, it is useful to be able to tell in advance whether a read/write is going to block. This adds new interfaces GPollableInputStream and GPollableOutputStream that can be implemented by a GInputStream or GOutputStream to add _is_readable/_is_writable, _create_source, and _read_nonblocking/_write_nonblocking methods. Also, implement for GUnixInput/OutputStream and GSocketInput/OutputStream https://bugzilla.gnome.org/show_bug.cgi?id=634241
This commit is contained in:
@@ -60,8 +60,12 @@ enum {
|
||||
PROP_CLOSE_FD
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GUnixOutputStream, g_unix_output_stream, G_TYPE_OUTPUT_STREAM);
|
||||
static void g_unix_output_stream_pollable_iface_init (GPollableOutputStreamInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GUnixOutputStream, g_unix_output_stream, G_TYPE_OUTPUT_STREAM,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_OUTPUT_STREAM,
|
||||
g_unix_output_stream_pollable_iface_init)
|
||||
);
|
||||
|
||||
struct _GUnixOutputStreamPrivate {
|
||||
int fd;
|
||||
@@ -103,6 +107,9 @@ static gboolean g_unix_output_stream_close_finish (GOutputStream *stream,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
static gboolean g_unix_output_stream_pollable_is_writable (GPollableOutputStream *stream);
|
||||
static GSource *g_unix_output_stream_pollable_create_source (GPollableOutputStream *stream,
|
||||
GCancellable *cancellable);
|
||||
|
||||
static void
|
||||
g_unix_output_stream_finalize (GObject *object)
|
||||
@@ -160,6 +167,13 @@ g_unix_output_stream_class_init (GUnixOutputStreamClass *klass)
|
||||
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
|
||||
}
|
||||
|
||||
static void
|
||||
g_unix_output_stream_pollable_iface_init (GPollableOutputStreamInterface *iface)
|
||||
{
|
||||
iface->is_writable = g_unix_output_stream_pollable_is_writable;
|
||||
iface->create_source = g_unix_output_stream_pollable_create_source;
|
||||
}
|
||||
|
||||
static void
|
||||
g_unix_output_stream_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@@ -593,3 +607,37 @@ g_unix_output_stream_close_finish (GOutputStream *stream,
|
||||
/* Failures handled in generic close_finish code */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
g_unix_output_stream_pollable_is_writable (GPollableOutputStream *stream)
|
||||
{
|
||||
GUnixOutputStream *unix_stream = G_UNIX_OUTPUT_STREAM (stream);
|
||||
GPollFD poll_fd;
|
||||
gint result;
|
||||
|
||||
poll_fd.fd = unix_stream->priv->fd;
|
||||
poll_fd.events = G_IO_OUT;
|
||||
|
||||
do
|
||||
result = g_poll (&poll_fd, 1, 0);
|
||||
while (result == -1 && errno == EINTR);
|
||||
|
||||
return poll_fd.revents != 0;
|
||||
}
|
||||
|
||||
static GSource *
|
||||
g_unix_output_stream_pollable_create_source (GPollableOutputStream *stream,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
GUnixOutputStream *unix_stream = G_UNIX_OUTPUT_STREAM (stream);
|
||||
GSource *inner_source, *pollable_source;
|
||||
|
||||
pollable_source = g_pollable_source_new (G_OBJECT (stream));
|
||||
|
||||
inner_source = _g_fd_source_new (unix_stream->priv->fd, G_IO_OUT, cancellable);
|
||||
g_source_set_dummy_callback (inner_source);
|
||||
g_source_add_child_source (pollable_source, inner_source);
|
||||
g_source_unref (inner_source);
|
||||
|
||||
return pollable_source;
|
||||
}
|
||||
|
Reference in New Issue
Block a user