Bug 1518639: Move the calls to the remote clients into nsRemoteService. r=jimm
authorDave Townsend <dtownsend@oxymoronical.com>
Thu, 31 Jan 2019 12:13:34 -0800
changeset 520638 34d973f8ea5b4acb22e4ad2a0ced65c2583f6397
parent 520637 2ac2c7a2a9a61bb33802721ff73163a1403f3c54
child 520639 b9d78d81a381350aa548ce7d6b640b93d57ebb7c
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjimm
bugs1518639
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1518639: Move the calls to the remote clients into nsRemoteService. r=jimm Makes nsRemoteService responsible for managing the clients too, simplifying nsAppRunner. Differential Revision: https://phabricator.services.mozilla.com/D19069
toolkit/components/remote/nsRemoteService.cpp
toolkit/components/remote/nsRemoteService.h
toolkit/xre/nsAppRunner.cpp
--- a/toolkit/components/remote/nsRemoteService.cpp
+++ b/toolkit/components/remote/nsRemoteService.cpp
@@ -2,31 +2,78 @@
 /* vim:expandtab:shiftwidth=2:tabstop=8:
  */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifdef MOZ_WIDGET_GTK
 #  include "nsGTKRemoteServer.h"
+#  include "nsXRemoteClient.h"
 #  ifdef MOZ_ENABLE_DBUS
 #    include "nsDBusRemoteServer.h"
+#    include "nsDBusRemoteClient.h"
 #  endif
 #endif
 #include "nsRemoteService.h"
 
 #include "nsString.h"
 #include "nsServiceManagerUtils.h"
 #include "mozilla/ModuleUtils.h"
 
 using namespace mozilla;
 
+extern int gArgc;
+extern char** gArgv;
+
 NS_IMPL_ISUPPORTS(nsRemoteService, nsIObserver)
 
-void nsRemoteService::Startup(const char* aAppName, const char* aProfileName) {
+RemoteResult nsRemoteService::StartClient(const char* aDesktopStartupID,
+                                          nsCString& program,
+                                          const char* profile) {
+  nsAutoPtr<nsRemoteClient> client;
+
+#ifdef MOZ_WIDGET_GTK
+  bool useX11Remote = GDK_IS_X11_DISPLAY(gdk_display_get_default());
+
+#  if defined(MOZ_ENABLE_DBUS)
+  if (!useX11Remote) {
+    client = new nsDBusRemoteClient();
+  }
+#  endif
+  if (useX11Remote) {
+    client = new nsXRemoteClient();
+  }
+
+  nsresult rv = client ? client->Init() : NS_ERROR_FAILURE;
+  if (NS_FAILED(rv)) return REMOTE_NOT_FOUND;
+
+  nsCString response;
+  bool success = false;
+  rv = client->SendCommandLine(program.get(), profile, gArgc, gArgv,
+                               aDesktopStartupID, getter_Copies(response),
+                               &success);
+  // did the command fail?
+  if (!success) return REMOTE_NOT_FOUND;
+
+  // The "command not parseable" error is returned when the
+  // nsICommandLineHandler throws a NS_ERROR_ABORT.
+  if (response.EqualsLiteral("500 command not parseable"))
+    return REMOTE_ARG_BAD;
+
+  if (NS_FAILED(rv)) return REMOTE_NOT_FOUND;
+
+  return REMOTE_FOUND;
+#else
+  return REMOTE_NOT_FOUND;
+#endif
+}
+
+void nsRemoteService::StartupServer(const char* aAppName,
+                                    const char* aProfileName) {
   if (mRemoteServer) {
     return;
   }
 
 #ifdef MOZ_WIDGET_GTK
   bool useX11Remote = GDK_IS_X11_DISPLAY(gdk_display_get_default());
 
 #  if defined(MOZ_ENABLE_DBUS)
@@ -49,20 +96,20 @@ void nsRemoteService::Startup(const char
   nsCOMPtr<nsIObserverService> obs(
       do_GetService("@mozilla.org/observer-service;1"));
   if (obs) {
     obs->AddObserver(this, "xpcom-shutdown", false);
     obs->AddObserver(this, "quit-application", false);
   }
 }
 
-void nsRemoteService::Shutdown() { mRemoteServer = nullptr; }
+void nsRemoteService::ShutdownServer() { mRemoteServer = nullptr; }
 
-nsRemoteService::~nsRemoteService() { Shutdown(); }
+nsRemoteService::~nsRemoteService() { ShutdownServer(); }
 
 NS_IMETHODIMP
 nsRemoteService::Observe(nsISupports* aSubject, const char* aTopic,
                          const char16_t* aData) {
   // This can be xpcom-shutdown or quit-application, but it's the same either
   // way.
-  Shutdown();
+  ShutdownServer();
   return NS_OK;
 }
--- a/toolkit/components/remote/nsRemoteService.h
+++ b/toolkit/components/remote/nsRemoteService.h
@@ -9,26 +9,34 @@
 #define __nsRemoteService_h__
 
 #include "nsRemoteServer.h"
 #include "nsIObserverService.h"
 #include "nsIObserver.h"
 #include "nsPIDOMWindow.h"
 #include "mozilla/UniquePtr.h"
 
+enum RemoteResult {
+  REMOTE_NOT_FOUND = 0,
+  REMOTE_FOUND = 1,
+  REMOTE_ARG_BAD = 2
+};
+
 class nsRemoteService final : public nsIObserver {
  public:
   // We will be a static singleton, so don't use the ordinary methods.
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
   nsRemoteService() = default;
 
-  void Startup(const char* aAppName, const char* aProfileName);
-  void Shutdown();
+  RemoteResult StartClient(const char* aDesktopStartupID, nsCString& program,
+                           const char* profile);
+  void StartupServer(const char* aAppName, const char* aProfileName);
+  void ShutdownServer();
 
  private:
   ~nsRemoteService();
 
   mozilla::UniquePtr<nsRemoteServer> mRemoteServer;
 };
 
 #endif  // __nsRemoteService_h__
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -399,22 +399,16 @@ static MOZ_FORMAT_PRINTF(2, 3) void Outp
   }
 #else
   vfprintf(stderr, fmt, ap);
 #endif
 
   va_end(ap);
 }
 
