Bug 630703: Provide a way to restart in 32-bit mode. r=josh, r=bsmedberg, a=blocks-betaN
authorDave Townsend <dtownsend@oxymoronical.com>
Thu, 03 Feb 2011 09:27:00 -0800
changeset 61862 f00b81064d570e372b70ac673ca4b00c40556f2e
parent 61861 3c87074d5f50d069edf461fe21d86a5b558cfd98
child 61863 4b90fd0c1c4d249436d38b6a07a7e77e1fb79c90
push idunknown
push userunknown
push dateunknown
reviewersjosh, bsmedberg, blocks-betaN
bugs630703
milestone2.0b12pre
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 630703: Provide a way to restart in 32-bit mode. r=josh, r=bsmedberg, a=blocks-betaN
toolkit/components/startup/public/nsIAppStartup.idl
toolkit/components/startup/src/nsAppStartup.cpp
toolkit/xre/MacLaunchHelper.h
toolkit/xre/MacLaunchHelper.mm
toolkit/xre/nsAppRunner.cpp
--- a/toolkit/components/startup/public/nsIAppStartup.idl
+++ b/toolkit/components/startup/public/nsIAppStartup.idl
@@ -100,16 +100,28 @@ interface nsIAppStartup : nsISupports
 
     /**
      * Restart the application after quitting.  The application will be
      * restarted with the same profile and an empty command line.
      */
     const PRUint32 eRestart = 0x10; 
 
     /**
+     * When restarting attempt to start in the i386 architecture. Only supported
+     * on OSX.
+     */
+    const PRUint32 eRestarti386 = 0x20;
+
+    /**
+     * When restarting attempt to start in the x86_64 architecture. Only
+     * supported on OSX.
+     */
+    const PRUint32 eRestartx86_64 = 0x40;
+
+    /**
      * Exit the event loop, and shut down the app.
      *
      * @param aMode
      *        This parameter modifies how the app is shutdown, and it is
      *        constructed from the constants defined above.
      */
     void quit(in PRUint32 aMode);
 };
--- a/toolkit/components/startup/src/nsAppStartup.cpp
+++ b/toolkit/components/startup/src/nsAppStartup.cpp
@@ -94,16 +94,18 @@ static NS_DEFINE_CID(kAppShellCID, NS_AP
 #ifdef MOZ_ENABLE_LIBXUL
 extern PRTime gXRE_mainTimestamp;
 extern PRTime gFirstPaintTimestamp;
 #endif
 // mfinklesessionstore-browser-state-restored might be a better choice than the one below
 static PRTime gRestoredTimestamp = 0;       // Timestamp of sessionstore-windows-restored
 static PRTime gProcessCreationTimestamp = 0;// Timestamp of sessionstore-windows-restored
 
+PRUint32 gRestartMode = 0;
+
 class nsAppExitEvent : public nsRunnable {
 private:
   nsRefPtr<nsAppStartup> mService;
 
 public:
   nsAppExitEvent(nsAppStartup *service) : mService(service) {}
 
   NS_IMETHOD Run() {
@@ -284,18 +286,20 @@ nsAppStartup::Quit(PRUint32 aMode)
             if (!domWindow->CanClose())
               return NS_OK;
           }
         }
       }
     }
 
     mShuttingDown = PR_TRUE;
-    if (!mRestart)
+    if (!mRestart) {
       mRestart = (aMode & eRestart) != 0;
+      gRestartMode = (aMode & 0xF0);
+    }
 
     if (mRestart) {
       // Firefox-restarts reuse the process. Process start-time isn't a useful indicator of startup time
       PR_SetEnv(PR_smprintf("MOZ_APP_RESTART=%lld", (PRInt64) PR_Now()));
     }
 
     obsService = mozilla::services::GetObserverService();
 
--- a/toolkit/xre/MacLaunchHelper.h
+++ b/toolkit/xre/MacLaunchHelper.h
@@ -35,12 +35,12 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #ifndef MacLaunchHelper_h_
 #define MacLaunchHelper_h_
 
 extern "C" {
-  void LaunchChildMac(int aArgc, char** aArgv);
+  void LaunchChildMac(int aArgc, char** aArgv, PRUint32 aRestartType = 0);
 }
 
 #endif
--- a/toolkit/xre/MacLaunchHelper.mm
+++ b/toolkit/xre/MacLaunchHelper.mm
@@ -31,58 +31,75 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#include "prtypes.h"
 #include "MacLaunchHelper.h"
 
 #include "nsMemory.h"
 #include "nsAutoPtr.h"
+#include "nsIAppStartup.h"
 
 #include <stdio.h>
 #include <spawn.h>
 #include <crt_externs.h>
 
 namespace {
 cpu_type_t pref_cpu_types[2] = {
 #if defined(__i386__)
                                  CPU_TYPE_X86,
 #elif defined(__x86_64__)
                                  CPU_TYPE_X86_64,
 #elif defined(__ppc__)
                                  CPU_TYPE_POWERPC,
 #endif
                                  CPU_TYPE_ANY };
+
+cpu_type_t cpu_i386_types[2] = {
+                                 CPU_TYPE_X86,
+                                 CPU_TYPE_ANY };
+
+cpu_type_t cpu_x64_86_types[2] = {
+                                 CPU_TYPE_X86_64,
+                                 CPU_TYPE_ANY };
 }
 
-void LaunchChildMac(int aArgc, char** aArgv)
+void LaunchChildMac(int aArgc, char** aArgv, PRUint32 aRestartType)
 {
   // "posix_spawnp" uses null termination for arguments rather than a count.
   // Note that we are not duplicating the argument strings themselves.
   nsAutoArrayPtr<char*> argv_copy(new char*[aArgc + 1]);
   for (int i = 0; i < aArgc; i++) {
     argv_copy[i] = aArgv[i];
   }
   argv_copy[aArgc] = NULL;
 
   // Initialize spawn attributes.
   posix_spawnattr_t spawnattr;
   if (posix_spawnattr_init(&spawnattr) != 0) {
     printf("Failed to init posix spawn attribute.");
     return;
   }
 
+  cpu_type_t *wanted_type = pref_cpu_types;
+
+  if (aRestartType & nsIAppStartup::eRestarti386)
+    wanted_type = cpu_i386_types;
+  else if (aRestartType & nsIAppStartup::eRestartx86_64)
+    wanted_type = cpu_x64_86_types;
+
   // Set spawn attributes.
-  size_t attr_count = NS_ARRAY_LENGTH(pref_cpu_types);
+  size_t attr_count = NS_ARRAY_LENGTH(wanted_type);
   size_t attr_ocount = 0;
-  if (posix_spawnattr_setbinpref_np(&spawnattr, attr_count, pref_cpu_types, &attr_ocount) != 0 ||
+  if (posix_spawnattr_setbinpref_np(&spawnattr, attr_count, wanted_type, &attr_ocount) != 0 ||
       attr_ocount != attr_count) {
     printf("Failed to set binary preference on posix spawn attribute.");
     posix_spawnattr_destroy(&spawnattr);
     return;
   }
 
   // Pass along our environment.
   char** envp = NULL;
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -248,16 +248,17 @@ public:
       ReleaseMutex(mHandle);
   }
 
 protected:
   HANDLE mHandle;
 };
 #endif
 
+extern PRUint32 gRestartMode;
 extern void InstallSignalHandlers(const char *ProgramName);
 #include "nsX11ErrorHandler.h"
 
 #define FILE_COMPATIBILITY_INFO NS_LITERAL_CSTRING("compatibility.ini")
 #define FILE_INVALIDATE_CACHES NS_LITERAL_CSTRING(".purgecaches")
 
 int    gArgc;
 char **gArgv;
@@ -1753,17 +1754,17 @@ static nsresult LaunchChild(nsINativeApp
 
   SaveToEnv("MOZ_LAUNCHED_CHILD=1");
 
 #if defined(ANDROID)
   mozilla::AndroidBridge::Bridge()->ScheduleRestart();
 #else
 #if defined(XP_MACOSX)
   CommandLineServiceMac::SetupMacCommandLine(gRestartArgc, gRestartArgv, PR_TRUE);
-  LaunchChildMac(gRestartArgc, gRestartArgv);
+  LaunchChildMac(gRestartArgc, gRestartArgv, gRestartMode);
 #else
   nsCOMPtr<nsILocalFile> lf;
   nsresult rv = XRE_GetBinaryPath(gArgv[0], getter_AddRefs(lf));
   if (NS_FAILED(rv))
     return rv;
 
 #if defined(XP_WIN)
   nsAutoString exePath;