w32: Use CancelSynchronousIo in destroy_reader.
authorWerner Koch <wk@gnupg.org>
Thu, 1 Nov 2018 08:55:24 +0000 (09:55 +0100)
committerWerner Koch <wk@gnupg.org>
Thu, 1 Nov 2018 08:55:24 +0000 (09:55 +0100)
* 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 <wk@gnupg.org>
src/sys-util.h
src/w32-io.c
src/w32-util.c

index 094399c..6cb2224 100644 (file)
@@ -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 */
index ad1e330..436bb7b 100644 (file)
@@ -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)
     {
index 7954189..8a04c8c 100644 (file)
@@ -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. */