-enum RemoteResult {
-  REMOTE_NOT_FOUND = 0,
-  REMOTE_FOUND = 1,
-  REMOTE_ARG_BAD = 2
-};
-
 /**
  * Check for a commandline flag. If the flag takes a parameter, the
  * parameter is returned in aParam. Flags may be in the form -arg or
  * --arg (or /arg on win32).
  *
  * @param aArg the parameter to check. Must be lowercase.
  * @param aParam if non-null, the -arg <data> will be stored in this pointer.
  *        This is *not* allocated, but rather a pointer to the argv data.
@@ -1540,54 +1534,16 @@ static inline void DumpVersion() {
   printf("%s", NS_STRINGIFY(MOZ_APP_VERSION_DISPLAY));
 
   if (gAppData->copyright) {
     printf(", %s", (const char*)gAppData->copyright);
   }
   printf("\n");
 }
 
-#if defined(MOZ_WIDGET_GTK)
-static RemoteResult StartRemoteClient(const char* aDesktopStartupID,
-                                      nsCString& program, const char* profile) {
-  nsAutoPtr<nsRemoteClient> client;
-
-  bool useX11Remote = GDK_IS_X11_DISPLAY(gdk_display_get_default());
-
-#  if defined(MOZ_ENABLE_DBUS)
-  if (!useX11Remote) {
-    client = new nsDBusRemoteClient();
-  }
-#  endif
-  if (useX11Remote) {
-    client = new nsXRemoteClient();
-  }
-
-  nsresult rv = client ? client->Init() : NS_ERROR_FAILURE;
-  if (NS_FAILED(rv)) return REMOTE_NOT_FOUND;
-
-  nsCString response;
-  bool success = false;
-  rv = client->SendCommandLine(program.get(), profile, gArgc, gArgv,
-                               aDesktopStartupID, getter_Copies(response),
-                               &success);
-  // did the command fail?
-  if (!success) return REMOTE_NOT_FOUND;
-
-  // The "command not parseable" error is returned when the
-  // nsICommandLineHandler throws a NS_ERROR_ABORT.
-  if (response.EqualsLiteral("500 command not parseable"))
-    return REMOTE_ARG_BAD;
-
-  if (NS_FAILED(rv)) return REMOTE_NOT_FOUND;
-
-  return REMOTE_FOUND;
-}
-#endif  // MOZ_WIDGET_GTK
-
 void XRE_InitOmnijar(nsIFile* greOmni, nsIFile* appOmni) {
   mozilla::Omnijar::Init(greOmni, appOmni);
 }
 
 nsresult XRE_GetBinaryPath(nsIFile** aResult) {
   return mozilla::BinaryPath::GetFile(aResult);
 }
 
@@ -3948,64 +3904,70 @@ int XREMain::XRE_mainStartup(bool* aExit
       newInstance = true;
     } else {
       e = PR_GetEnv("MOZ_NEW_INSTANCE");
       newInstance = (e && *e);
     }
   }
 
   if (!newInstance) {
-    nsAutoCString program(gAppData->remotingName);
-    ToLowerCase(program);
-
-    const char* profile = nullptr;
-    // It doesn't matter if this succeeds or fails. A failure will be handled
-    // 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;
+    mRemoteService = new nsRemoteService();
+    if (mRemoteService) {
+      nsAutoCString program(gAppData->remotingName);
+      ToLowerCase(program);
+
+      const char* profile = nullptr;
+      // It doesn't matter if this succeeds or fails. A failure will be handled
+      // 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");
+
+      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");
+        }
       }
-    }
-
-    // Try to remote the entire command line. If this fails, start up normally.
-    const char* desktopStartupIDPtr =
-        mDesktopStartupID.IsEmpty() ? nullptr : mDesktopStartupID.get();
-
-    RemoteResult rr = StartRemoteClient(desktopStartupIDPtr, program, profile);
-    if (rr == REMOTE_FOUND) {
-      *aExitFlag = true;
-      return 0;
-    }
-    if (rr == REMOTE_ARG_BAD) {
-      return 1;
+
+      // Try to remote the entire command line. If this fails, start up
+      // normally.
+      const char* desktopStartupIDPtr =
+          mDesktopStartupID.IsEmpty() ? nullptr : mDesktopStartupID.get();
+
+      RemoteResult rr =
+          mRemoteService->StartClient(desktopStartupIDPtr, program, profile);
+      if (rr == REMOTE_FOUND) {
+        *aExitFlag = true;
+        return 0;
+      }
+      if (rr == REMOTE_ARG_BAD) {
+        return 1;
+      }
     }
   }
 #endif
 #if defined(MOZ_WIDGET_GTK)
   g_set_application_name(mAppData->name);
   gtk_window_set_auto_startup_notification(false);
 
 #endif /* defined(MOZ_WIDGET_GTK) */
