[glib] win32: make gio stream cancellable
- From: Marc-Andre Lureau <malureau src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib] win32: make gio stream cancellable
- Date: Mon, 20 Aug 2012 16:03:17 +0000 (UTC)
commit b9d7b80897d79cb43c4a795c7d9d3d9a24e140cc
Author: Marc-Andrà Lureau <marcandre lureau gmail com>
Date: Fri Jul 6 00:46:32 2012 +0200
win32: make gio stream cancellable
v2:
- fix cancellation of concurrent readers
- replace g_assert() usage with g_warn_if_fail()
v3:
- fix indentation
- fix loop code to not leak (silly me)
https://bugzilla.gnome.org/show_bug.cgi?id=679288
gio/gasynchelper.c | 29 +++++++++++++++++++++++++----
1 files changed, 25 insertions(+), 4 deletions(-)
---
diff --git a/gio/gasynchelper.c b/gio/gasynchelper.c
index fa6c816..ab8bd2c 100644
--- a/gio/gasynchelper.c
+++ b/gio/gasynchelper.c
@@ -174,9 +174,9 @@ gboolean
_g_win32_overlap_wait_result (HANDLE hfile,
OVERLAPPED *overlap,
DWORD *transferred,
- GCancellable *cancellable G_GNUC_UNUSED)
+ GCancellable *cancellable)
{
- GPollFD pollfd[1] = { 0, };
+ GPollFD pollfd[2];
gboolean result = FALSE;
gint num, npoll;
@@ -184,15 +184,36 @@ _g_win32_overlap_wait_result (HANDLE hfile,
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;
- /* either cancelled or IO completed, either way get the result */
- result = GetOverlappedResult (overlap->hEvent, overlap, transferred, TRUE);
+ 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
+ * operaton 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
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]