[glib/wip/ghandle: 2/16] gio: use new g_cancellable_poll_simple() API



commit 0dce44800b09eb37a864db20d81b7b93f2262e1d
Author: Ryan Lortie <desrt desrt ca>
Date:   Thu Dec 18 01:52:23 2014 -0500

    gio: use new g_cancellable_poll_simple() API
    
    This removes a lot of similar-looking code.
    
    This also means that there is no longer any code inside of GIO that is
    handling fds from GCancellable.  That moves us closer to being able to
    completely rid ourselves of per-cancellable file descriptors.
    
    Windows parts are completely untested (and not even compiled).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=741716

 gio/gasynchelper.c      |   20 ++-------
 gio/gsocket.c           |  109 +++++++++-------------------------------------
 gio/gunixinputstream.c  |   44 ++++++-------------
 gio/gunixoutputstream.c |   45 ++++++--------------
 4 files changed, 52 insertions(+), 166 deletions(-)
---
diff --git a/gio/gasynchelper.c b/gio/gasynchelper.c
index 7cf86f1..e8d1b29 100644
--- a/gio/gasynchelper.c
+++ b/gio/gasynchelper.c
@@ -40,22 +40,14 @@ _g_win32_overlap_wait_result (HANDLE           hfile,
                               DWORD           *transferred,
                               GCancellable    *cancellable)
 {
-  GPollFD pollfd[2];
+  GPollFD pollfd;
   gboolean result = FALSE;
-  gint num, npoll;
 
-  pollfd[0].fd = (gint)overlap->hEvent;
-  pollfd[0].events = G_IO_IN;
-  num = 1;
-
-  if (g_cancellable_make_pollfd (cancellable, &pollfd[1]))
-    num++;
+  pollfd.fd = (gint)overlap->hEvent;
+  pollfd.events = G_IO_IN;
 
 loop:
-  npoll = g_poll (pollfd, num, -1);
-  if (npoll <= 0)
-    /* error out, should never happen */
-    goto end;
+  g_cancellable_poll_simple (cancellable, &pollfd, -1, NULL);
 
   if (g_cancellable_is_cancelled (cancellable))
     {
@@ -74,10 +66,6 @@ loop:
       !g_cancellable_is_cancelled (cancellable))
     goto loop;
 
-end:
-  if (num > 1)
-    g_cancellable_release_fd (cancellable);
-
   return result;
 }
 #endif
