From efa98f92fe04b45d62a889826ef0817b6971814c Mon Sep 17 00:00:00 2001 From: Dave Townsend Date: Thu, 31 Jan 2019 12:13:34 -0800 Subject: [PATCH] Bug 1518639: Move startup locking to the remote service. r=jimm Makes nsRemoteService responsible for the shared lock for the time between attempting to contact a remote server and starting up our own server. Differential Revision: https://phabricator.services.mozilla.com/D19070 --HG-- extra : rebase_source : d2191966989c1b6db0dfb0db91f1b27d85046835 extra : intermediate-source : 405ea32162ba129b0c3e9ed75c9de13259d2d759 extra : source : 4da03e7a957c180d5997e3d8f6903b22f9a800c4 --- toolkit/components/remote/moz.build | 3 ++ toolkit/components/remote/nsRemoteService.cpp | 46 +++++++++++++++++++ toolkit/components/remote/nsRemoteService.h | 7 +++ toolkit/xre/nsAppRunner.cpp | 40 +--------------- 4 files changed, 58 insertions(+), 38 deletions(-) diff --git a/toolkit/components/remote/moz.build b/toolkit/components/remote/moz.build index e057e3f4da7e..cae11a4ea6f0 100644 --- a/toolkit/components/remote/moz.build +++ b/toolkit/components/remote/moz.build @@ -27,4 +27,7 @@ if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']: CXXFLAGS += CONFIG['MOZ_DBUS_GLIB_CFLAGS'] CXXFLAGS += CONFIG['TK_CFLAGS'] +LOCAL_INCLUDES += [ + '../../profile', +] FINAL_LIBRARY = 'xul' diff --git a/toolkit/components/remote/nsRemoteService.cpp b/toolkit/components/remote/nsRemoteService.cpp index 867ca2d291fd..46fa354df906 100644 --- a/toolkit/components/remote/nsRemoteService.cpp +++ b/toolkit/components/remote/nsRemoteService.cpp @@ -18,6 +18,11 @@ #include "nsString.h" #include "nsServiceManagerUtils.h" #include "mozilla/ModuleUtils.h" +#include "SpecialSystemDirectory.h" + +// Time to wait for the remoting service to start +#define START_TIMEOUT_SEC 5 +#define START_SLEEP_MSEC 100 using namespace mozilla; @@ -26,6 +31,47 @@ extern char** gArgv; NS_IMPL_ISUPPORTS(nsRemoteService, nsIObserver) +void nsRemoteService::LockStartup(nsCString& aProgram, const char* aProfile) { + nsCOMPtr mutexDir; + nsresult rv = GetSpecialSystemDirectory(OS_TemporaryDirectory, + getter_AddRefs(mutexDir)); + if (NS_SUCCEEDED(rv)) { + nsAutoCString mutexPath(aProgram); + if (aProfile) { + mutexPath.Append(NS_LITERAL_CSTRING("_") + nsDependentCString(aProfile)); + } + mutexDir->AppendNative(mutexPath); + + rv = mutexDir->Create(nsIFile::DIRECTORY_TYPE, 0700); + if (NS_SUCCEEDED(rv) || rv == NS_ERROR_FILE_ALREADY_EXISTS) { + mRemoteLockDir = mutexDir; + } + } + + if (mRemoteLockDir) { + const mozilla::TimeStamp epoch = mozilla::TimeStamp::Now(); + do { + rv = mRemoteLock.Lock(mRemoteLockDir, nullptr); + if (NS_SUCCEEDED(rv)) break; + PR_Sleep(START_SLEEP_MSEC); + } while ((mozilla::TimeStamp::Now() - epoch) < + mozilla::TimeDuration::FromSeconds(START_TIMEOUT_SEC)); + if (NS_FAILED(rv)) { + NS_WARNING("Cannot lock remote start mutex"); + } + } +} + +void nsRemoteService::UnlockStartup() { + mRemoteLock.Unlock(); + mRemoteLock.Cleanup(); + + if (mRemoteLockDir) { + mRemoteLockDir->Remove(false); + mRemoteLockDir = nullptr; + } +} + RemoteResult nsRemoteService::StartClient(const char* aDesktopStartupID, nsCString& program, const char* profile) { diff --git a/toolkit/components/remote/nsRemoteService.h b/toolkit/components/remote/nsRemoteService.h index 5ab559a63ad0..276197ed5bf4 100644 --- a/toolkit/components/remote/nsRemoteService.h +++ b/toolkit/components/remote/nsRemoteService.h @@ -13,6 +13,8 @@ #include "nsIObserver.h" #include "nsPIDOMWindow.h" #include "mozilla/UniquePtr.h" +#include "nsIFile.h" +#include "nsProfileLock.h" enum RemoteResult { REMOTE_NOT_FOUND = 0, @@ -28,6 +30,9 @@ class nsRemoteService final : public nsIObserver { nsRemoteService() = default; + void LockStartup(nsCString& aProgram, const char* aProfile); + void UnlockStartup(); + RemoteResult StartClient(const char* aDesktopStartupID, nsCString& program, const char* profile); void StartupServer(const char* aAppName, const char* aProfileName); @@ -37,6 +42,8 @@ class nsRemoteService final : public nsIObserver { ~nsRemoteService(); mozilla::UniquePtr mRemoteServer; + nsProfileLock mRemoteLock; + nsCOMPtr mRemoteLockDir; }; #endif // __nsRemoteService_h__ diff --git a/toolkit/xre/nsAppRunner.cpp b/toolkit/xre/nsAppRunner.cpp index 9b08d0ff3f2b..94722ec5cb09 100644 --- a/toolkit/xre/nsAppRunner.cpp +++ b/toolkit/xre/nsAppRunner.cpp @@ -196,8 +196,6 @@ # ifdef MOZ_ENABLE_DBUS # include "nsDBusRemoteClient.h" # endif -// Time to wait for the remoting service to start -# define MOZ_XREMOTE_START_TIMEOUT_SEC 5 #endif #if defined(DEBUG) && defined(XP_WIN32) @@ -2882,8 +2880,6 @@ class XREMain { nsCOMPtr mProfileLock; #if defined(MOZ_WIDGET_GTK) RefPtr mRemoteService; - nsProfileLock mRemoteLock; - nsCOMPtr mRemoteLockDir; #endif UniquePtr mScopedXPCOM; @@ -3919,35 +3915,7 @@ int XREMain::XRE_mainStartup(bool* aExitFlag) { // later. CheckArg("p", &profile, CheckArgFlag::None); - nsCOMPtr mutexDir; - rv = GetSpecialSystemDirectory(OS_TemporaryDirectory, - getter_AddRefs(mutexDir)); - if (NS_SUCCEEDED(rv)) { - nsAutoCString mutexPath = program; - if (profile) { - mutexPath.Append(NS_LITERAL_CSTRING("_") + - nsDependentCString(profile)); - } - mutexDir->AppendNative(mutexPath); - - rv = mutexDir->Create(nsIFile::DIRECTORY_TYPE, 0700); - if (NS_SUCCEEDED(rv) || rv == NS_ERROR_FILE_ALREADY_EXISTS) { - mRemoteLockDir = mutexDir; - } - } - - if (mRemoteLockDir) { - const TimeStamp epoch = mozilla::TimeStamp::Now(); - do { - rv = mRemoteLock.Lock(mRemoteLockDir, nullptr); - if (NS_SUCCEEDED(rv)) break; - sched_yield(); - } while ((TimeStamp::Now() - epoch) < - TimeDuration::FromSeconds(MOZ_XREMOTE_START_TIMEOUT_SEC)); - if (NS_FAILED(rv)) { - NS_WARNING("Cannot lock XRemote start mutex"); - } - } + mRemoteService->LockStartup(program, profile); // Try to remote the entire command line. If this fails, start up // normally. @@ -4592,11 +4560,7 @@ nsresult XREMain::XRE_mainRun() { // proxy window. if (mRemoteService) { mRemoteService->StartupServer(mAppData->remotingName, mProfileName.get()); - } - if (mRemoteLockDir) { - mRemoteLock.Unlock(); - mRemoteLock.Cleanup(); - mRemoteLockDir->Remove(false); + mRemoteService->UnlockStartup(); } #endif /* MOZ_WIDGET_GTK */