ProcessUtils_common.cpp (4854B)
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */ 3 /* This Source Code Form is subject to the terms of the Mozilla Public 4 * License, v. 2.0. If a copy of the MPL was not distributed with this 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 6 7 #include "ProcessUtils.h" 8 9 #include "mozilla/Preferences.h" 10 #include "mozilla/GeckoArgs.h" 11 #include "mozilla/dom/RemoteType.h" 12 #include "mozilla/ipc/GeckoChildProcessHost.h" 13 #include "nsPrintfCString.h" 14 15 #include "XPCSelfHostedShmem.h" 16 17 namespace mozilla { 18 namespace ipc { 19 20 SharedPreferenceSerializer::SharedPreferenceSerializer() { 21 MOZ_COUNT_CTOR(SharedPreferenceSerializer); 22 } 23 24 SharedPreferenceSerializer::~SharedPreferenceSerializer() { 25 MOZ_COUNT_DTOR(SharedPreferenceSerializer); 26 } 27 28 SharedPreferenceSerializer::SharedPreferenceSerializer( 29 SharedPreferenceSerializer&& aOther) 30 : mPrefMapHandle(std::move(aOther.mPrefMapHandle)), 31 mPrefsHandle(std::move(aOther.mPrefsHandle)) { 32 MOZ_COUNT_CTOR(SharedPreferenceSerializer); 33 } 34 35 bool SharedPreferenceSerializer::SerializeToSharedMemory( 36 const GeckoProcessType aDestinationProcessType, 37 const nsACString& aDestinationRemoteType) { 38 mPrefMapHandle = Preferences::EnsureSnapshot(); 39 40 bool destIsWebContent = 41 aDestinationProcessType == GeckoProcessType_Content && 42 (StringBeginsWith(aDestinationRemoteType, WEB_REMOTE_TYPE) || 43 StringBeginsWith(aDestinationRemoteType, PREALLOC_REMOTE_TYPE)); 44 45 // Serialize the early prefs. 46 nsAutoCStringN<1024> prefs; 47 Preferences::SerializePreferences(prefs, destIsWebContent); 48 auto prefsLength = prefs.Length(); 49 50 // Set up the shared memory. 51 auto handle = shared_memory::Create(prefsLength); 52 if (!handle) { 53 NS_ERROR("failed to create shared memory in the parent"); 54 return false; 55 } 56 auto mapping = handle.Map(); 57 if (!mapping) { 58 NS_ERROR("failed to map shared memory in the parent"); 59 return false; 60 } 61 62 // Copy the serialized prefs into the shared memory. 63 memcpy(mapping.DataAs<char>(), prefs.get(), prefsLength); 64 65 mPrefsHandle = std::move(handle).ToReadOnly(); 66 return true; 67 } 68 69 void SharedPreferenceSerializer::AddSharedPrefCmdLineArgs( 70 mozilla::ipc::GeckoChildProcessHost& procHost, 71 geckoargs::ChildProcessArgs& aExtraOpts) const { 72 auto prefsHandle = GetPrefsHandle().Clone(); 73 MOZ_RELEASE_ASSERT(prefsHandle, "failed to clone prefs handle"); 74 auto prefMapHandle = GetPrefMapHandle().Clone(); 75 MOZ_RELEASE_ASSERT(prefMapHandle, "failed to clone pref map handle"); 76 77 // Pass the handles via command line flags. 78 geckoargs::sPrefsHandle.Put(std::move(prefsHandle), aExtraOpts); 79 geckoargs::sPrefMapHandle.Put(std::move(prefMapHandle), aExtraOpts); 80 } 81 82 SharedPreferenceDeserializer::SharedPreferenceDeserializer() { 83 MOZ_COUNT_CTOR(SharedPreferenceDeserializer); 84 } 85 86 SharedPreferenceDeserializer::~SharedPreferenceDeserializer() { 87 MOZ_COUNT_DTOR(SharedPreferenceDeserializer); 88 } 89 90 bool SharedPreferenceDeserializer::DeserializeFromSharedMemory( 91 ReadOnlySharedMemoryHandle&& aPrefsHandle, 92 ReadOnlySharedMemoryHandle&& aPrefMapHandle) { 93 if (!aPrefsHandle || !aPrefMapHandle) { 94 return false; 95 } 96 97 mPrefMapHandle = std::move(aPrefMapHandle); 98 99 // Init the shared-memory base preference mapping first, so that only changed 100 // preferences wind up in heap memory. 101 Preferences::InitSnapshot(mPrefMapHandle); 102 103 // Set up early prefs from the shared memory. 104 mShmem = aPrefsHandle.Map(); 105 if (!mShmem) { 106 NS_ERROR("failed to map shared memory in the child"); 107 return false; 108 } 109 Preferences::DeserializePreferences(mShmem.DataAs<char>(), mShmem.Size()); 110 111 return true; 112 } 113 114 void ExportSharedJSInit(mozilla::ipc::GeckoChildProcessHost& procHost, 115 geckoargs::ChildProcessArgs& aExtraOpts) { 116 auto& shmem = xpc::SelfHostedShmem::GetSingleton(); 117 auto handle = shmem.Handle().Clone(); 118 119 // If the file is not found or the content is empty, then we would start the 120 // content process without this optimization. 121 if (!handle) { 122 NS_ERROR("Can't use SelfHosted shared memory handle."); 123 return; 124 } 125 126 // command line: -jsInitHandle handle 127 geckoargs::sJsInitHandle.Put(std::move(handle), aExtraOpts); 128 } 129 130 bool ImportSharedJSInit(ReadOnlySharedMemoryHandle&& aJsInitHandle) { 131 // This is an optimization, and as such we can safely recover if the command 132 // line argument are not provided. 133 if (!aJsInitHandle) { 134 return true; 135 } 136 137 // Initialize the shared memory with the file handle and size of the content 138 // of the self-hosted Xdr. 139 auto& shmem = xpc::SelfHostedShmem::GetSingleton(); 140 if (!shmem.InitFromChild(std::move(aJsInitHandle))) { 141 NS_ERROR("failed to open shared memory in the child"); 142 return false; 143 } 144 145 return true; 146 } 147 148 } // namespace ipc 149 } // namespace mozilla