diff --git a/gio/gsocket.c b/gio/gsocket.c
index d9e135d..479387e 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -3557,7 +3557,7 @@ g_socket_condition_timed_wait (GSocket       *socket,
                               GCancellable  *cancellable,
                               GError       **error)
 {
-  gint64 start_time;
+  gint64 end_time;
 
   g_return_val_if_fail (G_IS_SOCKET (socket), FALSE);
 
@@ -3567,114 +3567,49 @@ g_socket_condition_timed_wait (GSocket       *socket,
   if (g_cancellable_set_error_if_cancelled (cancellable, error))
     return FALSE;
 
-  if (socket->priv->timeout &&
-      (timeout < 0 || socket->priv->timeout < timeout / G_USEC_PER_SEC))
-    timeout = socket->priv->timeout * 1000;
-  else if (timeout != -1)
-    timeout = timeout / 1000;
-
-  start_time = g_get_monotonic_time ();
+  if (socket->priv->timeout && (timeout < 0 || socket->priv->timeout < timeout / G_USEC_PER_SEC))
+    end_time = g_get_monotonic_time () + socket->priv->timeout * G_TIME_SPAN_SECOND;
+  else if (timeout > 0)
+    end_time = g_get_monotonic_time () + timeout;
+  else /* timeout is -1 or 0 */
+    end_time = timeout;
 
 #ifdef G_OS_WIN32
   {
     GIOCondition current_condition;
-    WSAEVENT events[2];
-    DWORD res;
-    GPollFD cancel_fd;
-    int num_events;
+    GPollFD pollfd;
 
     /* Always check these */
-    condition |=  G_IO_ERR | G_IO_HUP;
+    condition |= G_IO_ERR | G_IO_HUP;
 
     add_condition_watch (socket, &condition);
 
-    num_events = 0;
-    events[num_events++] = socket->priv->event;
-
-    if (g_cancellable_make_pollfd (cancellable, &cancel_fd))
-      events[num_events++] = (WSAEVENT)cancel_fd.fd;
-
-    if (timeout == -1)
-      timeout = WSA_INFINITE;
+    pollfd.fd = (gintptr) socket->priv->event;
+    pollfd.events = G_IO_IN;
 
     current_condition = update_condition (socket);
     while ((condition & current_condition) == 0)
       {
-       res = WSAWaitForMultipleEvents (num_events, events,
-                                       FALSE, timeout, FALSE);
-       if (res == WSA_WAIT_FAILED)
-         {
-           int errsv = get_socket_errno ();
-
-           g_set_error (error, G_IO_ERROR,
-                        socket_io_error_from_errno (errsv),
-                        _("Waiting for socket condition: %s"),
-                        socket_strerror (errsv));
-           break;
-         }
-       else if (res == WSA_WAIT_TIMEOUT)
-         {
-           g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
-                                _("Socket I/O timed out"));
-           break;
-         }
-
-       if (g_cancellable_set_error_if_cancelled (cancellable, error))
-         break;
-
-       current_condition = update_condition (socket);
+        if (!g_cancellable_poll_simple (cancellable, &pollfd, end_time, error))
+          {
+            g_prefix_error (error, _("Waiting for socket condition: "));
+            break;
+          }
 
-       if (timeout != WSA_INFINITE)
-         {
-           timeout -= (g_get_monotonic_time () - start_time) * 1000;
-           if (timeout < 0)
-             timeout = 0;
-         }
+        current_condition = update_condition (socket);
       }
     remove_condition_watch (socket, &condition);
-    if (num_events > 1)
-      g_cancellable_release_fd (cancellable);
 
     return (condition & current_condition) != 0;
   }
 #else
   {
-    GPollFD poll_fd[2];
-    gint result;
-    gint num;
-
-    poll_fd[0].fd = socket->priv->fd;
-    poll_fd[0].events = condition;
-    num = 1;
+    GPollFD pollfd;
 
-    if (g_cancellable_make_pollfd (cancellable, &poll_fd[1]))
-      num++;
-
-    while (TRUE)
-      {
-       result = g_poll (poll_fd, num, timeout);
-       if (result != -1 || errno != EINTR)
-         break;
-
-       if (timeout != -1)
-         {
-           timeout -= (g_get_monotonic_time () - start_time) / 1000;
-           if (timeout < 0)
-             timeout = 0;
-         }
-      }
-    
-    if (num > 1)
-      g_cancellable_release_fd (cancellable);
-
-    if (result == 0)
-      {
-       g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
-                            _("Socket I/O timed out"));
-       return FALSE;
-      }
+    pollfd.fd = socket->priv->fd;
+    pollfd.events = condition;
 
-    return !g_cancellable_set_error_if_cancelled (cancellable, error);
+    return g_cancellable_poll_simple (cancellable, &pollfd, end_time, error);
   }
   #endif
 }
