From: VMware, Inc <> Date: Tue, 29 Mar 2011 20:17:24 +0000 (-0700) Subject: unity/X11: Exit Unity upon notice of session termination. X-Git-Tag: 2011.03.28-387002~25 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3108553496ec07875a52fbd7ee7db7dbcf2af071;p=thirdparty%2Fopen-vm-tools.git unity/X11: Exit Unity upon notice of session termination. 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 --- diff --git a/open-vm-tools/services/plugins/unity/Makefile.am b/open-vm-tools/services/plugins/unity/Makefile.am index 01220d62a..e9f2207bf 100644 --- a/open-vm-tools/services/plugins/unity/Makefile.am +++ b/open-vm-tools/services/plugins/unity/Makefile.am @@ -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 diff --git a/open-vm-tools/services/plugins/unity/ghIntegration/platform.cc b/open-vm-tools/services/plugins/unity/ghIntegration/platform.cc index 00bcd975d..cc98a320a 100644 --- a/open-vm-tools/services/plugins/unity/ghIntegration/platform.cc +++ b/open-vm-tools/services/plugins/unity/ghIntegration/platform.cc @@ -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); } diff --git a/open-vm-tools/services/plugins/unity/unityPluginEntry.cpp b/open-vm-tools/services/plugins/unity/unityPluginEntry.cpp index 978304993..c14ac7889 100644 --- a/open-vm-tools/services/plugins/unity/unityPluginEntry.cpp +++ b/open-vm-tools/services/plugins/unity/unityPluginEntry.cpp @@ -21,12 +21,18 @@ * * 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 index 000000000..8687c0a4c --- /dev/null +++ b/open-vm-tools/services/plugins/unity/unityPluginPosix.cpp @@ -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 + +#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::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(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(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 index 000000000..b78b3ac7f --- /dev/null +++ b/open-vm-tools/services/plugins/unity/unityPluginPosix.h @@ -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 + +#include "unityPlugin.h" + +extern "C" { +#include +} + + +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 mSignalIDs; +}; + + +} // namespace tools +} // namespace vmware + +#endif // UNITY_PLUGIN_POSIX_H