Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(128)

Side by Side Diff: ppapi/proxy/serialized_var.cc

Issue 14208016: Hookup RawVarData to SerializedVar (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/proxy/serialized_var.h ('k') | ppapi/tests/test_post_message.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ppapi/proxy/serialized_var.h" 5 #include "ppapi/proxy/serialized_var.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "ipc/ipc_message_utils.h" 8 #include "ipc/ipc_message_utils.h"
9 #include "ppapi/c/pp_instance.h" 9 #include "ppapi/c/pp_instance.h"
10 #include "ppapi/proxy/dispatcher.h" 10 #include "ppapi/proxy/dispatcher.h"
11 #include "ppapi/proxy/interface_proxy.h" 11 #include "ppapi/proxy/interface_proxy.h"
12 #include "ppapi/proxy/ppapi_param_traits.h" 12 #include "ppapi/proxy/ppapi_param_traits.h"
13 #include "ppapi/proxy/ppb_buffer_proxy.h" 13 #include "ppapi/proxy/ppb_buffer_proxy.h"
14 #include "ppapi/shared_impl/ppapi_globals.h" 14 #include "ppapi/shared_impl/ppapi_globals.h"
15 #include "ppapi/shared_impl/var.h" 15 #include "ppapi/shared_impl/var.h"
16 #include "ppapi/thunk/enter.h" 16 #include "ppapi/thunk/enter.h"
17 17
18 namespace ppapi { 18 namespace ppapi {
19 namespace proxy { 19 namespace proxy {
20 20
21 // When sending array buffers, if the size is over 256K, we use shared
22 // memory instead of sending the data over IPC. Light testing suggests
23 // shared memory is much faster for 256K and larger messages.
24 static const uint32 kMinimumArrayBufferSizeForShmem = 256 * 1024;
25
26 // SerializedVar::Inner -------------------------------------------------------- 21 // SerializedVar::Inner --------------------------------------------------------
27 22
28 SerializedVar::Inner::Inner() 23 SerializedVar::Inner::Inner()
29 : serialization_rules_(NULL), 24 : serialization_rules_(NULL),
30 var_(PP_MakeUndefined()), 25 var_(PP_MakeUndefined()),
31 instance_(0), 26 instance_(0),
32 cleanup_mode_(CLEANUP_NONE) { 27 cleanup_mode_(CLEANUP_NONE) {
33 #ifndef NDEBUG 28 #ifndef NDEBUG
34 has_been_serialized_ = false; 29 has_been_serialized_ = false;
35 has_been_deserialized_ = false; 30 has_been_deserialized_ = false;
(...skipping 20 matching lines...) Expand all
56 serialization_rules_->EndReceiveCallerOwned(var_); 51 serialization_rules_->EndReceiveCallerOwned(var_);
57 break; 52 break;
58 default: 53 default:
59 break; 54 break;
60 } 55 }
61 } 56 }
62 57
63 PP_Var SerializedVar::Inner::GetVar() { 58 PP_Var SerializedVar::Inner::GetVar() {
64 DCHECK(serialization_rules_); 59 DCHECK(serialization_rules_);
65 60
66 ConvertRawVarData(); 61 #if defined(NACL_WIN64)
62 NOTREACHED();
63 return PP_MakeUndefined();
64 #endif
65
66 if (raw_var_data_.get()) {
67 var_ = raw_var_data_->CreatePPVar(instance_);
68 raw_var_data_.reset(NULL);
69 }
70
67 return var_; 71 return var_;
68 } 72 }
69 73
70 void SerializedVar::Inner::SetVar(PP_Var var) { 74 void SerializedVar::Inner::SetVar(PP_Var var) {
71 // Sanity check, when updating the var we should have received a 75 // Sanity check, when updating the var we should have received a
72 // serialization rules pointer already. 76 // serialization rules pointer already.
73 DCHECK(serialization_rules_); 77 DCHECK(serialization_rules_);
74 var_ = var; 78 var_ = var;
75 raw_var_data_.reset(NULL); 79 raw_var_data_.reset(NULL);
76 } 80 }
77 81
78 void SerializedVar::Inner::SetInstance(PP_Instance instance) { 82 void SerializedVar::Inner::SetInstance(PP_Instance instance) {
79 instance_ = instance; 83 instance_ = instance;
80 } 84 }
81 85
82 void SerializedVar::Inner::ForceSetVarValueForTest(PP_Var value) { 86 void SerializedVar::Inner::ForceSetVarValueForTest(PP_Var value) {
83 var_ = value; 87 var_ = value;
84 raw_var_data_.reset(NULL); 88 raw_var_data_.reset(NULL);
85 } 89 }
86 90
87 void SerializedVar::Inner::WriteRawVarHeader(IPC::Message* m) const {
88 // Write raw_var_data_ when we're called from
89 // chrome/nacl/nacl_ipc_adapter.cc.
90 DCHECK(raw_var_data_.get());
91 DCHECK_EQ(PP_VARTYPE_ARRAY_BUFFER, raw_var_data_->type);
92 DCHECK(raw_var_data_->shmem_size != 0);
93
94 // The serialization for this message MUST MATCH the implementation at
95 // SerializedVar::Inner::WriteToMessage for ARRAY_BUFFER_SHMEM_PLUGIN.
96 m->WriteInt(static_cast<int>(raw_var_data_->type));
97 m->WriteInt(ARRAY_BUFFER_SHMEM_PLUGIN);
98 m->WriteInt(raw_var_data_->shmem_size);
99 // NaClIPCAdapter will write the handles for us.
100 }
101
102 void SerializedVar::Inner::WriteToMessage(IPC::Message* m) const { 91 void SerializedVar::Inner::WriteToMessage(IPC::Message* m) const {
103 // When writing to the IPC messages, a serialization rules handler should 92 // When writing to the IPC messages, a serialization rules handler should
104 // always have been set. 93 // always have been set.
105 // 94 //
106 // When sending a message, it should be difficult to trigger this if you're 95 // When sending a message, it should be difficult to trigger this if you're
107 // using the SerializedVarSendInput class and giving a non-NULL dispatcher. 96 // using the SerializedVarSendInput class and giving a non-NULL dispatcher.
108 // Make sure you're using the proper "Send" helper class. 97 // Make sure you're using the proper "Send" helper class.
109 // 98 //
110 // It should be more common to see this when handling an incoming message 99 // It should be more common to see this when handling an incoming message
111 // that returns a var. This means the message handler didn't write to the 100 // that returns a var. This means the message handler didn't write to the
112 // output parameter, or possibly you used the wrong helper class 101 // output parameter, or possibly you used the wrong helper class
113 // (normally SerializedVarReturnValue). 102 // (normally SerializedVarReturnValue).
114 DCHECK(serialization_rules_); 103 DCHECK(serialization_rules_);
115 104
116 #ifndef NDEBUG 105 #ifndef NDEBUG
117 // We should only be serializing something once. 106 // We should only be serializing something once.
118 DCHECK(!has_been_serialized_); 107 DCHECK(!has_been_serialized_);
119 has_been_serialized_ = true; 108 has_been_serialized_ = true;
120 #endif 109 #endif
121 110 RawVarDataGraph::Create(var_, instance_)->Write(m);
122 DCHECK(!raw_var_data_.get());
123 m->WriteInt(static_cast<int>(var_.type));
124 switch (var_.type) {
125 case PP_VARTYPE_UNDEFINED:
126 case PP_VARTYPE_NULL:
127 // These don't need any data associated with them other than the type we
128 // just serialized.
129 break;
130 case PP_VARTYPE_BOOL:
131 m->WriteBool(PP_ToBool(var_.value.as_bool));
132 break;
133 case PP_VARTYPE_INT32:
134 m->WriteInt(var_.value.as_int);
135 break;
136 case PP_VARTYPE_DOUBLE:
137 IPC::ParamTraits<double>::Write(m, var_.value.as_double);
138 break;
139 case PP_VARTYPE_STRING: {
140 // TODO(brettw) in the case of an invalid string ID, it would be nice
141 // to send something to the other side such that a 0 ID would be
142 // generated there. Then the function implementing the interface can
143 // handle the invalid string as if it was in process rather than seeing
144 // what looks like a valid empty string.
145 StringVar* string_var = StringVar::FromPPVar(var_);
146 m->WriteString(string_var ? *string_var->ptr() : std::string());
147 break;
148 }
149 case PP_VARTYPE_ARRAY_BUFFER: {
150 // TODO(dmichael) in the case of an invalid var ID, it would be nice
151 // to send something to the other side such that a 0 ID would be
152 // generated there. Then the function implementing the interface can
153 // handle the invalid string as if it was in process rather than seeing
154 // what looks like a valid empty ArraryBuffer.
155 ArrayBufferVar* buffer_var = ArrayBufferVar::FromPPVar(var_);
156 bool using_shmem = false;
157 if (buffer_var &&
158 buffer_var->ByteLength() >= kMinimumArrayBufferSizeForShmem &&
159 instance_ != 0) {
160 int host_shm_handle_id;
161 base::SharedMemoryHandle plugin_shm_handle;
162 using_shmem = buffer_var->CopyToNewShmem(instance_,
163 &host_shm_handle_id,
164 &plugin_shm_handle);
165 if (using_shmem) {
166 // The serialization for this message MUST MATCH the implementation
167 // at SerializedVar::Inner::WriteRawVarHeader for
168 // ARRAY_BUFFER_SHMEM_PLUGIN.
169 if (host_shm_handle_id != -1) {
170 DCHECK(!base::SharedMemory::IsHandleValid(plugin_shm_handle));
171 DCHECK(PpapiGlobals::Get()->IsPluginGlobals());
172 m->WriteInt(ARRAY_BUFFER_SHMEM_HOST);
173 m->WriteInt(host_shm_handle_id);
174 } else {
175 DCHECK(base::SharedMemory::IsHandleValid(plugin_shm_handle));
176 DCHECK(PpapiGlobals::Get()->IsHostGlobals());
177 m->WriteInt(ARRAY_BUFFER_SHMEM_PLUGIN);
178 m->WriteInt(buffer_var->ByteLength());
179 SerializedHandle handle(plugin_shm_handle,
180 buffer_var->ByteLength());
181 IPC::ParamTraits<SerializedHandle>::Write(m, handle);
182 }
183 }
184 }
185 if (!using_shmem) {
186 if (buffer_var) {
187 m->WriteInt(ARRAY_BUFFER_NO_SHMEM);
188 m->WriteData(static_cast<const char*>(buffer_var->Map()),
189 buffer_var->ByteLength());
190 } else {
191 // TODO(teravest): Introduce an ARRAY_BUFFER_EMPTY message type.
192 m->WriteBool(ARRAY_BUFFER_NO_SHMEM);
193 m->WriteData(NULL, 0);
194 }
195 }
196 break;
197 }
198 case PP_VARTYPE_OBJECT:
199 m->WriteInt64(var_.value.as_id);
200 break;
201 case PP_VARTYPE_ARRAY:
202 case PP_VARTYPE_DICTIONARY:
203 // TODO(yzshen) when these are supported, implement this.
204 NOTIMPLEMENTED();
205 break;
206 }
207 } 111 }
208 112
209 bool SerializedVar::Inner::ReadFromMessage(const IPC::Message* m, 113 bool SerializedVar::Inner::ReadFromMessage(const IPC::Message* m,
210 PickleIterator* iter) { 114 PickleIterator* iter) {
211 #ifndef NDEBUG 115 #ifndef NDEBUG
212 // We should only deserialize something once or will end up with leaked 116 // We should only deserialize something once or will end up with leaked
213 // references. 117 // references.
214 // 118 //
215 // One place this has happened in the past is using 119 // One place this has happened in the past is using
216 // std::vector<SerializedVar>.resize(). If you're doing this manually instead 120 // std::vector<SerializedVar>.resize(). If you're doing this manually instead
217 // of using the helper classes for handling in/out vectors of vars, be 121 // of using the helper classes for handling in/out vectors of vars, be
218 // sure you use the same pattern as the SerializedVarVector classes. 122 // sure you use the same pattern as the SerializedVarVector classes.
219 DCHECK(!has_been_deserialized_); 123 DCHECK(!has_been_deserialized_);
220 has_been_deserialized_ = true; 124 has_been_deserialized_ = true;
221 #endif 125 #endif
222 // When reading, the dispatcher should be set when we get a Deserialize 126 // When reading, the dispatcher should be set when we get a Deserialize
223 // call (which will supply a dispatcher). 127 // call (which will supply a dispatcher).
224 int type; 128 raw_var_data_ = RawVarDataGraph::Read(m, iter);
225 if (!m->ReadInt(iter, &type)) 129 return raw_var_data_.get() != NULL;
226 return false;
227
228 bool success = false;
229 switch (type) {
230 case PP_VARTYPE_UNDEFINED:
231 case PP_VARTYPE_NULL:
232 // These don't have any data associated with them other than the type we
233 // just serialized.
234 success = true;
235 break;
236 case PP_VARTYPE_BOOL: {
237 bool bool_value;
238 success = m->ReadBool(iter, &bool_value);
239 var_.value.as_bool = PP_FromBool(bool_value);
240 break;
241 }
242 case PP_VARTYPE_INT32:
243 success = m->ReadInt(iter, &var_.value.as_int);
244 break;
245 case PP_VARTYPE_DOUBLE:
246 success = IPC::ParamTraits<double>::Read(m, iter, &var_.value.as_double);
247 break;
248 case PP_VARTYPE_STRING: {
249 raw_var_data_.reset(new RawVarData);
250 raw_var_data_->type = PP_VARTYPE_STRING;
251 success = m->ReadString(iter, &raw_var_data_->data);
252 if (!success)
253 raw_var_data_.reset(NULL);
254 break;
255 }
256 case PP_VARTYPE_ARRAY_BUFFER: {
257 int length = 0;
258 const char* message_bytes = NULL;
259 int shmem_type;
260 success = m->ReadInt(iter, &shmem_type);
261 if (success) {
262 if (shmem_type == ARRAY_BUFFER_NO_SHMEM) {
263 success = m->ReadData(iter, &message_bytes, &length);
264 if (success) {
265 raw_var_data_.reset(new RawVarData);
266 raw_var_data_->type = PP_VARTYPE_ARRAY_BUFFER;
267 raw_var_data_->shmem_type = static_cast<ShmemType>(shmem_type);
268 raw_var_data_->shmem_size = 0;
269 raw_var_data_->data.assign(message_bytes, length);
270 }
271 } else if (shmem_type == ARRAY_BUFFER_SHMEM_HOST) {
272 int host_handle_id;
273 success = m->ReadInt(iter, &host_handle_id);
274 if (success) {
275 raw_var_data_.reset(new RawVarData);
276 raw_var_data_->type = PP_VARTYPE_ARRAY_BUFFER;
277 raw_var_data_->shmem_type = static_cast<ShmemType>(shmem_type);
278 raw_var_data_->host_handle_id = host_handle_id;
279 }
280 } else if (shmem_type == ARRAY_BUFFER_SHMEM_PLUGIN) {
281 SerializedHandle plugin_handle;
282 success = m->ReadInt(iter, &length);
283 success &= IPC::ParamTraits<SerializedHandle>::Read(
284 m, iter, &plugin_handle);
285 if (success) {
286 raw_var_data_.reset(new RawVarData);
287 raw_var_data_->type = PP_VARTYPE_ARRAY_BUFFER;
288 raw_var_data_->shmem_type = static_cast<ShmemType>(shmem_type);
289 raw_var_data_->shmem_size = length;
290 raw_var_data_->plugin_handle = plugin_handle;
291 }
292 }
293 }
294 break;
295 }
296 case PP_VARTYPE_OBJECT:
297 success = m->ReadInt64(iter, &var_.value.as_id);
298 break;
299 case PP_VARTYPE_ARRAY:
300 case PP_VARTYPE_DICTIONARY:
301 // TODO(yzshen) when these types are supported, implement this.
302 NOTIMPLEMENTED();
303 break;
304 default:
305 // Leave success as false.
306 break;
307 }
308
309 // All success cases get here. We avoid writing the type above so that the
310 // output param is untouched (defaults to VARTYPE_UNDEFINED) even in the
311 // failure case.
312 // We also don't write the type if |raw_var_data_| is set. |var_| will be
313 // updated lazily when GetVar() is called.
314 if (success && !raw_var_data_.get())
315 var_.type = static_cast<PP_VarType>(type);
316 return success;
317 } 130 }
318 131
319 void SerializedVar::Inner::SetCleanupModeToEndSendPassRef() { 132 void SerializedVar::Inner::SetCleanupModeToEndSendPassRef() {
320 cleanup_mode_ = END_SEND_PASS_REF; 133 cleanup_mode_ = END_SEND_PASS_REF;
321 } 134 }
322 135
323 void SerializedVar::Inner::SetCleanupModeToEndReceiveCallerOwned() { 136 void SerializedVar::Inner::SetCleanupModeToEndReceiveCallerOwned() {
324 cleanup_mode_ = END_RECEIVE_CALLER_OWNED; 137 cleanup_mode_ = END_RECEIVE_CALLER_OWNED;
325 } 138 }
326 139
327 void SerializedVar::Inner::ConvertRawVarData() {
328 #if defined(NACL_WIN64)
329 NOTREACHED();
330 #else
331 if (!raw_var_data_.get())
332 return;
333
334 DCHECK_EQ(PP_VARTYPE_UNDEFINED, var_.type);
335 switch (raw_var_data_->type) {
336 case PP_VARTYPE_STRING: {
337 var_ = StringVar::SwapValidatedUTF8StringIntoPPVar(
338 &raw_var_data_->data);
339 break;
340 }
341 case PP_VARTYPE_ARRAY_BUFFER: {
342 if (raw_var_data_->shmem_type == ARRAY_BUFFER_SHMEM_HOST) {
343 base::SharedMemoryHandle host_handle;
344 uint32 size_in_bytes;
345 bool ok =
346 PpapiGlobals::Get()->GetVarTracker()->
347 StopTrackingSharedMemoryHandle(raw_var_data_->host_handle_id,
348 instance_,
349 &host_handle,
350 &size_in_bytes);
351 if (ok) {
352 var_ = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
353 size_in_bytes, host_handle);
354 } else {
355 LOG(ERROR) << "Couldn't find array buffer id: "
356 << raw_var_data_->host_handle_id;
357 var_ = PP_MakeUndefined();
358 }
359 } else if (raw_var_data_->shmem_type == ARRAY_BUFFER_SHMEM_PLUGIN) {
360 var_ = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
361 raw_var_data_->shmem_size,
362 raw_var_data_->plugin_handle.shmem());
363 } else {
364 var_ = PpapiGlobals::Get()->GetVarTracker()->MakeArrayBufferPPVar(
365 static_cast<uint32>(raw_var_data_->data.size()),
366 raw_var_data_->data.data());
367 }
368 break;
369 }
370 default:
371 NOTREACHED();
372 }
373 raw_var_data_.reset(NULL);
374 #endif
375 }
376
377 SerializedHandle* SerializedVar::Inner::GetPluginShmemHandle() const {
378 if (raw_var_data_.get()) {
379 if (raw_var_data_->type == PP_VARTYPE_ARRAY_BUFFER) {
380 if (raw_var_data_->shmem_size != 0)
381 return &raw_var_data_->plugin_handle;
382 }
383 }
384 return NULL;
385 }
386
387 // SerializedVar --------------------------------------------------------------- 140 // SerializedVar ---------------------------------------------------------------
388 141
389 SerializedVar::SerializedVar() : inner_(new Inner) { 142 SerializedVar::SerializedVar() : inner_(new Inner) {
390 } 143 }
391 144
392 SerializedVar::SerializedVar(VarSerializationRules* serialization_rules) 145 SerializedVar::SerializedVar(VarSerializationRules* serialization_rules)
393 : inner_(new Inner(serialization_rules)) { 146 : inner_(new Inner(serialization_rules)) {
394 } 147 }
395 148
396 SerializedVar::~SerializedVar() { 149 SerializedVar::~SerializedVar() {
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 const std::string& str) { 427 const std::string& str) {
675 inner_->ForceSetVarValueForTest(StringVar::StringToPPVar(str)); 428 inner_->ForceSetVarValueForTest(StringVar::StringToPPVar(str));
676 } 429 }
677 430
678 SerializedVarTestReader::SerializedVarTestReader(const SerializedVar& var) 431 SerializedVarTestReader::SerializedVarTestReader(const SerializedVar& var)
679 : SerializedVar(var) { 432 : SerializedVar(var) {
680 } 433 }
681 434
682 } // namespace proxy 435 } // namespace proxy
683 } // namespace ppapi 436 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/proxy/serialized_var.h ('k') | ppapi/tests/test_post_message.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698