| /* GIO - GLib Input, Output and Streaming Library | 
 |  *  | 
 |  * Copyright (C) 2006-2007 Red Hat, Inc. | 
 |  * | 
 |  * SPDX-License-Identifier: LGPL-2.1-or-later | 
 |  * | 
 |  * This library is free software; you can redistribute it and/or | 
 |  * modify it under the terms of the GNU Lesser General Public | 
 |  * License as published by the Free Software Foundation; either | 
 |  * version 2.1 of the License, or (at your option) any later version. | 
 |  * | 
 |  * This library is distributed in the hope that it will be useful, | 
 |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
 |  * Lesser General Public License for more details. | 
 |  * | 
 |  * You should have received a copy of the GNU Lesser General | 
 |  * Public License along with this library; if not, see <http://www.gnu.org/licenses/>. | 
 |  * | 
 |  * Author: Alexander Larsson <alexl@redhat.com> | 
 |  */ | 
 |  | 
 | #include "config.h" | 
 |  | 
 | #include "gasynchelper.h" | 
 |  | 
 |  | 
 | /*< private > | 
 |  * GAsyncHelper: | 
 |  *  | 
 |  * Provides helper functions for asynchronous operations. | 
 |  */ | 
 |  | 
 | #ifdef G_OS_WIN32 | 
 | gboolean | 
 | _g_win32_overlap_wait_result (HANDLE           hfile, | 
 |                               OVERLAPPED      *overlap, | 
 |                               DWORD           *transferred, | 
 |                               GCancellable    *cancellable) | 
 | { | 
 |   GPollFD pollfd[2]; | 
 |   gboolean result = FALSE; | 
 |   gint num, npoll; | 
 |  | 
 | #if GLIB_SIZEOF_VOID_P == 8 | 
 |   pollfd[0].fd = (gint64)overlap->hEvent; | 
 | #else | 
 |   pollfd[0].fd = (gint)overlap->hEvent; | 
 | #endif | 
 |   pollfd[0].events = G_IO_IN; | 
 |   num = 1; | 
 |  | 
 |   if (g_cancellable_make_pollfd (cancellable, &pollfd[1])) | 
 |     num++; | 
 |  | 
 | loop: | 
 |   npoll = g_poll (pollfd, num, -1); | 
 |   if (npoll <= 0) | 
 |     /* error out, should never happen */ | 
 |     goto end; | 
 |  | 
 |   if (g_cancellable_is_cancelled (cancellable)) | 
 |     { | 
 |       /* CancelIO only cancels pending operations issued by the | 
 |        * current thread and since we're doing only sync operations, | 
 |        * this is safe.... */ | 
 |       /* CancelIoEx is only Vista+. Since we have only one overlap | 
 |        * operation on this thread, we can just use: */ | 
 |       result = CancelIo (hfile); | 
 |       g_warn_if_fail (result); | 
 |     } | 
 |  | 
 |   result = GetOverlappedResult (overlap->hEvent, overlap, transferred, FALSE); | 
 |   if (result == FALSE && | 
 |       GetLastError () == ERROR_IO_INCOMPLETE && | 
 |       !g_cancellable_is_cancelled (cancellable)) | 
 |     goto loop; | 
 |  | 
 | end: | 
 |   if (num > 1) | 
 |     g_cancellable_release_fd (cancellable); | 
 |  | 
 |   return result; | 
 | } | 
 | #endif |