@@ -4623,21 +4585,18 @@ nsresult XREMain::XRE_mainRun() {
 
     appStartup->GetShuttingDown(&mShuttingDown);
   }
 
   if (!mShuttingDown) {
 #if defined(MOZ_WIDGET_GTK)
     // if we have X remote support, start listening for requests on the
     // proxy window.
-    if (!mDisableRemote) {
-      mRemoteService = new nsRemoteService();
-    }
     if (mRemoteService) {
-      mRemoteService->Startup(mAppData->remotingName, mProfileName.get());
+      mRemoteService->StartupServer(mAppData->remotingName, mProfileName.get());
     }
     if (mRemoteLockDir) {
       mRemoteLock.Unlock();
       mRemoteLock.Cleanup();
       mRemoteLockDir->Remove(false);
     }
 #endif /* MOZ_WIDGET_GTK */
 
@@ -4838,17 +4797,17 @@ int XREMain::XRE_main(int argc, char* ar
     // In particular we don't want to poison IO for checking late-writes.
     gShutdownChecks = SCM_NOTHING;
   }
 
   if (!mShuttingDown) {
 #if defined(MOZ_WIDGET_GTK)
     // shut down the x remote proxy window
     if (mRemoteService) {
-      mRemoteService->Shutdown();
+      mRemoteService->ShutdownServer();
     }
 #endif /* MOZ_WIDGET_GTK */
   }
 
   mScopedXPCOM = nullptr;
 
 #if defined(XP_WIN)
   mozilla::widget::StopAudioSession();