Skip to content

Commit

Permalink
PPAPI: Implement PPB_FileMapping on POSIX
Browse files Browse the repository at this point in the history
BUG=83774
R=bbudge@chromium.org

Review URL: https://codereview.chromium.org/69663002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247473 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
dmichael@chromium.org committed Jan 28, 2014
1 parent b36c4bd commit 5e4d293
Show file tree
Hide file tree
Showing 26 changed files with 1,111 additions and 13 deletions.
1 change: 1 addition & 0 deletions chrome/browser/component_updater/ppapi_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include "ppapi/c/ppb_console.h"
#include "ppapi/c/ppb_core.h"
#include "ppapi/c/ppb_file_io.h"
#include "ppapi/c/ppb_file_mapping.h"
#include "ppapi/c/ppb_file_ref.h"
#include "ppapi/c/ppb_file_system.h"
#include "ppapi/c/ppb_fullscreen.h"
Expand Down
10 changes: 10 additions & 0 deletions chrome/test/ppapi/ppapi_browsertest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -971,6 +971,16 @@ IN_PROC_BROWSER_TEST_F(PPAPIPrivateNaClPNaClTest, MAYBE_PNaCl_FileIO_Private) {
);
}

// PPB_FileMapping is only implemented on POSIX currently.
// http://crbug.com/83774
#if defined(OS_WIN)
#define MAYBE_FileMapping DISABLED_FileMapping
#else
#define MAYBE_FileMapping FileMapping
#endif
TEST_PPAPI_OUT_OF_PROCESS_VIA_HTTP(MAYBE_FileMapping)
TEST_PPAPI_NACL(MAYBE_FileMapping)

