• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ppapi/proxy/plugin_array_buffer_var.h"
6 
7 #include <stdlib.h>
8 
9 #include <limits>
10 
11 #include "base/memory/shared_memory.h"
12 #include "ppapi/c/dev/ppb_buffer_dev.h"
13 #include "ppapi/proxy/plugin_dispatcher.h"
14 #include "ppapi/proxy/plugin_globals.h"
15 #include "ppapi/proxy/ppapi_messages.h"
16 #include "ppapi/proxy/serialized_structs.h"
17 #include "ppapi/shared_impl/host_resource.h"
18 #include "ppapi/shared_impl/resource.h"
19 #include "ppapi/thunk/enter.h"
20 #include "ppapi/thunk/ppb_buffer_api.h"
21 
22 using base::SharedMemory;
23 using base::SharedMemoryHandle;
24 using ppapi::proxy::PluginGlobals;
25 using ppapi::proxy::PluginResourceTracker;
26 
27 namespace ppapi {
28 
PluginArrayBufferVar(uint32 size_in_bytes)29 PluginArrayBufferVar::PluginArrayBufferVar(uint32 size_in_bytes)
30     : buffer_(size_in_bytes),
31       plugin_handle_(base::SharedMemory::NULLHandle()),
32       size_in_bytes_(size_in_bytes) {
33 }
34 
PluginArrayBufferVar(uint32 size_in_bytes,SharedMemoryHandle plugin_handle)35 PluginArrayBufferVar::PluginArrayBufferVar(uint32 size_in_bytes,
36                                            SharedMemoryHandle plugin_handle)
37     : plugin_handle_(plugin_handle),
38       size_in_bytes_(size_in_bytes) {
39 }
40 
~PluginArrayBufferVar()41 PluginArrayBufferVar::~PluginArrayBufferVar() {
42   Unmap();
43 
44   if (shmem_.get() == NULL) {
45     // The SharedMemory destuctor can't close the handle for us.
46     if (SharedMemory::IsHandleValid(plugin_handle_))
47       SharedMemory::CloseHandle(plugin_handle_);
48   } else {
49     // Delete SharedMemory, if we have one.
50     shmem_.reset();
51   }
52 }
53 
Map()54 void* PluginArrayBufferVar::Map() {
55   if (shmem_.get())
56     return shmem_->memory();
57   if (SharedMemory::IsHandleValid(plugin_handle_)) {
58     shmem_.reset(new SharedMemory(plugin_handle_, false));
59     if (!shmem_->Map(size_in_bytes_)) {
60       shmem_.reset();
61       return NULL;
62     }
63     return shmem_->memory();
64   }
65   if (buffer_.empty())
66     return NULL;
67   return &(buffer_[0]);
68 }
69 
Unmap()70 void PluginArrayBufferVar::Unmap() {
71   if (shmem_.get())
72     shmem_->Unmap();
73 }
74 
ByteLength()75 uint32 PluginArrayBufferVar::ByteLength() {
76   return size_in_bytes_;
77 }
78 
CopyToNewShmem(PP_Instance instance,int * host_handle_id,SharedMemoryHandle * plugin_out_handle)79 bool PluginArrayBufferVar::CopyToNewShmem(
80     PP_Instance instance,
81     int* host_handle_id,
82     SharedMemoryHandle* plugin_out_handle) {
83   ppapi::proxy::PluginDispatcher* dispatcher =
84       ppapi::proxy::PluginDispatcher::GetForInstance(instance);
85   if (!dispatcher)
86     return false;
87 
88   ppapi::proxy::SerializedHandle plugin_handle;
89   dispatcher->Send(new PpapiHostMsg_SharedMemory_CreateSharedMemory(
90       instance, ByteLength(), host_handle_id, &plugin_handle));
91   if (!plugin_handle.IsHandleValid() || !plugin_handle.is_shmem() ||
92       *host_handle_id == -1)
93     return false;
94 
95   base::SharedMemoryHandle tmp_handle = plugin_handle.shmem();
96   SharedMemory s(tmp_handle, false);
97   if (!s.Map(ByteLength()))
98     return false;
99   memcpy(s.memory(), Map(), ByteLength());
100   s.Unmap();
101 
102   // We don't need to keep the shared memory around on the plugin side;
103   // we've already copied all our data into it. We'll make it invalid
104   // just to be safe.
105   *plugin_out_handle = base::SharedMemory::NULLHandle();
106 
107   return true;
108 }
109 
110 }  // namespace ppapi
111