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
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;