(root)/
glib-2.79.0/
gio/
gasynchelper.c
       1  /* GIO - GLib Input, Output and Streaming Library
       2   * 
       3   * Copyright (C) 2006-2007 Red Hat, Inc.
       4   *
       5   * SPDX-License-Identifier: LGPL-2.1-or-later
       6   *
       7   * This library is free software; you can redistribute it and/or
       8   * modify it under the terms of the GNU Lesser General Public
       9   * License as published by the Free Software Foundation; either
      10   * version 2.1 of the License, or (at your option) any later version.
      11   *
      12   * This library is distributed in the hope that it will be useful,
      13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15   * Lesser General Public License for more details.
      16   *
      17   * You should have received a copy of the GNU Lesser General
      18   * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
      19   *
      20   * Author: Alexander Larsson <alexl@redhat.com>
      21   */
      22  
      23  #include "config.h"
      24  
      25  #include "gasynchelper.h"
      26  
      27  
      28  /*< private >
      29   * GAsyncHelper:
      30   * 
      31   * Provides helper functions for asynchronous operations.
      32   */
      33  
      34  #ifdef G_OS_WIN32
      35  gboolean
      36  _g_win32_overlap_wait_result (HANDLE           hfile,
      37                                OVERLAPPED      *overlap,
      38                                DWORD           *transferred,
      39                                GCancellable    *cancellable)
      40  {
      41    GPollFD pollfd[2];
      42    gboolean result = FALSE;
      43    gint num, npoll;
      44  
      45  #if GLIB_SIZEOF_VOID_P == 8
      46    pollfd[0].fd = (gint64)overlap->hEvent;
      47  #else
      48    pollfd[0].fd = (gint)overlap->hEvent;
      49  #endif
      50    pollfd[0].events = G_IO_IN;
      51    num = 1;
      52  
      53    if (g_cancellable_make_pollfd (cancellable, &pollfd[1]))
      54      num++;
      55  
      56  loop:
      57    npoll = g_poll (pollfd, num, -1);
      58    if (npoll <= 0)
      59      /* error out, should never happen */
      60      goto end;
      61  
      62    if (g_cancellable_is_cancelled (cancellable))
      63      {
      64        /* CancelIO only cancels pending operations issued by the
      65         * current thread and since we're doing only sync operations,
      66         * this is safe.... */
      67        /* CancelIoEx is only Vista+. Since we have only one overlap
      68         * operation on this thread, we can just use: */
      69        result = CancelIo (hfile);
      70        g_warn_if_fail (result);
      71      }
      72  
      73    result = GetOverlappedResult (overlap->hEvent, overlap, transferred, FALSE);
      74    if (result == FALSE &&
      75        GetLastError () == ERROR_IO_INCOMPLETE &&
      76        !g_cancellable_is_cancelled (cancellable))
      77      goto loop;
      78  
      79  end:
      80    if (num > 1)
      81      g_cancellable_release_fd (cancellable);
      82  
      83    return result;
      84  }
      85  #endif