[git] GpgOL - branch, master, updated. gpgol-1.3.0-6-ged11229

by Andre Heinecke cvs at cvs.gnupg.org
Fri Nov 27 16:27:34 CET 2015


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GnuPG extension for MS Outlook".

The branch, master has been updated
       via  ed1122988eddb34e22ac37344a1ca2b328abdd4d (commit)
       via  2deba0f8820d2d1fd9c42dbb3ff37f1ccd765e4b (commit)
       via  e5be7ebd8e4c61c70f4c307f3faa63a81c1a213b (commit)
      from  eb8f1fbb6af9f9114e718c5ceaf4b62662fccc45 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit ed1122988eddb34e22ac37344a1ca2b328abdd4d
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Fri Nov 27 16:23:57 2015 +0100

    Start UIServer on demand
    
    * src/engine-assuan.c (op_assuan_init): Don't test connection.
    --
    The old spawning code with the retry counter made this unfeasible.
    Starting on demand has the charm that it is properly handled
    if the user stops the UIServer or the UIServer crashes (which of course
    only Kleo does).
    
    This should also give us a big boost in the startup timing benchmark
    Outlook runs to suggest "Addins that are making Outlook slow".
    
    GnuPG-Bug-Id: 2137

diff --git a/src/engine-assuan.c b/src/engine-assuan.c
index 633dd2e..ffb8cee 100644
--- a/src/engine-assuan.c
+++ b/src/engine-assuan.c
@@ -597,27 +597,10 @@ int
 op_assuan_init (void)
 {
   static int init_done;
-  gpgme_error_t err;
-  assuan_context_t ctx;
-  pid_t pid;
-  ULONG cmdid;
 
   if (init_done)
     return 0;
-  
-  /* Reset the retry counter.  */
-  connect_uiserver (NULL, NULL, NULL, NULL);
 
-  /* Run a test connection to see whether the UI server is available.  */
-  err = connect_uiserver (&ctx, &pid, &cmdid, NULL);
-  if (!err)
-    {
-      err = assuan_transact (ctx, "NOP", NULL, NULL, NULL, NULL, NULL, NULL);
-      assuan_release (ctx);
-    }
-  if (err)
-    return err;
-  
   /* Fire up the pipe worker thread. */
   {
     HANDLE th;

commit 2deba0f8820d2d1fd9c42dbb3ff37f1ccd765e4b
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Fri Nov 27 16:22:13 2015 +0100

    Rework connect_uiserver call based on gpgex
    
    * src/engine-assuan.c (connect_uiserver): Use proper locking. Improve
     retry handling.

diff --git a/src/engine-assuan.c b/src/engine-assuan.c
index f3422e3..633dd2e 100644
--- a/src/engine-assuan.c
+++ b/src/engine-assuan.c
@@ -32,6 +32,7 @@
 #include "engine.h"
 #include "engine-assuan.h"
 #include "util.h"
+#include "exechelp.h"
 
 /* Debug macros.  */
 #define debug_ioworker        (opt.enable_debug & DBG_IOWORKER)
@@ -469,92 +470,93 @@ static gpg_error_t
 connect_uiserver (assuan_context_t *r_ctx, pid_t *r_pid, ULONG *r_cmdid,
                   void *hwnd)
 {
-  static ULONG retry_counter;
-  ULONG retry_count;
-  gpg_error_t err;
-  assuan_context_t ctx;
-
-  if (!r_ctx && !r_pid && !r_cmdid && !hwnd)
-    {
-      InterlockedExchange (&retry_counter, 0);
-      return 0;
-    }
-
+  gpg_error_t rc;
+  const char *socket_name = NULL;
+  lock_spawn_t lock;
 
   *r_ctx = NULL;
   *r_pid = (pid_t)(-1);
   *r_cmdid = 0;
-  err = assuan_new (&ctx);
-  if (err)
+
+  socket_name = get_socket_name();
+  if (!socket_name || !*socket_name)
     {
-      InterlockedExchange (&retry_counter, 0);
-      return 0;
+      log_error ("%s:%s: Invalid socket name",
+                 SRCNAME, __func__);
+      return gpg_error (GPG_ERR_INV_ARG);
     }
-      
- retry:
-  err = assuan_socket_connect (ctx, get_socket_name (), -1, 0);
-  if (err)
+
+  rc = assuan_new (r_ctx);
+  if (rc)
     {
-      /* Let only one thread start an UI server but all allow threads
-         to check for a connection.  Note that this is not really
-         correct as the maximum waiting time decreases with the number
-         of threads.  However, it is unlikely that we have more than 2
-         or 3 threads here - if at all more than one.  */
-      retry_count = InterlockedExchangeAdd (&retry_counter, 1);
-      if (retry_count < FIREUP_RETRIES)
+      log_error ("%s:%s: Could not allocate context",
+                 SRCNAME, __func__);
+      return rc;
+    }
+
+  rc = assuan_socket_connect (*r_ctx, socket_name, -1, 0);
+  if (rc)
+    {
+      int count;
+
+      log_debug ("%s:%s: UI server not running at: \"%s\", starting it",
+                 SRCNAME, __func__, socket_name);
+
+      /* Now try to connect again with the spawn lock taken.  */
+      if (!(rc = gpgol_lock_spawning (&lock))
+          && assuan_socket_connect (*r_ctx, socket_name, -1, 0))
         {
-          if (!retry_count)
+          char *uiserver = get_uiserver_name ();
+          if (!uiserver)
             {
-              char *uiserver = get_uiserver_name ();
-              if (!uiserver)
-                {
-                  log_error ("%s:%s: UI server not installed",
-                             SRCNAME, __func__);
-                  InterlockedExchange (&retry_counter, FIREUP_RETRIES);
-                  retry_count = FIREUP_RETRIES;
-                }
-              else
-                {
-                  log_debug ("%s:%s: UI server not running, starting `%s'",
-                             SRCNAME, __func__, uiserver);
-                  if (gpgol_spawn_detached (uiserver))
-                    {
-                      /* Error; try again to connect in case the
-                         server has been started in the meantime.
-                         Make sure that we don't get here a second
-                         time.  */
-                      InterlockedExchange (&retry_counter, FIREUP_RETRIES);
-                    }
-                  xfree (uiserver);
-                }
+              log_error ("%s:%s: UI server not installed",
+                         SRCNAME, __func__);
+              assuan_release (*r_ctx);
+              *r_ctx = NULL;
+              return GPG_ERR_GENERAL;
             }
-          if (retry_count < FIREUP_RETRIES)
+          rc = gpgol_spawn_detached (uiserver);
+          xfree (uiserver);
+          if (!rc)
             {
-              log_debug ("%s:%s: waiting for UI server to come up",
-                         SRCNAME, __func__);
-              Sleep (1000);
-              goto retry;
+              /* Give it a bit of time to start up and try a couple of
+                 times.  */
+              for (count = 0; count < 10; count++)
+                {
+                  Sleep (1000);
+                  rc = assuan_socket_connect (*r_ctx, socket_name, -1, 0);
+                  if (!rc)
+                    break;
+                }
             }
-        }
-      else
-        {
-          /* Avoid a retry counter overflow by limiting to the limit.  */
-          InterlockedExchange (&retry_counter, FIREUP_RETRIES);
-        }
 
-      log_error ("%s:%s: error connecting `%s': %s\n", SRCNAME, __func__,
-                 get_socket_name (), gpg_strerror (err));
+        }
+      gpgol_unlock_spawning (&lock);
     }
-  else if ((err = send_options (ctx, hwnd, r_pid)))
+
+  if (rc)
     {
-      assuan_release (ctx);
+      log_error ("%s:%s: UI Server failed to start",
+                 SRCNAME, __func__);
+      assuan_release (*r_ctx);
+      *r_ctx = NULL;
+      return rc;
     }
-  else
+#if 0
+ // Something for later
+      if (debug_flags & DEBUG_ASSUAN)
+        assuan_set_log_stream (*ctx, debug_file);
+#endif
+  rc = send_options (*r_ctx, hwnd, r_pid);
+  if (rc)
     {
-      *r_cmdid = create_command_id ();
-      *r_ctx = ctx;
+      assuan_release (*r_ctx);
+      *r_ctx = NULL;
+      return rc;
     }
-  return err;
+  *r_cmdid = create_command_id ();
+
+  return 0;
 }
 
 

commit e5be7ebd8e4c61c70f4c307f3faa63a81c1a213b
Author: Andre Heinecke <aheinecke at intevation.de>
Date:   Fri Nov 27 16:15:47 2015 +0100

    Add process spawning code from gpgex
    
    * src/common.c, src/common.h (gpgol_spawn_detached): New.
    * src/exechelp.h, src/exechelp.c: New.
    * src/Makefile.am: Add exechelp files.
    
    --
    While the spawning in gpgol_spawn_detached was quite similar
    it makes sense to move that out in it's own source file and
    use the same mutex that gpgex uses.

diff --git a/src/Makefile.am b/src/Makefile.am
index cc0aea8..6e02fb4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -84,7 +84,8 @@ gpgol_SOURCES = \
 	mail.h mail.cpp \
 	rfc2047parse.h rfc2047parse.c \
 	mlang-charset.cpp mlang-charset.h \
-	gmime-table-private.h
+	gmime-table-private.h \
+	exechelp.c exechelp.h
 
 
 #treeview_SOURCES = treeview.c
diff --git a/src/common.c b/src/common.c
index fd53592..bf1c9e9 100644
--- a/src/common.c
+++ b/src/common.c
@@ -965,57 +965,6 @@ generate_boundary (char *buffer)
 }
 
 
