Commit ab88d154 authored by mcgrathr@chromium.org's avatar mcgrathr@chromium.org

Revert 110361 - NaCl: preallocate shared-memory object on Linux as on MacOSX

Preallocating the shared memory object saves an IPC round trip.
It also makes the code path more similar for Linux and Mac.
It also lays the groundwork for changing the allocation method
later without having to replumb the proxying layer.

BUG= http://code.google.com/p/chromium/issues/detail?id=103377
TEST= nacl still works on Linux

R=mseaborn@chromium.org,jam@chromium.org

Review URL: http://codereview.chromium.org/8513018

TBR=mseaborn@chromium.org
Review URL: http://codereview.chromium.org/8598029

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110776 0039d316-1c4b-4281-b951-d872f2087c98
parent f38b332e
...@@ -486,11 +486,11 @@ void NaClProcessHost::SendStart(base::PlatformFile irt_file) { ...@@ -486,11 +486,11 @@ void NaClProcessHost::SendStart(base::PlatformFile irt_file) {
return; return;
} }
#if defined(OS_POSIX) #if defined(OS_MACOSX)
// For dynamic loading support, NaCl requires a file descriptor on an // For dynamic loading support, NaCl requires a file descriptor that
// anonymous file that can have PROT_EXEC applied to its mappings. // was created in /tmp, since those created with shm_open() are not
// Rather than requiring an extra IPC round trip out of the sandbox, // mappable with PROT_EXEC. Rather than requiring an extra IPC
// we create an FD here. // round trip out of the sandbox, we create an FD here.
base::SharedMemory memory_buffer; base::SharedMemory memory_buffer;
if (!memory_buffer.CreateAnonymous(/* size= */ 1)) { if (!memory_buffer.CreateAnonymous(/* size= */ 1)) {
LOG(ERROR) << "Failed to allocate memory buffer"; LOG(ERROR) << "Failed to allocate memory buffer";
......
...@@ -33,59 +33,41 @@ typedef HANDLE NaClHandle; ...@@ -33,59 +33,41 @@ typedef HANDLE NaClHandle;
typedef int NaClHandle; typedef int NaClHandle;
#endif // NaClHandle #endif // NaClHandle
#if defined(OS_POSIX) #if defined(OS_MACOSX)
namespace { namespace {
// On Mac OS X, shm_open() works in the sandbox but does not give us an FD // On Mac OS X, shm_open() works in the sandbox but does not give us
// that we can map as PROT_EXEC. On Linux, shm_open() can only be used // an FD that we can map as PROT_EXEC. Rather than doing an IPC to
// outside the sandbox anyway. Rather than doing an IPC to get an // get an executable SHM region when CreateMemoryObject() is called,
// executable SHM region when CreateMemoryObject() is called, we // we preallocate one on startup, since NaCl's sel_ldr only needs one
// preallocate one on startup, since NaCl's sel_ldr only needs one of them. // of them. This saves a round trip.
// This saves a round trip.
bool SetShmFdSize(int fd, size_t size) {
#if defined(OS_MACOSX)
// ftruncate() is disallowed by the Mac OS X sandbox and returns EPERM.
// Luckily, we can get the same effect with lseek() + write().
if (lseek(fd, size - 1, SEEK_SET) == -1) {
LOG(ERROR) << "lseek() failed: " << errno;
close(fd);
return false;
}
if (write(fd, "", 1) != 1) {
LOG(ERROR) << "write() failed: " << errno;
close(fd);
return -1;
}
#else
if (ftruncate(fd, size) < 0) {
LOG(ERROR) << "ftruncate() failed: " << errno;
close(fd);
return false;
}
#endif // defined(OS_MACOSX)
return true;
}
base::subtle::Atomic32 g_shm_fd = -1; base::subtle::Atomic32 g_shm_fd = -1;
int CreateMemoryObject(size_t size, bool executable) { int CreateMemoryObject(size_t size, bool executable) {
if (executable && size > 0) { if (executable && size > 0) {
int result_fd = base::subtle::NoBarrier_AtomicExchange(&g_shm_fd, -1); int result_fd = base::subtle::NoBarrier_AtomicExchange(&g_shm_fd, -1);
if (result_fd != -1 && SetShmFdSize(result_fd, size)) if (result_fd != -1) {
// ftruncate() is disallowed by the Mac OS X sandbox and
// returns EPERM. Luckily, we can get the same effect with
// lseek() + write().
if (lseek(result_fd, size - 1, SEEK_SET) == -1) {
LOG(ERROR) << "lseek() failed: " << errno;
return -1;
}
if (write(result_fd, "", 1) != 1) {
LOG(ERROR) << "write() failed: " << errno;
return -1;
}
return result_fd; return result_fd;
} }
#if defined(OS_LINUX) }
// Use the proxied implementation. It doesn't really support executability.
CHECK(!executable);
return content::MakeSharedMemorySegmentViaIPC(size, executable);
#endif
// Fall back to NaCl's default implementation. // Fall back to NaCl's default implementation.
return -1; return -1;
} }
} // namespace } // namespace
#endif // defined(OS_POSIX) #endif // defined(OS_MACOSX)
extern "C" void NaClMainForChromium(int handle_count, extern "C" void NaClMainForChromium(int handle_count,
const NaClHandle* handles, const NaClHandle* handles,
...@@ -115,15 +97,17 @@ bool NaClListener::OnMessageReceived(const IPC::Message& msg) { ...@@ -115,15 +97,17 @@ bool NaClListener::OnMessageReceived(const IPC::Message& msg) {
} }
void NaClListener::OnStartSelLdr(std::vector<nacl::FileDescriptor> handles) { void NaClListener::OnStartSelLdr(std::vector<nacl::FileDescriptor> handles) {
#if defined(OS_POSIX) #if defined(OS_LINUX)
nacl::SetCreateMemoryObjectFunc(content::MakeSharedMemorySegmentViaIPC);
#elif defined(OS_MACOSX)
nacl::SetCreateMemoryObjectFunc(CreateMemoryObject); nacl::SetCreateMemoryObjectFunc(CreateMemoryObject);
CHECK(!handles.empty()); CHECK(handles.size() >= 1);
g_shm_fd = nacl::ToNativeHandle(handles.back()); g_shm_fd = nacl::ToNativeHandle(handles[handles.size() - 1]);
handles.pop_back(); handles.pop_back();
#endif #endif
CHECK(!handles.empty()); CHECK(handles.size() >= 1);
NaClHandle irt_handle = nacl::ToNativeHandle(handles.back()); NaClHandle irt_handle = nacl::ToNativeHandle(handles[handles.size() - 1]);
handles.pop_back(); handles.pop_back();
#if defined(OS_WIN) #if defined(OS_WIN)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment