]> git.ipfire.org Git - thirdparty/open-vm-tools.git/commitdiff
unity/X11: Exit Unity upon notice of session termination.
authorVMware, Inc <>
Tue, 29 Mar 2011 20:17:24 +0000 (13:17 -0700)
committerMarcelo Vanzin <mvanzin@vmware.com>
Tue, 29 Mar 2011 20:17:24 +0000 (13:17 -0700)
During session termination, not exiting Unity until vmusr unloads the
plugin is racy.  By the time the Unity shutdown routine executes, it's
possible that the X server has already terminated (or at least severed
our connection to it).  Instead of waiting until then, we'll instead
exit Unity as soon as vmusr is alerted of a pending session termination,
_before_ vmusr returns its acknowledgement to the session manager.

Signed-off-by: Marcelo Vanzin <mvanzin@vmware.com>
open-vm-tools/services/plugins/unity/Makefile.am
open-vm-tools/services/plugins/unity/ghIntegration/platform.cc
open-vm-tools/services/plugins/unity/unityPluginEntry.cpp
open-vm-tools/services/plugins/unity/unityPluginPosix.cpp [new file with mode: 0644]
open-vm-tools/services/plugins/unity/unityPluginPosix.h [new file with mode: 0644]

index 01220d62a8981a4466adbc5b7ce7d8a8afdfd8d3..e9f2207bff4f910185441b79f9e6bf334ae20e2a 100644 (file)
@@ -54,6 +54,8 @@ libunity_la_SOURCES =
 libunity_la_SOURCES += unityPlugin.cpp
 libunity_la_SOURCES += unityPluginEntry.cpp
 libunity_la_SOURCES += unityPlugin.h
+libunity_la_SOURCES += unityPluginPosix.h
+libunity_la_SOURCES += unityPluginPosix.cpp
 libunity_la_SOURCES += ghiTclo.h
 libunity_la_SOURCES += ghiTclo.cpp
 libunity_la_SOURCES += unityTclo.h
index 00bcd975db71dbbdea6e8c6c94317c4ce4070245..cc98a320a52ac49ceae9a2461f80fad1fff6e3ba 100644 (file)
@@ -240,8 +240,13 @@ Bool
 GHIPlatformIsSupported(void)
 {
    const char *desktopEnv = Xdg_DetectDesktopEnv();
-   return    (g_strcmp0(desktopEnv, "GNOME") == 0)
-          || (g_strcmp0(desktopEnv, "KDE") == 0);
+   Bool supported = (g_strcmp0(desktopEnv, "GNOME") == 0) ||
+                    (g_strcmp0(desktopEnv, "KDE") == 0);
+   if (!supported) {
+      g_message("GHI not available under unsupported desktop environment %s\n",
+                desktopEnv ? desktopEnv : "(nil)");
+   }
+   return supported;
 }
 
 
@@ -271,6 +276,14 @@ GHIPlatformInit(GMainLoop *mainLoop,            // IN
 
    Gtk::Main::init_gtkmm_internals();
 
+   if (!GHIPlatformIsSupported()) {
+      /*
+       * Don't bother allocating resources if running under an unsupported
+       * desktop environment.
+       */
+      return NULL;
+   }
+
    ghip = (GHIPlatform *) Util_SafeCalloc(1, sizeof *ghip);
    ghip->appsByWindowExecutable =
       g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
@@ -283,6 +296,7 @@ GHIPlatformInit(GMainLoop *mainLoop,            // IN
    }
 
    desktopEnv = Xdg_DetectDesktopEnv();
+   ASSERT(desktopEnv); // Asserting based on GHIPlatformIsSupported check above.
    g_desktop_app_info_set_desktop_env(desktopEnv);
 
 #ifdef REDIST_GMENU
@@ -377,6 +391,9 @@ GHIPlatformCleanup(GHIPlatform *ghip) // IN
       return;
    }
 
+#ifdef REDIST_GMENU
+   delete ghip->menuItemManager;
+#endif
    g_hash_table_destroy(ghip->appsByWindowExecutable);
    free(ghip);
 }
index 978304993a511498a5f8b7adcddd67ad876edf4b..c14ac788918c6eb0b3f925d52a75e50ab5dd6942 100644 (file)
  *
  *    Implements the unity plugin for the tools services. Registers for the Unity
  *    RPC's and sets the Unity capabilities.
+ *
+ *    XXX Rewrite all of this to match CUI models and be, like, readable.
  */
 
 #define G_LOG_DOMAIN "unity"
 
 #include "unityPlugin.h"
 
+#ifndef WIN32
+#   include "unityPluginPosix.h"
+#endif
+
 extern "C" {
    #include "util.h"
    // guestrpc.h defines the RPCIn_Callback which is needed in rpcin.h which is in turn
@@ -42,6 +48,7 @@ extern "C" {
 
 using namespace vmware::tools;
 
+
 /*
  *-----------------------------------------------------------------------------
  *
@@ -258,7 +265,7 @@ ToolsOnLoad(ToolsAppCtx *ctx)           // IN: The app context.
 #if WIN32
       pluginInstance = new UnityPluginWin32();
 #else // Linux
-      pluginInstance = new UnityPlugin();
+      pluginInstance = new UnityPluginPosix();
 #endif
 
       if (!pluginInstance) {
diff --git a/open-vm-tools/services/plugins/unity/unityPluginPosix.cpp b/open-vm-tools/services/plugins/unity/unityPluginPosix.cpp
new file mode 100644 (file)
index 0000000..8687c0a
--- /dev/null
@@ -0,0 +1,193 @@
+/*********************************************************
+ * Copyright (C) 2011 VMware, Inc. All rights reserved.
+ *
+ * This program 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 version 2.1 and no later version.
+ *
+ * This program 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 Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+/*
+ * unityPluginPosix.cpp --
+ *
+ *    POSIX subclass of UnityPlugin interface.
+ */
+
+
+#include "unityPluginPosix.h"
+
+
+extern "C" {
+#include <glib-object.h>
+
+#include "vmware/tools/desktopevents.h"
+#if defined(OPEN_VM_TOOLS)
+   #include "unitylib/unity.h"
+#else
+   #include "unity.h"
+#endif // OPEN_VM_TOOLS
+}
+
+
+namespace vmware {
+namespace tools {
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * UnityPluginPosix::UnityPluginPosix --
+ *
+ *      Constructor.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+UnityPluginPosix::UnityPluginPosix()
+   : UnityPlugin(),
+     mCtx(NULL)
+{
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * UnityPluginPosix::~UnityPluginPosix --
+ *
+ *      Destructor.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+UnityPluginPosix::~UnityPluginPosix()
+{
+   if (mCtx) {
+      for (std::map<const char*, gulong>::iterator i = mSignalIDs.begin();
+           i != mSignalIDs.end();
+           ++i) {
+         g_signal_handler_disconnect(mCtx->serviceObj, i->second);
+      }
+   }
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * UnityPluginPosix::Initialize --
+ *
+ *      Initialize UnityPlugin base class and connect to X Session Manager
+ *      GLib signals.
+ *
+ * Results:
+ *      TRUE on success, FALSE otherwise.
+ *
+ * Side effects:
+ *      None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+gboolean
+UnityPluginPosix::Initialize(ToolsAppCtx* ctx)  // IN
+{
+   if (UnityPlugin::Initialize(ctx)) {
+      mCtx = ctx;
+      mSignalIDs[TOOLS_CORE_SIG_XSM_DIE] =
+         g_signal_connect(ctx->serviceObj, TOOLS_CORE_SIG_XSM_DIE,
+                          G_CALLBACK(XSMDieCb), static_cast<gpointer>(this));
+      return TRUE;
+   }
+
+   return FALSE;
+}
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * UnityPluginPosix::OnXSMEvent --
+ *
+ *      X Session Management event handler.  Exits Unity upon notice of session
+ *      termination.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      May trigger Unity exit.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+UnityPluginPosix::OnXSMDie()
+{
+   if (Unity_IsActive()) {
+      Unity_Exit();
+   }
+}
+
+
+/*
+ ******************************************************************************
+ * BEGIN Static member functions
+ */
+
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * UnityPluginPosix::XSMDieCb --
+ *
+ *      Thunk between XSM "die" OnXSMDie.
+ *
+ * Results:
+ *      None.
+ *
+ * Side effects:
+ *      See OnXSMDie.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+void
+UnityPluginPosix::XSMDieCb(GObject* obj,        // UNUSED
+                           ToolsAppCtx* ctx,    // UNUSED
+                           gpointer cbData)     // IN: UnityPluginPosix*
+{
+   UnityPluginPosix* unityPlugin = static_cast<UnityPluginPosix*>(cbData);
+   unityPlugin->OnXSMDie();
+}
+
+
+/*
+ * END Static member functions
+ ******************************************************************************
+ */
+
+
+} // namespace tools
+} // namespace vmware
diff --git a/open-vm-tools/services/plugins/unity/unityPluginPosix.h b/open-vm-tools/services/plugins/unity/unityPluginPosix.h
new file mode 100644 (file)
index 0000000..b78b3ac
--- /dev/null
@@ -0,0 +1,61 @@
+/*********************************************************
+ * Copyright (C) 2011 VMware, Inc. All rights reserved.
+ *
+ * This program 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 version 2.1 and no later version.
+ *
+ * This program 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 Lesser GNU General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA.
+ *
+ *********************************************************/
+
+/*
+ * unityPluginPosix.h --
+ *
+ *    POSIX subclass of UnityPlugin interface.
+ */
+
+#ifndef UNITY_PLUGIN_POSIX_H
+#define UNITY_PLUGIN_POSIX_H
+
+#include <map>
+
+#include "unityPlugin.h"
+
+extern "C" {
+#include <glib-object.h>
+}
+
+
+namespace vmware {
+namespace tools {
+
+class UnityPluginPosix
+   : public UnityPlugin
+{
+public:
+   UnityPluginPosix();
+   virtual ~UnityPluginPosix();
+
+   gboolean Initialize(ToolsAppCtx* ctx);
+
+private:
+   static void XSMDieCb(GObject*, ToolsAppCtx*, gpointer);
+   void OnXSMDie();
+
+   ToolsAppCtx* mCtx;
+   std::map<const char*, gulong> mSignalIDs;
+};
+
+
+} // namespace tools
+} // namespace vmware
+
+#endif // UNITY_PLUGIN_POSIX_H