-/* Fork and exec the program given in CMDLINE with /dev/null as
-   stdin, stdout and stderr.  Returns 0 on success.  */
-int
-gpgol_spawn_detached (const char *cmdline)
-{
-  int rc;
-  SECURITY_ATTRIBUTES sec_attr;
-  PROCESS_INFORMATION pi = { NULL, 0, 0, 0 };
-  STARTUPINFO si;
-  int cr_flags;
-  char *cmdline_copy;
-
-  memset (&sec_attr, 0, sizeof sec_attr);
-  sec_attr.nLength = sizeof sec_attr;
-  
-  memset (&si, 0, sizeof si);
-  si.cb = sizeof (si);
-  si.dwFlags = STARTF_USESHOWWINDOW;
-  si.wShowWindow = SW_SHOW;
-
-  cr_flags = (CREATE_DEFAULT_ERROR_MODE
-              | GetPriorityClass (GetCurrentProcess ())
-	      | CREATE_NEW_PROCESS_GROUP
-              | DETACHED_PROCESS); 
-
-  cmdline_copy = xstrdup (cmdline);
-  rc = CreateProcess (NULL,          /* No appliactionname, use CMDLINE.  */
-                      cmdline_copy,  /* Command line arguments.  */
-                      &sec_attr,     /* Process security attributes.  */
-                      &sec_attr,     /* Thread security attributes.  */
-                      FALSE,          /* Inherit handles.  */
-                      cr_flags,      /* Creation flags.  */
-                      NULL,          /* Environment.  */
-                      NULL,          /* Use current drive/directory.  */
-                      &si,           /* Startup information. */
-                      &pi            /* Returns process information.  */
-                      );
-  xfree (cmdline_copy);
-  if (!rc)
-    {
-      log_error_w32 (-1, "%s:%s: CreateProcess failed", SRCNAME, __func__);
-      return -1;
-    }
-
-  CloseHandle (pi.hThread); 
-  CloseHandle (pi.hProcess);
-  return 0;
-}
-
-
-
 /* Percent-escape the string STR by replacing colons with '%3a'.  If
    EXTRA is not NULL all characters in it are also escaped. */
 char *
