| OLD | NEW |
| 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 "base/memory/ref_counted.h" | |
| 9 #include "ipc/ipc_message_utils.h" | 8 #include "ipc/ipc_message_utils.h" |
| 10 #include "ppapi/proxy/dispatcher.h" | 9 #include "ppapi/proxy/dispatcher.h" |
| 11 #include "ppapi/proxy/interface_proxy.h" | 10 #include "ppapi/proxy/interface_proxy.h" |
| 12 #include "ppapi/proxy/ppapi_param_traits.h" | 11 #include "ppapi/proxy/ppapi_param_traits.h" |
| 13 #include "ppapi/proxy/var_serialization_rules.h" | |
| 14 #include "ppapi/shared_impl/ppapi_globals.h" | 12 #include "ppapi/shared_impl/ppapi_globals.h" |
| 15 #include "ppapi/shared_impl/var.h" | 13 #include "ppapi/shared_impl/var.h" |
| 16 | 14 |
| 17 namespace ppapi { | 15 namespace ppapi { |
| 18 namespace proxy { | 16 namespace proxy { |
| 19 | 17 |
| 20 // SerializedVar::Inner -------------------------------------------------------- | 18 // SerializedVar::Inner -------------------------------------------------------- |
| 21 | 19 |
| 22 SerializedVar::Inner::Inner() | 20 SerializedVar::Inner::Inner() |
| 23 : serialization_rules_(NULL), | 21 : serialization_rules_(NULL), |
| 24 var_(PP_MakeUndefined()), | 22 var_(PP_MakeUndefined()), |
| 25 cleanup_mode_(CLEANUP_NONE), | 23 cleanup_mode_(CLEANUP_NONE) { |
| 26 dispatcher_for_end_send_pass_ref_(NULL) { | |
| 27 #ifndef NDEBUG | 24 #ifndef NDEBUG |
| 28 has_been_serialized_ = false; | 25 has_been_serialized_ = false; |
| 29 has_been_deserialized_ = false; | 26 has_been_deserialized_ = false; |
| 30 #endif | 27 #endif |
| 31 } | 28 } |
| 32 | 29 |
| 33 SerializedVar::Inner::Inner(VarSerializationRules* serialization_rules) | 30 SerializedVar::Inner::Inner(VarSerializationRules* serialization_rules) |
| 34 : serialization_rules_(serialization_rules), | 31 : serialization_rules_(serialization_rules), |
| 35 var_(PP_MakeUndefined()), | 32 var_(PP_MakeUndefined()), |
| 36 cleanup_mode_(CLEANUP_NONE), | 33 cleanup_mode_(CLEANUP_NONE) { |
| 37 dispatcher_for_end_send_pass_ref_(NULL) { | |
| 38 #ifndef NDEBUG | 34 #ifndef NDEBUG |
| 39 has_been_serialized_ = false; | 35 has_been_serialized_ = false; |
| 40 has_been_deserialized_ = false; | 36 has_been_deserialized_ = false; |
| 41 #endif | 37 #endif |
| 42 } | 38 } |
| 43 | 39 |
| 44 SerializedVar::Inner::~Inner() { | 40 SerializedVar::Inner::~Inner() { |
| 45 switch (cleanup_mode_) { | 41 switch (cleanup_mode_) { |
| 46 case END_SEND_PASS_REF: | 42 case END_SEND_PASS_REF: |
| 47 DCHECK(dispatcher_for_end_send_pass_ref_); | 43 serialization_rules_->EndSendPassRef(var_); |
| 48 serialization_rules_->EndSendPassRef(var_, | |
| 49 dispatcher_for_end_send_pass_ref_); | |
| 50 break; | 44 break; |
| 51 case END_RECEIVE_CALLER_OWNED: | 45 case END_RECEIVE_CALLER_OWNED: |
| 52 serialization_rules_->EndReceiveCallerOwned(var_); | 46 serialization_rules_->EndReceiveCallerOwned(var_); |
| 53 break; | 47 break; |
| 54 default: | 48 default: |
| 55 break; | 49 break; |
| 56 } | 50 } |
| 57 } | 51 } |
| 58 | 52 |
| 59 PP_Var SerializedVar::Inner::GetVar() const { | 53 PP_Var SerializedVar::Inner::GetVar() const { |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 } | 211 } |
| 218 | 212 |
| 219 // All success cases get here. We avoid writing the type above so that the | 213 // All success cases get here. We avoid writing the type above so that the |
| 220 // output param is untouched (defaults to VARTYPE_UNDEFINED) even in the | 214 // output param is untouched (defaults to VARTYPE_UNDEFINED) even in the |
| 221 // failure case. | 215 // failure case. |
| 222 if (success) | 216 if (success) |
| 223 var_.type = static_cast<PP_VarType>(type); | 217 var_.type = static_cast<PP_VarType>(type); |
| 224 return success; | 218 return success; |
| 225 } | 219 } |
| 226 | 220 |
| 227 void SerializedVar::Inner::SetCleanupModeToEndSendPassRef( | 221 void SerializedVar::Inner::SetCleanupModeToEndSendPassRef() { |
| 228 Dispatcher* dispatcher) { | |
| 229 DCHECK(dispatcher); | |
| 230 DCHECK(!dispatcher_for_end_send_pass_ref_); | |
| 231 dispatcher_for_end_send_pass_ref_ = dispatcher; | |
| 232 cleanup_mode_ = END_SEND_PASS_REF; | 222 cleanup_mode_ = END_SEND_PASS_REF; |
| 233 } | 223 } |
| 234 | 224 |
| 235 void SerializedVar::Inner::SetCleanupModeToEndReceiveCallerOwned() { | 225 void SerializedVar::Inner::SetCleanupModeToEndReceiveCallerOwned() { |
| 236 cleanup_mode_ = END_RECEIVE_CALLER_OWNED; | 226 cleanup_mode_ = END_RECEIVE_CALLER_OWNED; |
| 237 } | 227 } |
| 238 | 228 |
| 239 // SerializedVar --------------------------------------------------------------- | 229 // SerializedVar --------------------------------------------------------------- |
| 240 | 230 |
| 241 SerializedVar::SerializedVar() : inner_(new Inner) { | 231 SerializedVar::SerializedVar() : inner_(new Inner) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 272 } | 262 } |
| 273 | 263 |
| 274 ReceiveSerializedVarReturnValue::ReceiveSerializedVarReturnValue( | 264 ReceiveSerializedVarReturnValue::ReceiveSerializedVarReturnValue( |
| 275 const SerializedVar& serialized) | 265 const SerializedVar& serialized) |
| 276 : SerializedVar(serialized) { | 266 : SerializedVar(serialized) { |
| 277 } | 267 } |
| 278 | 268 |
| 279 PP_Var ReceiveSerializedVarReturnValue::Return(Dispatcher* dispatcher) { | 269 PP_Var ReceiveSerializedVarReturnValue::Return(Dispatcher* dispatcher) { |
| 280 inner_->set_serialization_rules(dispatcher->serialization_rules()); | 270 inner_->set_serialization_rules(dispatcher->serialization_rules()); |
| 281 inner_->SetVar(inner_->serialization_rules()->ReceivePassRef( | 271 inner_->SetVar(inner_->serialization_rules()->ReceivePassRef( |
| 282 inner_->GetVar(), dispatcher)); | 272 inner_->GetVar())); |
| 283 return inner_->GetVar(); | 273 return inner_->GetVar(); |
| 284 } | 274 } |
| 285 | 275 |
| 286 // ReceiveSerializedException -------------------------------------------------- | 276 // ReceiveSerializedException -------------------------------------------------- |
| 287 | 277 |
| 288 ReceiveSerializedException::ReceiveSerializedException(Dispatcher* dispatcher, | 278 ReceiveSerializedException::ReceiveSerializedException(Dispatcher* dispatcher, |
| 289 PP_Var* exception) | 279 PP_Var* exception) |
| 290 : SerializedVar(dispatcher->serialization_rules()), | 280 : SerializedVar(dispatcher->serialization_rules()), |
| 291 dispatcher_(dispatcher), | |
| 292 exception_(exception) { | 281 exception_(exception) { |
| 293 } | 282 } |
| 294 | 283 |
| 295 ReceiveSerializedException::~ReceiveSerializedException() { | 284 ReceiveSerializedException::~ReceiveSerializedException() { |
| 296 if (exception_) { | 285 if (exception_) { |
| 297 // When an output exception is specified, it will take ownership of the | 286 // When an output exception is specified, it will take ownership of the |
| 298 // reference. | 287 // reference. |
| 299 inner_->SetVar( | 288 inner_->SetVar( |
| 300 inner_->serialization_rules()->ReceivePassRef(inner_->GetVar(), | 289 inner_->serialization_rules()->ReceivePassRef(inner_->GetVar())); |
| 301 dispatcher_)); | |
| 302 *exception_ = inner_->GetVar(); | 290 *exception_ = inner_->GetVar(); |
| 303 } else { | 291 } else { |
| 304 // When no output exception is specified, the browser thinks we have a ref | 292 // When no output exception is specified, the browser thinks we have a ref |
| 305 // to an object that we don't want (this will happen only in the plugin | 293 // to an object that we don't want (this will happen only in the plugin |
| 306 // since the browser will always specify an out exception for the plugin to | 294 // since the browser will always specify an out exception for the plugin to |
| 307 // write into). | 295 // write into). |
| 308 // | 296 // |
| 309 // Strings don't need this handling since we can just avoid creating a | 297 // Strings don't need this handling since we can just avoid creating a |
| 310 // Var from the std::string in the first place. | 298 // Var from the std::string in the first place. |
| 311 if (inner_->GetVar().type == PP_VARTYPE_OBJECT) | 299 if (inner_->GetVar().type == PP_VARTYPE_OBJECT) |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 346 } | 334 } |
| 347 | 335 |
| 348 std::vector<SerializedVar>* ReceiveSerializedVarVectorOutParam::OutParam() { | 336 std::vector<SerializedVar>* ReceiveSerializedVarVectorOutParam::OutParam() { |
| 349 return &vector_; | 337 return &vector_; |
| 350 } | 338 } |
| 351 | 339 |
| 352 // SerializedVarReceiveInput --------------------------------------------------- | 340 // SerializedVarReceiveInput --------------------------------------------------- |
| 353 | 341 |
| 354 SerializedVarReceiveInput::SerializedVarReceiveInput( | 342 SerializedVarReceiveInput::SerializedVarReceiveInput( |
| 355 const SerializedVar& serialized) | 343 const SerializedVar& serialized) |
| 356 : serialized_(serialized), | 344 : serialized_(serialized) { |
| 357 dispatcher_(NULL), | |
| 358 var_(PP_MakeUndefined()) { | |
| 359 } | 345 } |
| 360 | 346 |
| 361 SerializedVarReceiveInput::~SerializedVarReceiveInput() { | 347 SerializedVarReceiveInput::~SerializedVarReceiveInput() { |
| 362 } | 348 } |
| 363 | 349 |
| 364 PP_Var SerializedVarReceiveInput::Get(Dispatcher* dispatcher) { | 350 PP_Var SerializedVarReceiveInput::Get(Dispatcher* dispatcher) { |
| 365 serialized_.inner_->set_serialization_rules( | 351 serialized_.inner_->set_serialization_rules( |
| 366 dispatcher->serialization_rules()); | 352 dispatcher->serialization_rules()); |
| 367 | 353 |
| 368 // Ensure that when the serialized var goes out of scope it cleans up the | 354 // Ensure that when the serialized var goes out of scope it cleans up the |
| 369 // stuff we're making in BeginReceiveCallerOwned. | 355 // stuff we're making in BeginReceiveCallerOwned. |
| 370 serialized_.inner_->SetCleanupModeToEndReceiveCallerOwned(); | 356 serialized_.inner_->SetCleanupModeToEndReceiveCallerOwned(); |
| 371 | 357 |
| 372 serialized_.inner_->SetVar( | 358 serialized_.inner_->SetVar( |
| 373 serialized_.inner_->serialization_rules()->BeginReceiveCallerOwned( | 359 serialized_.inner_->serialization_rules()->BeginReceiveCallerOwned( |
| 374 serialized_.inner_->GetVar(), | 360 serialized_.inner_->GetVar())); |
| 375 dispatcher)); | |
| 376 return serialized_.inner_->GetVar(); | 361 return serialized_.inner_->GetVar(); |
| 377 } | 362 } |
| 378 | 363 |
| 379 // SerializedVarVectorReceiveInput --------------------------------------------- | 364 // SerializedVarVectorReceiveInput --------------------------------------------- |
| 380 | 365 |
| 381 SerializedVarVectorReceiveInput::SerializedVarVectorReceiveInput( | 366 SerializedVarVectorReceiveInput::SerializedVarVectorReceiveInput( |
| 382 const std::vector<SerializedVar>& serialized) | 367 const std::vector<SerializedVar>& serialized) |
| 383 : serialized_(serialized) { | 368 : serialized_(serialized) { |
| 384 } | 369 } |
| 385 | 370 |
| 386 SerializedVarVectorReceiveInput::~SerializedVarVectorReceiveInput() { | 371 SerializedVarVectorReceiveInput::~SerializedVarVectorReceiveInput() { |
| 387 for (size_t i = 0; i < deserialized_.size(); i++) { | 372 for (size_t i = 0; i < deserialized_.size(); i++) { |
| 388 serialized_[i].inner_->serialization_rules()->EndReceiveCallerOwned( | 373 serialized_[i].inner_->serialization_rules()->EndReceiveCallerOwned( |
| 389 deserialized_[i]); | 374 deserialized_[i]); |
| 390 } | 375 } |
| 391 } | 376 } |
| 392 | 377 |
| 393 PP_Var* SerializedVarVectorReceiveInput::Get(Dispatcher* dispatcher, | 378 PP_Var* SerializedVarVectorReceiveInput::Get(Dispatcher* dispatcher, |
| 394 uint32_t* array_size) { | 379 uint32_t* array_size) { |
| 395 deserialized_.resize(serialized_.size()); | 380 deserialized_.resize(serialized_.size()); |
| 396 for (size_t i = 0; i < serialized_.size(); i++) { | 381 for (size_t i = 0; i < serialized_.size(); i++) { |
| 397 // The vectors must be able to clean themselves up after this call is | 382 // The vectors must be able to clean themselves up after this call is |
| 398 // torn down. | 383 // torn down. |
| 399 serialized_[i].inner_->set_serialization_rules( | 384 serialized_[i].inner_->set_serialization_rules( |
| 400 dispatcher->serialization_rules()); | 385 dispatcher->serialization_rules()); |
| 401 | 386 |
| 402 serialized_[i].inner_->SetVar( | 387 serialized_[i].inner_->SetVar( |
| 403 serialized_[i].inner_->serialization_rules()->BeginReceiveCallerOwned( | 388 serialized_[i].inner_->serialization_rules()->BeginReceiveCallerOwned( |
| 404 serialized_[i].inner_->GetVar(), | 389 serialized_[i].inner_->GetVar())); |
| 405 dispatcher)); | |
| 406 deserialized_[i] = serialized_[i].inner_->GetVar(); | 390 deserialized_[i] = serialized_[i].inner_->GetVar(); |
| 407 } | 391 } |
| 408 | 392 |
| 409 *array_size = static_cast<uint32_t>(serialized_.size()); | 393 *array_size = static_cast<uint32_t>(serialized_.size()); |
| 410 return deserialized_.empty() ? NULL : &deserialized_[0]; | 394 return deserialized_.empty() ? NULL : &deserialized_[0]; |
| 411 } | 395 } |
| 412 | 396 |
| 413 // SerializedVarReturnValue ---------------------------------------------------- | 397 // SerializedVarReturnValue ---------------------------------------------------- |
| 414 | 398 |
| 415 SerializedVarReturnValue::SerializedVarReturnValue(SerializedVar* serialized) | 399 SerializedVarReturnValue::SerializedVarReturnValue(SerializedVar* serialized) |
| 416 : serialized_(serialized) { | 400 : serialized_(serialized) { |
| 417 } | 401 } |
| 418 | 402 |
| 419 void SerializedVarReturnValue::Return(Dispatcher* dispatcher, | 403 void SerializedVarReturnValue::Return(Dispatcher* dispatcher, |
| 420 const PP_Var& var) { | 404 const PP_Var& var) { |
| 421 serialized_->inner_->set_serialization_rules( | 405 serialized_->inner_->set_serialization_rules( |
| 422 dispatcher->serialization_rules()); | 406 dispatcher->serialization_rules()); |
| 423 | 407 |
| 424 // Var must clean up after our BeginSendPassRef call. | 408 // Var must clean up after our BeginSendPassRef call. |
| 425 serialized_->inner_->SetCleanupModeToEndSendPassRef(dispatcher); | 409 serialized_->inner_->SetCleanupModeToEndSendPassRef(); |
| 426 | 410 |
| 427 serialized_->inner_->SetVar( | 411 serialized_->inner_->SetVar( |
| 428 dispatcher->serialization_rules()->BeginSendPassRef(var)); | 412 dispatcher->serialization_rules()->BeginSendPassRef(var)); |
| 429 } | 413 } |
| 430 | 414 |
| 431 // static | 415 // static |
| 432 SerializedVar SerializedVarReturnValue::Convert(Dispatcher* dispatcher, | 416 SerializedVar SerializedVarReturnValue::Convert(Dispatcher* dispatcher, |
| 433 const PP_Var& var) { | 417 const PP_Var& var) { |
| 434 // Mimic what happens in the normal case. | 418 // Mimic what happens in the normal case. |
| 435 SerializedVar result; | 419 SerializedVar result; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 450 if (serialized_->inner_->serialization_rules()) { | 434 if (serialized_->inner_->serialization_rules()) { |
| 451 // When unset, OutParam wasn't called. We'll just leave the var untouched | 435 // When unset, OutParam wasn't called. We'll just leave the var untouched |
| 452 // in that case. | 436 // in that case. |
| 453 serialized_->inner_->SetVar( | 437 serialized_->inner_->SetVar( |
| 454 serialized_->inner_->serialization_rules()->BeginSendPassRef( | 438 serialized_->inner_->serialization_rules()->BeginSendPassRef( |
| 455 writable_var_)); | 439 writable_var_)); |
| 456 | 440 |
| 457 // Normally the current object will be created on the stack to wrap a | 441 // Normally the current object will be created on the stack to wrap a |
| 458 // SerializedVar and won't have a scope around the actual IPC send. So we | 442 // SerializedVar and won't have a scope around the actual IPC send. So we |
| 459 // need to tell the SerializedVar to do the begin/end send pass ref calls. | 443 // need to tell the SerializedVar to do the begin/end send pass ref calls. |
| 460 serialized_->inner_->SetCleanupModeToEndSendPassRef(dispatcher_); | 444 serialized_->inner_->SetCleanupModeToEndSendPassRef(); |
| 461 } | 445 } |
| 462 } | 446 } |
| 463 | 447 |
| 464 PP_Var* SerializedVarOutParam::OutParam(Dispatcher* dispatcher) { | 448 PP_Var* SerializedVarOutParam::OutParam(Dispatcher* dispatcher) { |
| 465 dispatcher_ = dispatcher; | 449 dispatcher_ = dispatcher; |
| 466 serialized_->inner_->set_serialization_rules( | 450 serialized_->inner_->set_serialization_rules( |
| 467 dispatcher->serialization_rules()); | 451 dispatcher->serialization_rules()); |
| 468 return &writable_var_; | 452 return &writable_var_; |
| 469 } | 453 } |
| 470 | 454 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 514 const std::string& str) { | 498 const std::string& str) { |
| 515 inner_->ForceSetVarValueForTest(StringVar::StringToPPVar(str)); | 499 inner_->ForceSetVarValueForTest(StringVar::StringToPPVar(str)); |
| 516 } | 500 } |
| 517 | 501 |
| 518 SerializedVarTestReader::SerializedVarTestReader(const SerializedVar& var) | 502 SerializedVarTestReader::SerializedVarTestReader(const SerializedVar& var) |
| 519 : SerializedVar(var) { | 503 : SerializedVar(var) { |
| 520 } | 504 } |
| 521 | 505 |
| 522 } // namespace proxy | 506 } // namespace proxy |
| 523 } // namespace ppapi | 507 } // namespace ppapi |
| 524 | |
| OLD | NEW |