mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-29 20:34:11 +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,7 +60,12 @@ enum {
|
||||
PROP_CLOSE_FD
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GUnixInputStream, g_unix_input_stream, G_TYPE_INPUT_STREAM);
|
||||
static void g_unix_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface);
|
||||
|
||||
G_DEFINE_TYPE_WITH_CODE (GUnixInputStream, g_unix_input_stream, G_TYPE_INPUT_STREAM,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_POLLABLE_INPUT_STREAM,
|
||||
g_unix_input_stream_pollable_iface_init)
|
||||
);
|
||||
|
||||
struct _GUnixInputStreamPrivate {
|
||||
int fd;
|
||||
@@ -111,6 +116,9 @@ static gboolean g_unix_input_stream_close_finish (GInputStream *stream,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
static gboolean g_unix_input_stream_pollable_is_readable (GPollableInputStream *stream);
|
||||
static GSource *g_unix_input_stream_pollable_create_source (GPollableInputStream *stream,
|
||||
GCancellable *cancellable);
|
||||
|
||||
static void
|
||||
g_unix_input_stream_finalize (GObject *object)
|
||||
@@ -174,6 +182,13 @@ g_unix_input_stream_class_init (GUnixInputStreamClass *klass)
|
||||
G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_NAME | G_PARAM_STATIC_NICK | G_PARAM_STATIC_BLURB));
|
||||
}
|
||||
|
||||
static void
|
||||
g_unix_input_stream_pollable_iface_init (GPollableInputStreamInterface *iface)
|
||||
{
|
||||
iface->is_readable = g_unix_input_stream_pollable_is_readable;
|
||||
iface->create_source = g_unix_input_stream_pollable_create_source;
|
||||
}
|
||||
|
||||
static void
|
||||
g_unix_input_stream_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@@ -637,3 +652,37 @@ g_unix_input_stream_close_finish (GInputStream *stream,
|
||||
/* Failures handled in generic close_finish code */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
g_unix_input_stream_pollable_is_readable (GPollableInputStream *stream)
|
||||
{
|
||||
GUnixInputStream *unix_stream = G_UNIX_INPUT_STREAM (stream);
|
||||
GPollFD poll_fd;
|
||||
gint result;
|
||||
|
||||
poll_fd.fd = unix_stream->priv->fd;
|
||||
poll_fd.events = G_IO_IN;
|
||||
|
||||
do
|
||||
result = g_poll (&poll_fd, 1, 0);
|
||||
while (result == -1 && errno == EINTR);
|
||||
|
||||
return poll_fd.revents != 0;
|
||||
}
|
||||
|
||||
static GSource *
|
||||
g_unix_input_stream_pollable_create_source (GPollableInputStream *stream,
|
||||
GCancellable *cancellable)
|
||||
{
|
||||
GUnixInputStream *unix_stream = G_UNIX_INPUT_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_IN, 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