From 63ba09b541dabbe838253926896e721cb9be564a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Thu, 1 Nov 2018 09:55:24 +0100 Subject: [PATCH] w32: Use CancelSynchronousIo in destroy_reader. * src/w32-util.c (_gpgme_w32_cancel_synchronous_io): New. * src/w32-io.c (destroy_reader): Use it here. -- This has not been tested but should on Vista and later help to fix a possible hang. Signed-off-by: Werner Koch --- src/sys-util.h | 1 + src/w32-io.c | 2 +- src/w32-util.c | 42 +++++++++++++++++++++++++++++++++++++++--- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/sys-util.h b/src/sys-util.h index 094399c4..6cb22245 100644 --- a/src/sys-util.h +++ b/src/sys-util.h @@ -30,6 +30,7 @@ char *_gpgme_get_gpgconf_path (void); #ifdef HAVE_W32_SYSTEM const char *_gpgme_get_inst_dir (void); +void _gpgme_w32_cancel_synchronous_io (HANDLE thread); #endif #endif /* SYS_UTIL_H */ diff --git a/src/w32-io.c b/src/w32-io.c index ad1e330c..436bb7b2 100644 --- a/src/w32-io.c +++ b/src/w32-io.c @@ -485,7 +485,7 @@ destroy_reader (struct reader_context_s *ctx) dlopen that syscall. */ if (ctx->file_hd != INVALID_HANDLE_VALUE) { - /* Fixme: Call CancelSynchronousIo (handle_of_thread). */ + _gpgme_w32_cancel_synchronous_io (ctx->thread_hd); } else if (ctx->file_sock != INVALID_SOCKET) { diff --git a/src/w32-util.c b/src/w32-util.c index 79541898..8a04c8c1 100644 --- a/src/w32-util.c +++ b/src/w32-util.c @@ -99,8 +99,6 @@ static char *default_gpgconf_name; gpgme_set_global_flag and accessed by _gpgme_get_inst_dir. */ static char *override_inst_dir; -#ifdef HAVE_ALLOW_SET_FOREGROUND_WINDOW - #define RTLD_LAZY 0 static GPG_ERR_INLINE void * @@ -135,7 +133,6 @@ dlclose (void * hd) } return -1; } -#endif /* HAVE_ALLOW_SET_FOREGROUND_WINDOW */ /* Return a malloced string encoded in UTF-8 from the wide char input @@ -241,6 +238,45 @@ _gpgme_allow_set_foreground_window (pid_t pid) } +/* Wrapper around CancelSynchronousIo which is only available since + * Vista. */ +void +_gpgme_w32_cancel_synchronous_io (HANDLE thread) +{ + static int initialized; + static BOOL (WINAPI * func)(DWORD); + void *handle; + + if (!initialized) + { + /* Available since Vista; thus we dynload it. */ + initialized = 1; + handle = dlopen ("kerner32.dll", RTLD_LAZY); + if (handle) + { + func = dlsym (handle, "CancelSynchronousIo"); + if (!func) + { + dlclose (handle); + handle = NULL; + } + } + } + + if (func) + { + int rc = func (thread); + TRACE2 (DEBUG_ENGINE, "gpgme:CancelSynchronousIo", 0, + "called for thread %p; result=%d", thread, rc); + } + else + { + TRACE0 (DEBUG_ENGINE, "gpgme:CancelSynchronousIo", 0, + "function not available"); + } +} + + /* Return a string from the W32 Registry or NULL in case of error. Caller must release the return value. A NULL for root is an alias for HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE in turn. */