diff --git a/gio/gunixinputstream.c b/gio/gunixinputstream.c
index 24700ec..6996b0b 100644
--- a/gio/gunixinputstream.c
+++ b/gio/gunixinputstream.c
@@ -340,43 +340,27 @@ g_unix_input_stream_read (GInputStream  *stream,
 {
   GUnixInputStream *unix_stream;
   gssize res = -1;
-  GPollFD poll_fds[2];
-  int nfds;
-  int poll_ret;
+  GPollFD pollfd;
 
   unix_stream = G_UNIX_INPUT_STREAM (stream);
 
-  poll_fds[0].fd = unix_stream->priv->fd;
-  poll_fds[0].events = G_IO_IN;
-  if (unix_stream->priv->is_pipe_or_socket &&
-      g_cancellable_make_pollfd (cancellable, &poll_fds[1]))
-    nfds = 2;
-  else
-    nfds = 1;
+  pollfd.fd = unix_stream->priv->fd;
+  pollfd.events = G_IO_IN;
 
   while (1)
     {
-      poll_fds[0].revents = poll_fds[1].revents = 0;
-      do
-       poll_ret = g_poll (poll_fds, nfds, -1);
-      while (poll_ret == -1 && errno == EINTR);
-
-      if (poll_ret == -1)
-       {
-          int errsv = errno;
+      gboolean result;
 
-         g_set_error (error, G_IO_ERROR,
-                      g_io_error_from_errno (errsv),
-                      _("Error reading from file descriptor: %s"),
-                      g_strerror (errsv));
-         break;
-       }
-
-      if (g_cancellable_set_error_if_cancelled (cancellable, error))
-       break;
+      if (unix_stream->priv->is_pipe_or_socket)
+        result = g_cancellable_poll_simple (cancellable, &pollfd, -1, error);
+      else
+        result = !g_cancellable_set_error_if_cancelled (cancellable, error);
 
-      if (!poll_fds[0].revents)
-       continue;
+      if (!result)
+        {
+          g_prefix_error (error, _("Error reading from file descriptor: "));
+          break;
+        }
 
       res = read (unix_stream->priv->fd, buffer, count);
       if (res == -1)
@@ -395,8 +379,6 @@ g_unix_input_stream_read (GInputStream  *stream,
       break;
     }
 
-  if (nfds == 2)
-    g_cancellable_release_fd (cancellable);
   return res;
 }
 
diff --git a/gio/gunixoutputstream.c b/gio/gunixoutputstream.c
index 8aa7292..a4193a2 100644
--- a/gio/gunixoutputstream.c
+++ b/gio/gunixoutputstream.c
@@ -325,44 +325,27 @@ g_unix_output_stream_write (GOutputStream  *stream,
 {
   GUnixOutputStream *unix_stream;
   gssize res = -1;
-  GPollFD poll_fds[2];
-  int nfds;
-  int poll_ret;
+  GPollFD pollfd;
 
   unix_stream = G_UNIX_OUTPUT_STREAM (stream);
 
-  poll_fds[0].fd = unix_stream->priv->fd;
-  poll_fds[0].events = G_IO_OUT;
-
-  if (unix_stream->priv->is_pipe_or_socket &&
-      g_cancellable_make_pollfd (cancellable, &poll_fds[1]))
-    nfds = 2;
-  else
-    nfds = 1;
+  pollfd.fd = unix_stream->priv->fd;
+  pollfd.events = G_IO_OUT;
 
   while (1)
     {
-      poll_fds[0].revents = poll_fds[1].revents = 0;
-      do
-       poll_ret = g_poll (poll_fds, nfds, -1);
-      while (poll_ret == -1 && errno == EINTR);
-
-      if (poll_ret == -1)
-       {
-          int errsv = errno;
-
-         g_set_error (error, G_IO_ERROR,
-                      g_io_error_from_errno (errsv),
-                      _("Error writing to file descriptor: %s"),
-                      g_strerror (errsv));
-         break;
-       }
+      gboolean result;
 
-      if (g_cancellable_set_error_if_cancelled (cancellable, error))
-       break;
+      if (unix_stream->priv->is_pipe_or_socket)
+        result = g_cancellable_poll_simple (cancellable, &pollfd, -1, error);
+      else
+        result = !g_cancellable_set_error_if_cancelled (cancellable, error);
 
-      if (!poll_fds[0].revents)
-       continue;
+      if (!result)
+        {
+          g_prefix_error (error, _("Error writing to file descriptor: "));
+          break;
+        }
 
       res = write (unix_stream->priv->fd, buffer, count);
       if (res == -1)
@@ -381,8 +364,6 @@ g_unix_output_stream_write (GOutputStream  *stream,
       break;
     }
 
-  if (nfds == 2)
-    g_cancellable_release_fd (cancellable);
   return res;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]