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
This commit is contained in:
Dave Townsend 2019-01-31 12:13:34 -08:00
parent 35a7ffebca
commit efa98f92fe
4 changed files with 58 additions and 38 deletions

View File

@ -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'

View File

@ -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<nsIFile> 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) {

View File

@ -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<nsRemoteServer> mRemoteServer;
nsProfileLock mRemoteLock;
nsCOMPtr<nsIFile> mRemoteLockDir;
};
#endif // __nsRemoteService_h__

View File

@ -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<nsIProfileLock> mProfileLock;
#if defined(MOZ_WIDGET_GTK)
RefPtr<nsRemoteService> mRemoteService;
nsProfileLock mRemoteLock;
nsCOMPtr<nsIFile> mRemoteLockDir;
#endif
UniquePtr<ScopedXPCOMStartup> mScopedXPCOM;
@ -3919,35 +3915,7 @@ int XREMain::XRE_mainStartup(bool* aExitFlag) {
// later.
CheckArg("p", &profile, CheckArgFlag::None);
nsCOMPtr<nsIFile> 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 */