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 */