[glib] Bug 591714 – Figure out failure handling for g_cancellable_make_pollfd()
- From: Benjamin Otte <otte src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [glib] Bug 591714 – Figure out failure handling for g_cancellable_make_pollfd()
- Date: Wed, 19 Aug 2009 09:02:36 +0000 (UTC)
commit bb8e4f06ab1a0ada2c8835284ec5f853378694e2
Author: Benjamin Otte <otte gnome org>
Date: Thu Aug 13 20:19:15 2009 +0200
Bug 591714 â?? Figure out failure handling for g_cancellable_make_pollfd()
Make g_cancellable_make_pollfd() return a gboolean that indicates its error
status. Update the code that calls this function accordingly.
gio/gcancellable.c | 38 +++++++++++++++++++++++++-------------
gio/gcancellable.h | 2 +-
gio/gsocket.c | 19 ++++++-------------
gio/gunixinputstream.c | 3 +--
gio/gunixoutputstream.c | 3 +--
5 files changed, 34 insertions(+), 31 deletions(-)
---
diff --git a/gio/gcancellable.c b/gio/gcancellable.c
index 88490b0..ada764a 100644
--- a/gio/gcancellable.c
+++ b/gio/gcancellable.c
@@ -55,7 +55,6 @@ struct _GCancellablePrivate
GObject parent_instance;
guint cancelled : 1;
- guint allocated_pipe : 1;
guint cancelled_running : 1;
guint cancelled_running_waiting : 1;
int cancel_pipe[2];
@@ -224,8 +223,6 @@ g_cancellable_open_pipe (GCancellable *cancellable)
set_fd_close_exec (priv->cancel_pipe[0]);
set_fd_close_exec (priv->cancel_pipe[1]);
}
- else
- g_warning ("Failed to create pipe for GCancellable. Out of file descriptors?");
}
#endif
@@ -440,11 +437,8 @@ g_cancellable_get_fd (GCancellable *cancellable)
return -1;
#else
G_LOCK(cancellable);
- if (!priv->allocated_pipe)
- {
- priv->allocated_pipe = TRUE;
- g_cancellable_open_pipe (cancellable);
- }
+ if (priv->cancel_pipe[0] == -1)
+ g_cancellable_open_pipe (cancellable);
fd = priv->cancel_pipe[0];
G_UNLOCK(cancellable);
@@ -455,7 +449,7 @@ g_cancellable_get_fd (GCancellable *cancellable)
/**
* g_cancellable_make_pollfd:
- * @cancellable: a #GCancellable.
+ * @cancellable: a #GCancellable or %NULL
* @pollfd: a pointer to a #GPollFD
*
* Creates a #GPollFD corresponding to @cancellable; this can be passed
@@ -463,18 +457,31 @@ g_cancellable_get_fd (GCancellable *cancellable)
* for unix systems without a native poll and for portability to
* windows.
*
+ * If this function returns %FALSE, either no @cancellable was given or
+ * resource limits prevent this function from allocating the necessary
+ * structures for polling. (On Linux, you will likely have reached
+ * the maximum number of file descriptors.) The suggested way to handle
+ * these cases is to ignore the @cancellable.
+ *
* You are not supposed to read from the fd yourself, just check for
* readable status. Reading to unset the readable status is done
* with g_cancellable_reset().
+ *
+ * @Returns: %TRUE if @pollfd was successfully initialized, %FALSE on
+ * failure to prepare the cancellable.
*
+ * @Since: 2.22
**/
-void
+gboolean
g_cancellable_make_pollfd (GCancellable *cancellable, GPollFD *pollfd)
{
GCancellablePrivate *priv;
+ int fd;
- g_return_if_fail (G_IS_CANCELLABLE (cancellable));
- g_return_if_fail (pollfd != NULL);
+ g_return_val_if_fail (pollfd != NULL, FALSE);
+ if (cancellable == NULL)
+ return FALSE;
+ g_return_val_if_fail (G_IS_CANCELLABLE (cancellable), FALSE);
priv = cancellable->priv;
@@ -483,10 +490,15 @@ g_cancellable_make_pollfd (GCancellable *cancellable, GPollFD *pollfd)
{
/* A manual reset anonymous event, starting unset */
priv->event = CreateEvent (NULL, TRUE, FALSE, NULL);
+ if (priv->event == NULL)
+ return FALSE;
}
pollfd->fd = (gintptr)priv->event;
#else /* !G_OS_WIN32 */
- pollfd->fd = g_cancellable_get_fd (cancellable);
+ fd = g_cancellable_get_fd (cancellable);
+ if (fd == -1)
+ return -1;
+ pollfd->fd = fd;
#endif /* G_OS_WIN32 */
pollfd->events = G_IO_IN;
pollfd->revents = 0;
diff --git a/gio/gcancellable.h b/gio/gcancellable.h
index 714899d..9d318c2 100644
--- a/gio/gcancellable.h
+++ b/gio/gcancellable.h
@@ -79,7 +79,7 @@ gboolean g_cancellable_set_error_if_cancelled (GCancellable *cancellable,
GError **error);
int g_cancellable_get_fd (GCancellable *cancellable);
-void g_cancellable_make_pollfd (GCancellable *cancellable,
+gboolean g_cancellable_make_pollfd (GCancellable *cancellable,
GPollFD *pollfd);
GCancellable *g_cancellable_get_current (void);
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 3f92c75..923212b 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -2291,11 +2291,10 @@ winsock_source_new (GSocket *socket,
winsock_source->condition = condition;
add_condition_watch (socket, &winsock_source->condition);
- if (cancellable)
+ if (g_cancellable_make_pollfd (cancellable,
+ &winsock_source->cancel_pollfd))
{
winsock_source->cancellable = g_object_ref (cancellable);
- g_cancellable_make_pollfd (cancellable,
- &winsock_source->cancel_pollfd);
g_source_add_poll (source, &winsock_source->cancel_pollfd);
}
@@ -2446,11 +2445,8 @@ g_socket_condition_wait (GSocket *socket,
num_events = 0;
events[num_events++] = socket->priv->event;
- if (cancellable)
- {
- g_cancellable_make_pollfd (cancellable, &cancel_fd);
- events[num_events++] = (WSAEVENT)cancel_fd.fd;
- }
+ if (g_cancellable_make_pollfd (cancellable, &cancel_fd))
+ events[num_events++] = (WSAEVENT)cancel_fd.fd;
current_condition = update_condition (socket);
while ((condition & current_condition) == 0)
@@ -2487,11 +2483,8 @@ g_socket_condition_wait (GSocket *socket,
poll_fd[0].events = condition;
num = 1;
- if (cancellable)
- {
- g_cancellable_make_pollfd (cancellable, &poll_fd[1]);
- num++;
- }
+ if (g_cancellable_make_pollfd (cancellable, &poll_fd[1]))
+ num++;
do
result = g_poll (poll_fd, num, -1);
diff --git a/gio/gunixinputstream.c b/gio/gunixinputstream.c
index 2813aad..a6038b8 100644
--- a/gio/gunixinputstream.c
+++ b/gio/gunixinputstream.c
@@ -340,11 +340,10 @@ g_unix_input_stream_read (GInputStream *stream,
unix_stream = G_UNIX_INPUT_STREAM (stream);
- if (cancellable)
+ if (g_cancellable_make_pollfd (cancellable, &poll_fds[1]))
{
poll_fds[0].fd = unix_stream->priv->fd;
poll_fds[0].events = G_IO_IN;
- g_cancellable_make_pollfd (cancellable, &poll_fds[1]);
do
poll_ret = g_poll (poll_fds, 2, -1);
while (poll_ret == -1 && errno == EINTR);
diff --git a/gio/gunixoutputstream.c b/gio/gunixoutputstream.c
index 147561b..1680cd3 100644
--- a/gio/gunixoutputstream.c
+++ b/gio/gunixoutputstream.c
@@ -326,11 +326,10 @@ g_unix_output_stream_write (GOutputStream *stream,
unix_stream = G_UNIX_OUTPUT_STREAM (stream);
- if (cancellable)
+ if (g_cancellable_make_pollfd (cancellable, &poll_fds[1]))
{
poll_fds[0].fd = unix_stream->priv->fd;
poll_fds[0].events = G_IO_OUT;
- g_cancellable_make_pollfd (cancellable, &poll_fds[1]);
do
poll_ret = g_poll (poll_fds, 2, -1);
while (poll_ret == -1 && errno == EINTR);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]