// Note, the FileRef tests are split into two, because all of them together
// sometimes take too long on windows: crbug.com/336999
IN_PROC_BROWSER_TEST_F(PPAPITest, FileRef1) {
Expand Down
1 change: 1 addition & 0 deletions content/renderer/pepper/pepper_plugin_instance_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2402,6 +2402,7 @@ ppapi::Resource* PepperPluginInstanceImpl::GetSingletonResource(
case ppapi::BROKER_SINGLETON_ID:
case ppapi::BROWSER_FONT_SINGLETON_ID:
case ppapi::EXTENSIONS_COMMON_SINGLETON_ID:
case ppapi::FILE_MAPPING_SINGLETON_ID:
case ppapi::FLASH_CLIPBOARD_SINGLETON_ID:
case ppapi::FLASH_FILE_SINGLETON_ID:
case ppapi::FLASH_FULLSCREEN_SINGLETON_ID:
Expand Down
1 change: 1 addition & 0 deletions content/renderer/pepper/plugin_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include "ppapi/c/ppb_console.h"
#include "ppapi/c/ppb_core.h"
#include "ppapi/c/ppb_file_io.h"
#include "ppapi/c/ppb_file_mapping.h"
#include "ppapi/c/ppb_file_ref.h"
#include "ppapi/c/ppb_file_system.h"
#include "ppapi/c/ppb_fullscreen.h"
Expand Down
2 changes: 2 additions & 0 deletions ppapi/api/ppb_file_mapping.idl
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
* memory.
*/

[generate_thunk]

label Chrome {
[channel=dev] M34 = 0.1
};
Expand Down
2 changes: 1 addition & 1 deletion ppapi/c/ppb_file_mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* found in the LICENSE file.
*/

/* From ppb_file_mapping.idl modified Wed Jan 22 12:25:44 2014. */
/* From ppb_file_mapping.idl modified Mon Jan 27 11:00:43 2014. */

#ifndef PPAPI_C_PPB_FILE_MAPPING_H_
#define PPAPI_C_PPB_FILE_MAPPING_H_
Expand Down
12 changes: 6 additions & 6 deletions ppapi/native_client/src/untrusted/pnacl_irt_shim/pnacl_shim.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,14 +421,14 @@ static int32_t Pnacl_M34_PPB_FileMapping_Map(PP_Instance instance, PP_Resource f
return iface->Map(instance, file_io, length, map_protection, map_flags, offset, address, *callback);
}

static int32_t Pnacl_M34_PPB_FileMapping_Unmap(PP_Instance file_io, const void* address, int64_t length, struct PP_CompletionCallback* callback) {
static int32_t Pnacl_M34_PPB_FileMapping_Unmap(PP_Instance instance, const void* address, int64_t length, struct PP_CompletionCallback* callback) {
const struct PPB_FileMapping_0_1 *iface = Pnacl_WrapperInfo_PPB_FileMapping_0_1.real_iface;
return iface->Unmap(file_io, address, length, *callback);
return iface->Unmap(instance, address, length, *callback);
}

static int64_t Pnacl_M34_PPB_FileMapping_GetMapPageSize(PP_Instance file_io) {
static int64_t Pnacl_M34_PPB_FileMapping_GetMapPageSize(PP_Instance instance) {
const struct PPB_FileMapping_0_1 *iface = Pnacl_WrapperInfo_PPB_FileMapping_0_1.real_iface;
return iface->GetMapPageSize(file_io);
return iface->GetMapPageSize(instance);
}

/* End wrapper methods for PPB_FileMapping_0_1 */
Expand Down Expand Up @@ -4231,8 +4231,8 @@ static struct PPB_FileIO_1_1 Pnacl_Wrappers_PPB_FileIO_1_1 = {

static struct PPB_FileMapping_0_1 Pnacl_Wrappers_PPB_FileMapping_0_1 = {
.Map = (int32_t (*)(PP_Instance instance, PP_Resource file_io, int64_t length, uint32_t map_protection, uint32_t map_flags, int64_t offset, void** address, struct PP_CompletionCallback callback))&Pnacl_M34_PPB_FileMapping_Map,
.Unmap = (int32_t (*)(PP_Instance file_io, const void* address, int64_t length, struct PP_CompletionCallback callback))&Pnacl_M34_PPB_FileMapping_Unmap,
.GetMapPageSize = (int64_t (*)(PP_Instance file_io))&Pnacl_M34_PPB_FileMapping_GetMapPageSize
.Unmap = (int32_t (*)(PP_Instance instance, const void* address, int64_t length, struct PP_CompletionCallback callback))&Pnacl_M34_PPB_FileMapping_Unmap,
.GetMapPageSize = (int64_t (*)(PP_Instance instance))&Pnacl_M34_PPB_FileMapping_GetMapPageSize
};

static struct PPB_FileRef_1_0 Pnacl_Wrappers_PPB_FileRef_1_0 = {
Expand Down
12 changes: 8 additions & 4 deletions ppapi/ppapi_proxy.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,16 @@
'proxy/extensions_common_resource.h',
'proxy/file_chooser_resource.cc',
'proxy/file_chooser_resource.h',
'proxy/file_io_resource.cc',
'proxy/file_io_resource.h',
'proxy/file_mapping_resource.cc',
'proxy/file_mapping_resource.h',
'proxy/file_mapping_resource_posix.cc',
'proxy/file_mapping_resource_win.cc',
'proxy/file_ref_resource.cc',
'proxy/file_ref_resource.h',
'proxy/file_system_resource.cc',
'proxy/file_system_resource.h',
'proxy/flash_clipboard_resource.cc',
'proxy/flash_clipboard_resource.h',
'proxy/flash_drm_resource.cc',
Expand All @@ -55,10 +63,6 @@
'proxy/flash_menu_resource.h',
'proxy/flash_resource.cc',
'proxy/flash_resource.h',
'proxy/file_io_resource.cc',
'proxy/file_io_resource.h',
'proxy/file_system_resource.cc',
'proxy/file_system_resource.h',
'proxy/gamepad_resource.cc',
'proxy/gamepad_resource.h',
'proxy/graphics_2d_resource.cc',
Expand Down
1 change: 1 addition & 0 deletions ppapi/ppapi_shared.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@
'thunk/ppb_file_io_api.h',
'thunk/ppb_file_io_private_thunk.cc',
'thunk/ppb_file_io_thunk.cc',
'thunk/ppb_file_mapping_thunk.cc',
'thunk/ppb_file_ref_api.h',
'thunk/ppb_file_ref_thunk.cc',
'thunk/ppb_file_system_api.h',
Expand Down
3 changes: 3 additions & 0 deletions ppapi/ppapi_sources.gypi
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
'c/ppb_console.h',
'c/ppb_core.h',
'c/ppb_file_io.h',
'c/ppb_file_mapping.h',
'c/ppb_file_ref.h',
'c/ppb_file_system.h',
'c/ppb_fullscreen.h',
Expand Down Expand Up @@ -433,6 +434,8 @@
'tests/test_empty.h',
'tests/test_file_io.cc',
'tests/test_file_io.h',
'tests/test_file_mapping.cc',
'tests/test_file_mapping.h',
'tests/test_file_ref.cc',
'tests/test_file_ref.h',
'tests/test_file_system.cc',
Expand Down
5 changes: 4 additions & 1 deletion ppapi/proxy/file_io_resource.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ class PPAPI_PROXY_EXPORT FileIOResource
PP_FileHandle* handle,
scoped_refptr<TrackedCallback> callback) OVERRIDE;

private:
// FileHandleHolder is used to guarantee that file operations will have a
// valid FD to operate on, even if they're in a different thread.
// If instead we just passed the raw FD, the FD could be closed before the
Expand Down Expand Up @@ -102,7 +101,11 @@ class PPAPI_PROXY_EXPORT FileIOResource
~FileHandleHolder();
PP_FileHandle raw_handle_;
};
scoped_refptr<FileHandleHolder> file_handle() {
return file_handle_;
}

private:
// Class to perform file query operations across multiple threads.
class QueryOp : public base::RefCountedThreadSafe<QueryOp> {
public:
Expand Down
160 changes: 160 additions & 0 deletions ppapi/proxy/file_mapping_resource.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
// Copyright (c) 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ppapi/proxy/file_mapping_resource.h"

#include "base/bind.h"
#include "base/numerics/safe_conversions.h"
#include "base/task_runner_util.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/shared_impl/tracked_callback.h"
#include "ppapi/shared_impl/var.h"
#include "ppapi/thunk/enter.h"
#include "ppapi/thunk/ppb_file_io_api.h"

namespace ppapi {
namespace proxy {

FileMappingResource::FileMappingResource(Connection connection,
PP_Instance instance)
: PluginResource(connection, instance) {
}

FileMappingResource::~FileMappingResource() {
}

thunk::PPB_FileMapping_API* FileMappingResource::AsPPB_FileMapping_API() {
return this;
}

int32_t FileMappingResource::Map(PP_Instance /* instance */,
PP_Resource file_io,
int64_t length,
uint32_t protection,
uint32_t flags,
int64_t offset,
void** address,
scoped_refptr<TrackedCallback> callback) {
thunk::EnterResourceNoLock<thunk::PPB_FileIO_API> enter(file_io, true);
if (enter.failed())
return PP_ERROR_BADARGUMENT;
FileIOResource* file_io_resource =
static_cast<FileIOResource*>(enter.object());
scoped_refptr<FileIOResource::FileHandleHolder> file_handle =
file_io_resource->file_handle();
if (!FileIOResource::FileHandleHolder::IsValid(file_handle))
return PP_ERROR_FAILED;
if (length < 0 || offset < 0 ||
!base::IsValueInRangeForNumericType<off_t>(offset)) {
return PP_ERROR_BADARGUMENT;
}
if (!base::IsValueInRangeForNumericType<size_t>(length)) {
return PP_ERROR_NOMEMORY;
}

// Ensure any bits we don't recognize are zero.
if (protection &
~(PP_FILEMAPPROTECTION_READ | PP_FILEMAPPROTECTION_WRITE)) {
return PP_ERROR_BADARGUMENT;
}
if (flags &
~(PP_FILEMAPFLAG_SHARED | PP_FILEMAPFLAG_PRIVATE |
PP_FILEMAPFLAG_FIXED)) {
return PP_ERROR_BADARGUMENT;
}
// Ensure at least one of SHARED and PRIVATE is set.
if (!(flags & (PP_FILEMAPFLAG_SHARED | PP_FILEMAPFLAG_PRIVATE)))
return PP_ERROR_BADARGUMENT;
// Ensure at most one of SHARED and PRIVATE is set.
if ((flags & PP_FILEMAPFLAG_SHARED) &&
(flags & PP_FILEMAPFLAG_PRIVATE)) {
return PP_ERROR_BADARGUMENT;
}
if (!address)
return PP_ERROR_BADARGUMENT;

base::Callback<MapResult()> map_cb(
base::Bind(&FileMappingResource::DoMapBlocking, file_handle, *address,
length, protection, flags, offset));
if (callback->is_blocking()) {
// The plugin could release its reference to this instance when we release
// the proxy lock below.
scoped_refptr<FileMappingResource> protect(this);
MapResult map_result;
{
// Release the proxy lock while making a potentially slow file call.
ProxyAutoUnlock unlock;
map_result = map_cb.Run();
}
OnMapCompleted(address, length, callback, map_result);
return map_result.result;
} else {
base::PostTaskAndReplyWithResult(
PpapiGlobals::Get()->GetFileTaskRunner(),
FROM_HERE,
map_cb,
RunWhileLocked(Bind(&FileMappingResource::OnMapCompleted,
this,
base::Unretained(address),
length,
callback)));
return PP_OK_COMPLETIONPENDING;
}
}

int32_t FileMappingResource::Unmap(PP_Instance /* instance */,
const void* address,
int64_t length,
scoped_refptr<TrackedCallback> callback) {
if (!address)
return PP_ERROR_BADARGUMENT;
if (!base::IsValueInRangeForNumericType<size_t>(length))
return PP_ERROR_BADARGUMENT;

base::Callback<int32_t()> unmap_cb(
base::Bind(&FileMappingResource::DoUnmapBlocking, address, length));
if (callback->is_blocking()) {
// Release the proxy lock while making a potentially slow file call.
ProxyAutoUnlock unlock;
return unmap_cb.Run();
} else {
base::PostTaskAndReplyWithResult(
PpapiGlobals::Get()->GetFileTaskRunner(),
FROM_HERE,
unmap_cb,
RunWhileLocked(Bind(&TrackedCallback::Run, callback)));
return PP_OK_COMPLETIONPENDING;
}
}

int64_t FileMappingResource::GetMapPageSize(PP_Instance /* instance */) {
return DoGetMapPageSize();
}

void FileMappingResource::OnMapCompleted(
void** mapped_address_out_param,
int64_t length,
scoped_refptr<TrackedCallback> callback,
const MapResult& map_result) {
if (callback->aborted()) {
if (map_result.result == PP_OK) {
// If the Map operation was successful, we need to Unmap to avoid leaks.
// The plugin won't get the address, so doesn't have a chance to do the
// Unmap.
PpapiGlobals::Get()->GetFileTaskRunner()->PostTask(
FROM_HERE,
base::Bind(base::IgnoreResult(&FileMappingResource::DoUnmapBlocking),
map_result.address,
length));
}
return;
}
if (map_result.result == PP_OK)
*mapped_address_out_param = map_result.address;
if (!callback->is_blocking())
callback->Run(map_result.result);
}

} // namespace proxy
} // namespace ppapi
Loading

0 comments on commit 5e4d293

Please sign in to comment.