diff --git a/src/common.h b/src/common.h
index 1d46515..379a55c 100644
--- a/src/common.h
+++ b/src/common.h
@@ -202,8 +202,6 @@ wchar_t *get_pretty_attachment_name (wchar_t *path, protocol_t protocol,
 #define BOUNDARYSIZE 20
 char *generate_boundary (char *buffer);
 
-int gpgol_spawn_detached (const char *cmdline);
-
 /*-- recipient-dialog.c --*/
 unsigned int recipient_dialog_box (gpgme_key_t **ret_rset);
 unsigned int recipient_dialog_box2 (gpgme_key_t *fnd, char **unknown,
diff --git a/src/exechelp.c b/src/exechelp.c
new file mode 100644
index 0000000..5d2a5bf
--- /dev/null
+++ b/src/exechelp.c
@@ -0,0 +1,145 @@
+/* exechelp.c - fork and exec helpers
+ * Copyright (C) 2004, 2007, 2014 g10 Code GmbH
+ * Copyright (C) 2015 Intevation GmbH
+ *
+ * This file is part of GpgOL.
+ *
+ * GpgOL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgOL 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <windows.h>
+
+#include <gpg-error.h>
+
+#include "common.h"
+#include "exechelp.h"
+
+/* Define to 1 do enable debugging.  */
+#define DEBUG_W32_SPAWN 0
+
+
+

+
+/* Lock a spawning process.  The caller needs to provide the address
+   of a variable to store the lock information and the name or the
+   process.  */
+gpg_error_t
+gpgol_lock_spawning (lock_spawn_t *lock)
+{
+  int waitrc;
+  int timeout = 5;
+
+  *lock = CreateMutexW (NULL, FALSE, L"spawn_gnupg_uiserver_sentinel");
+  if (!*lock)
+    {
+      log_error ("failed to create the spawn mutex: rc=%ld", GetLastError ());
+      return gpg_error (GPG_ERR_GENERAL);
+    }
+
+ retry:
+  waitrc = WaitForSingleObject (*lock, 1000);
+  if (waitrc == WAIT_OBJECT_0)
+    return 0;
+
+  if (waitrc == WAIT_TIMEOUT && timeout)
+    {
+      timeout--;
+      goto retry;
+    }
+  if (waitrc == WAIT_TIMEOUT)
+    log_error ("error waiting for the spawn mutex: timeout");
+  else
+    log_error ("error waiting for the spawn mutex: (code=%d) rc=%ld",
+                waitrc, GetLastError ());
+  return gpg_error (GPG_ERR_GENERAL);
+}
+
+
+/* Unlock the spawning process.  */
+void
+gpgol_unlock_spawning (lock_spawn_t *lock)
+{
+  if (*lock)
+    {
+      if (!ReleaseMutex (*lock))
+        log_error ("failed to release the spawn mutex: rc=%ld", GetLastError());
+      CloseHandle (*lock);
+      *lock = NULL;
+    }
+}
+
+
+/* Fork and exec the program with /dev/null as stdin, stdout and
+   stderr.  Returns 0 on success or an error code.  */
+gpg_error_t
+gpgol_spawn_detached (const char *cmdline)
+{
+  SECURITY_ATTRIBUTES sec_attr;
+  PROCESS_INFORMATION pi =
+    {
+      NULL,      /* Returns process handle.  */
+      0,         /* Returns primary thread handle.  */
+      0,         /* Returns pid.  */
+      0          /* Returns tid.  */
+    };
+  STARTUPINFO si;
+  int cr_flags;
+
+  log_debug ("gpgol_spawn_detached cmdline=%s", cmdline);
+
+  /* Prepare security attributes.  */
+  memset (&sec_attr, 0, sizeof sec_attr);
+  sec_attr.nLength = sizeof sec_attr;
+  sec_attr.bInheritHandle = FALSE;
+
+  /* Start the process.  Note that we can't run the PREEXEC function
+     because this would change our own environment. */
+  memset (&si, 0, sizeof si);
+  si.cb = sizeof (si);
+  si.dwFlags = STARTF_USESHOWWINDOW;
+  si.wShowWindow = DEBUG_W32_SPAWN ? SW_SHOW : SW_MINIMIZE;
+
+  cr_flags = (CREATE_DEFAULT_ERROR_MODE
+              | GetPriorityClass (GetCurrentProcess ())
+              | CREATE_NEW_PROCESS_GROUP
+              | DETACHED_PROCESS);
+
+  if (!CreateProcess (NULL,          /* pgmname; Program to start.  */
+                      (char *) cmdline, /* Command line arguments.  */
+                      &sec_attr,     /* Process security attributes.  */
+                      &sec_attr,     /* Thread security attributes.  */
+                      TRUE,          /* Inherit handles.  */
+                      cr_flags,      /* Creation flags.  */
+                      NULL,          /* Environment.  */
+                      NULL,          /* Use current drive/directory.  */
+                      &si,           /* Startup information. */
+                      &pi            /* Returns process information.  */
+                      ))
+    {
+      log_error ("CreateProcess failed: %ld\n", GetLastError ());
+      return gpg_error (GPG_ERR_GENERAL);
+    }
+
+  /* Process has been created suspended; resume it now. */
+  CloseHandle (pi.hThread);
+  CloseHandle (pi.hProcess);
+
+  return 0;
+}
diff --git a/src/exechelp.h b/src/exechelp.h
new file mode 100644
index 0000000..5f4c9f4
--- /dev/null
+++ b/src/exechelp.h
@@ -0,0 +1,50 @@
+/* exechelp.h - fork and exec helpers
+ * Copyright (C) 2004, 2007 g10 Code GmbH
+ * Copyright (C) 2015 Intevation GmbH
+ *
+ * This file is part of GpgOL.
+ *
+ * GpgOL is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * GpgOL 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#ifndef GPGOL_EXECHELP_H
+#define GPGOL_EXECHELP_H
+
+#include <gpg-error.h>
+
+#ifdef __cplusplus
+extern "C" {
+#if 0
+}
+#endif
+#endif
+
+#define lock_spawn_t HANDLE
+
+gpg_error_t gpgol_lock_spawning (lock_spawn_t *lock);
+void gpgol_unlock_spawning (lock_spawn_t *lock);
+
+/* Fork and exec CMDLINE with /dev/null as stdin, stdout and stderr.
+   Returns 0 on success or an error code.  */
+gpg_error_t gpgol_spawn_detached (const char *cmdline);
+
+#ifdef __cplusplus
+#if 0
+{
+#endif
+}
+#endif
+
+#endif /* GPGOL_EXECHELP_H */

-----------------------------------------------------------------------

Summary of changes:
 src/Makefile.am     |   3 +-
 src/common.c        |  51 -----------------
 src/common.h        |   2 -
 src/engine-assuan.c | 155 ++++++++++++++++++++++++----------------------------
 src/exechelp.c      | 145 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/exechelp.h      |  50 +++++++++++++++++
 6 files changed, 267 insertions(+), 139 deletions(-)
 create mode 100644 src/exechelp.c
 create mode 100644 src/exechelp.h


hooks/post-receive
-- 
GnuPG extension for MS Outlook
http://git.gnupg.org




More information about the Gnupg-commits mailing list