| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "mojo/edk/system/core.h" | 5 #include "mojo/edk/system/core.h" |
| 6 | 6 |
| 7 #include <string.h> | 7 #include <string.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 // This is an unnecessarily large limit that is relatively easy to enforce. | 44 // This is an unnecessarily large limit that is relatively easy to enforce. |
| 45 const uint32_t kMaxHandlesPerMessage = 1024 * 1024; | 45 const uint32_t kMaxHandlesPerMessage = 1024 * 1024; |
| 46 | 46 |
| 47 // TODO: Maybe we could negotiate a debugging pipe ID for cross-process pipes | 47 // TODO: Maybe we could negotiate a debugging pipe ID for cross-process pipes |
| 48 // too; for now we just use a constant. This only affects bootstrap pipes. | 48 // too; for now we just use a constant. This only affects bootstrap pipes. |
| 49 const uint64_t kUnknownPipeIdForDebug = 0x7f7f7f7f7f7f7f7fUL; | 49 const uint64_t kUnknownPipeIdForDebug = 0x7f7f7f7f7f7f7f7fUL; |
| 50 | 50 |
| 51 void CallWatchCallback(MojoWatchCallback callback, | 51 void CallWatchCallback(MojoWatchCallback callback, |
| 52 uintptr_t context, | 52 uintptr_t context, |
| 53 MojoResult result, | 53 MojoResult result, |
| 54 const HandleSignalsState& signals_state) { | 54 const HandleSignalsState& signals_state, |
| 55 callback(context, result, | 55 MojoWatchNotificationFlags flags) { |
| 56 static_cast<MojoHandleSignalsState>(signals_state)); | 56 callback(context, result, static_cast<MojoHandleSignalsState>(signals_state), |
| 57 flags); |
| 57 } | 58 } |
| 58 | 59 |
| 59 } // namespace | 60 } // namespace |
| 60 | 61 |
| 61 Core::Core() {} | 62 Core::Core() {} |
| 62 | 63 |
| 63 Core::~Core() { | 64 Core::~Core() { |
| 64 if (node_controller_ && node_controller_->io_task_runner()) { | 65 if (node_controller_ && node_controller_->io_task_runner()) { |
| 65 // If this races with IO thread shutdown the callback will be dropped and | 66 // If this races with IO thread shutdown the callback will be dropped and |
| 66 // the NodeController will be shutdown on this thread anyway, which is also | 67 // the NodeController will be shutdown on this thread anyway, which is also |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 270 if (rv == MOJO_RESULT_OK) | 271 if (rv == MOJO_RESULT_OK) |
| 271 ignore_result(waiter.release()); | 272 ignore_result(waiter.release()); |
| 272 return rv; | 273 return rv; |
| 273 } | 274 } |
| 274 | 275 |
| 275 MojoTimeTicks Core::GetTimeTicksNow() { | 276 MojoTimeTicks Core::GetTimeTicksNow() { |
| 276 return base::TimeTicks::Now().ToInternalValue(); | 277 return base::TimeTicks::Now().ToInternalValue(); |
| 277 } | 278 } |
| 278 | 279 |
| 279 MojoResult Core::Close(MojoHandle handle) { | 280 MojoResult Core::Close(MojoHandle handle) { |
| 280 RequestContext request_context; | 281 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 281 scoped_refptr<Dispatcher> dispatcher; | 282 scoped_refptr<Dispatcher> dispatcher; |
| 282 { | 283 { |
| 283 base::AutoLock lock(handles_lock_); | 284 base::AutoLock lock(handles_lock_); |
| 284 MojoResult rv = handles_.GetAndRemoveDispatcher(handle, &dispatcher); | 285 MojoResult rv = handles_.GetAndRemoveDispatcher(handle, &dispatcher); |
| 285 if (rv != MOJO_RESULT_OK) | 286 if (rv != MOJO_RESULT_OK) |
| 286 return rv; | 287 return rv; |
| 287 } | 288 } |
| 288 dispatcher->Close(); | 289 dispatcher->Close(); |
| 289 return MOJO_RESULT_OK; | 290 return MOJO_RESULT_OK; |
| 290 } | 291 } |
| 291 | 292 |
| 292 MojoResult Core::Wait(MojoHandle handle, | 293 MojoResult Core::Wait(MojoHandle handle, |
| 293 MojoHandleSignals signals, | 294 MojoHandleSignals signals, |
| 294 MojoDeadline deadline, | 295 MojoDeadline deadline, |
| 295 MojoHandleSignalsState* signals_state) { | 296 MojoHandleSignalsState* signals_state) { |
| 296 RequestContext request_context; | 297 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 297 uint32_t unused = static_cast<uint32_t>(-1); | 298 uint32_t unused = static_cast<uint32_t>(-1); |
| 298 HandleSignalsState hss; | 299 HandleSignalsState hss; |
| 299 MojoResult rv = WaitManyInternal(&handle, &signals, 1, deadline, &unused, | 300 MojoResult rv = WaitManyInternal(&handle, &signals, 1, deadline, &unused, |
| 300 signals_state ? &hss : nullptr); | 301 signals_state ? &hss : nullptr); |
| 301 if (rv != MOJO_RESULT_INVALID_ARGUMENT && signals_state) | 302 if (rv != MOJO_RESULT_INVALID_ARGUMENT && signals_state) |
| 302 *signals_state = hss; | 303 *signals_state = hss; |
| 303 return rv; | 304 return rv; |
| 304 } | 305 } |
| 305 | 306 |
| 306 MojoResult Core::WaitMany(const MojoHandle* handles, | 307 MojoResult Core::WaitMany(const MojoHandle* handles, |
| 307 const MojoHandleSignals* signals, | 308 const MojoHandleSignals* signals, |
| 308 uint32_t num_handles, | 309 uint32_t num_handles, |
| 309 MojoDeadline deadline, | 310 MojoDeadline deadline, |
| 310 uint32_t* result_index, | 311 uint32_t* result_index, |
| 311 MojoHandleSignalsState* signals_state) { | 312 MojoHandleSignalsState* signals_state) { |
| 312 RequestContext request_context; | 313 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 313 if (num_handles < 1) | 314 if (num_handles < 1) |
| 314 return MOJO_RESULT_INVALID_ARGUMENT; | 315 return MOJO_RESULT_INVALID_ARGUMENT; |
| 315 if (num_handles > GetConfiguration().max_wait_many_num_handles) | 316 if (num_handles > GetConfiguration().max_wait_many_num_handles) |
| 316 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 317 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 317 | 318 |
| 318 uint32_t index = static_cast<uint32_t>(-1); | 319 uint32_t index = static_cast<uint32_t>(-1); |
| 319 MojoResult rv; | 320 MojoResult rv; |
| 320 if (!signals_state) { | 321 if (!signals_state) { |
| 321 rv = WaitManyInternal(handles, signals, num_handles, deadline, &index, | 322 rv = WaitManyInternal(handles, signals, num_handles, deadline, &index, |
| 322 nullptr); | 323 nullptr); |
| 323 } else { | 324 } else { |
| 324 // Note: The |reinterpret_cast| is safe, since |HandleSignalsState| is a | 325 // Note: The |reinterpret_cast| is safe, since |HandleSignalsState| is a |
| 325 // subclass of |MojoHandleSignalsState| that doesn't add any data members. | 326 // subclass of |MojoHandleSignalsState| that doesn't add any data members. |
| 326 rv = WaitManyInternal(handles, signals, num_handles, deadline, &index, | 327 rv = WaitManyInternal(handles, signals, num_handles, deadline, &index, |
| 327 reinterpret_cast<HandleSignalsState*>(signals_state)); | 328 reinterpret_cast<HandleSignalsState*>(signals_state)); |
| 328 } | 329 } |
| 329 if (index != static_cast<uint32_t>(-1) && result_index) | 330 if (index != static_cast<uint32_t>(-1) && result_index) |
| 330 *result_index = index; | 331 *result_index = index; |
| 331 return rv; | 332 return rv; |
| 332 } | 333 } |
| 333 | 334 |
| 334 MojoResult Core::Watch(MojoHandle handle, | 335 MojoResult Core::Watch(MojoHandle handle, |
| 335 MojoHandleSignals signals, | 336 MojoHandleSignals signals, |
| 336 MojoWatchCallback callback, | 337 MojoWatchCallback callback, |
| 337 uintptr_t context) { | 338 uintptr_t context) { |
| 338 RequestContext request_context; | 339 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 339 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handle); | 340 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handle); |
| 340 if (!dispatcher) | 341 if (!dispatcher) |
| 341 return MOJO_RESULT_INVALID_ARGUMENT; | 342 return MOJO_RESULT_INVALID_ARGUMENT; |
| 342 return dispatcher->Watch( | 343 return dispatcher->Watch( |
| 343 signals, base::Bind(&CallWatchCallback, callback, context), context); | 344 signals, base::Bind(&CallWatchCallback, callback, context), context); |
| 344 } | 345 } |
| 345 | 346 |
| 346 MojoResult Core::CancelWatch(MojoHandle handle, uintptr_t context) { | 347 MojoResult Core::CancelWatch(MojoHandle handle, uintptr_t context) { |
| 347 RequestContext request_context; | 348 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 348 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handle); | 349 scoped_refptr<Dispatcher> dispatcher = GetDispatcher(handle); |
| 349 if (!dispatcher) | 350 if (!dispatcher) |
| 350 return MOJO_RESULT_INVALID_ARGUMENT; | 351 return MOJO_RESULT_INVALID_ARGUMENT; |
| 351 return dispatcher->CancelWatch(context); | 352 return dispatcher->CancelWatch(context); |
| 352 } | 353 } |
| 353 | 354 |
| 354 MojoResult Core::CreateWaitSet(MojoHandle* wait_set_handle) { | 355 MojoResult Core::CreateWaitSet(MojoHandle* wait_set_handle) { |
| 355 RequestContext request_context; | 356 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 356 if (!wait_set_handle) | 357 if (!wait_set_handle) |
| 357 return MOJO_RESULT_INVALID_ARGUMENT; | 358 return MOJO_RESULT_INVALID_ARGUMENT; |
| 358 | 359 |
| 359 scoped_refptr<WaitSetDispatcher> dispatcher = new WaitSetDispatcher(); | 360 scoped_refptr<WaitSetDispatcher> dispatcher = new WaitSetDispatcher(); |
| 360 MojoHandle h = AddDispatcher(dispatcher); | 361 MojoHandle h = AddDispatcher(dispatcher); |
| 361 if (h == MOJO_HANDLE_INVALID) { | 362 if (h == MOJO_HANDLE_INVALID) { |
| 362 LOG(ERROR) << "Handle table full"; | 363 LOG(ERROR) << "Handle table full"; |
| 363 dispatcher->Close(); | 364 dispatcher->Close(); |
| 364 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 365 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 365 } | 366 } |
| 366 | 367 |
| 367 *wait_set_handle = h; | 368 *wait_set_handle = h; |
| 368 return MOJO_RESULT_OK; | 369 return MOJO_RESULT_OK; |
| 369 } | 370 } |
| 370 | 371 |
| 371 MojoResult Core::AddHandle(MojoHandle wait_set_handle, | 372 MojoResult Core::AddHandle(MojoHandle wait_set_handle, |
| 372 MojoHandle handle, | 373 MojoHandle handle, |
| 373 MojoHandleSignals signals) { | 374 MojoHandleSignals signals) { |
| 374 RequestContext request_context; | 375 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 375 scoped_refptr<Dispatcher> wait_set_dispatcher(GetDispatcher(wait_set_handle)); | 376 scoped_refptr<Dispatcher> wait_set_dispatcher(GetDispatcher(wait_set_handle)); |
| 376 if (!wait_set_dispatcher) | 377 if (!wait_set_dispatcher) |
| 377 return MOJO_RESULT_INVALID_ARGUMENT; | 378 return MOJO_RESULT_INVALID_ARGUMENT; |
| 378 | 379 |
| 379 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(handle)); | 380 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(handle)); |
| 380 if (!dispatcher) | 381 if (!dispatcher) |
| 381 return MOJO_RESULT_INVALID_ARGUMENT; | 382 return MOJO_RESULT_INVALID_ARGUMENT; |
| 382 | 383 |
| 383 return wait_set_dispatcher->AddWaitingDispatcher(dispatcher, signals, handle); | 384 return wait_set_dispatcher->AddWaitingDispatcher(dispatcher, signals, handle); |
| 384 } | 385 } |
| 385 | 386 |
| 386 MojoResult Core::RemoveHandle(MojoHandle wait_set_handle, | 387 MojoResult Core::RemoveHandle(MojoHandle wait_set_handle, |
| 387 MojoHandle handle) { | 388 MojoHandle handle) { |
| 388 RequestContext request_context; | 389 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 389 scoped_refptr<Dispatcher> wait_set_dispatcher(GetDispatcher(wait_set_handle)); | 390 scoped_refptr<Dispatcher> wait_set_dispatcher(GetDispatcher(wait_set_handle)); |
| 390 if (!wait_set_dispatcher) | 391 if (!wait_set_dispatcher) |
| 391 return MOJO_RESULT_INVALID_ARGUMENT; | 392 return MOJO_RESULT_INVALID_ARGUMENT; |
| 392 | 393 |
| 393 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(handle)); | 394 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(handle)); |
| 394 if (!dispatcher) | 395 if (!dispatcher) |
| 395 return MOJO_RESULT_INVALID_ARGUMENT; | 396 return MOJO_RESULT_INVALID_ARGUMENT; |
| 396 | 397 |
| 397 return wait_set_dispatcher->RemoveWaitingDispatcher(dispatcher); | 398 return wait_set_dispatcher->RemoveWaitingDispatcher(dispatcher); |
| 398 } | 399 } |
| 399 | 400 |
| 400 MojoResult Core::GetReadyHandles(MojoHandle wait_set_handle, | 401 MojoResult Core::GetReadyHandles(MojoHandle wait_set_handle, |
| 401 uint32_t* count, | 402 uint32_t* count, |
| 402 MojoHandle* handles, | 403 MojoHandle* handles, |
| 403 MojoResult* results, | 404 MojoResult* results, |
| 404 MojoHandleSignalsState* signals_states) { | 405 MojoHandleSignalsState* signals_states) { |
| 405 RequestContext request_context; | 406 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 406 if (!handles || !count || !(*count) || !results) | 407 if (!handles || !count || !(*count) || !results) |
| 407 return MOJO_RESULT_INVALID_ARGUMENT; | 408 return MOJO_RESULT_INVALID_ARGUMENT; |
| 408 | 409 |
| 409 scoped_refptr<Dispatcher> wait_set_dispatcher(GetDispatcher(wait_set_handle)); | 410 scoped_refptr<Dispatcher> wait_set_dispatcher(GetDispatcher(wait_set_handle)); |
| 410 if (!wait_set_dispatcher) | 411 if (!wait_set_dispatcher) |
| 411 return MOJO_RESULT_INVALID_ARGUMENT; | 412 return MOJO_RESULT_INVALID_ARGUMENT; |
| 412 | 413 |
| 413 DispatcherVector awoken_dispatchers; | 414 DispatcherVector awoken_dispatchers; |
| 414 base::StackVector<uintptr_t, 16> contexts; | 415 base::StackVector<uintptr_t, 16> contexts; |
| 415 contexts->assign(*count, MOJO_HANDLE_INVALID); | 416 contexts->assign(*count, MOJO_HANDLE_INVALID); |
| 416 | 417 |
| 417 MojoResult result = wait_set_dispatcher->GetReadyDispatchers( | 418 MojoResult result = wait_set_dispatcher->GetReadyDispatchers( |
| 418 count, &awoken_dispatchers, results, contexts->data()); | 419 count, &awoken_dispatchers, results, contexts->data()); |
| 419 | 420 |
| 420 if (result == MOJO_RESULT_OK) { | 421 if (result == MOJO_RESULT_OK) { |
| 421 for (size_t i = 0; i < *count; i++) { | 422 for (size_t i = 0; i < *count; i++) { |
| 422 handles[i] = static_cast<MojoHandle>(contexts[i]); | 423 handles[i] = static_cast<MojoHandle>(contexts[i]); |
| 423 if (signals_states) | 424 if (signals_states) |
| 424 signals_states[i] = awoken_dispatchers[i]->GetHandleSignalsState(); | 425 signals_states[i] = awoken_dispatchers[i]->GetHandleSignalsState(); |
| 425 } | 426 } |
| 426 } | 427 } |
| 427 | 428 |
| 428 return result; | 429 return result; |
| 429 } | 430 } |
| 430 | 431 |
| 431 MojoResult Core::CreateMessagePipe( | 432 MojoResult Core::CreateMessagePipe( |
| 432 const MojoCreateMessagePipeOptions* options, | 433 const MojoCreateMessagePipeOptions* options, |
| 433 MojoHandle* message_pipe_handle0, | 434 MojoHandle* message_pipe_handle0, |
| 434 MojoHandle* message_pipe_handle1) { | 435 MojoHandle* message_pipe_handle1) { |
| 435 RequestContext request_context; | 436 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 436 ports::PortRef port0, port1; | 437 ports::PortRef port0, port1; |
| 437 GetNodeController()->node()->CreatePortPair(&port0, &port1); | 438 GetNodeController()->node()->CreatePortPair(&port0, &port1); |
| 438 | 439 |
| 439 CHECK(message_pipe_handle0); | 440 CHECK(message_pipe_handle0); |
| 440 CHECK(message_pipe_handle1); | 441 CHECK(message_pipe_handle1); |
| 441 | 442 |
| 442 uint64_t pipe_id = base::RandUint64(); | 443 uint64_t pipe_id = base::RandUint64(); |
| 443 | 444 |
| 444 *message_pipe_handle0 = AddDispatcher( | 445 *message_pipe_handle0 = AddDispatcher( |
| 445 new MessagePipeDispatcher(GetNodeController(), port0, pipe_id, 0)); | 446 new MessagePipeDispatcher(GetNodeController(), port0, pipe_id, 0)); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 459 | 460 |
| 460 return MOJO_RESULT_OK; | 461 return MOJO_RESULT_OK; |
| 461 } | 462 } |
| 462 | 463 |
| 463 MojoResult Core::WriteMessage(MojoHandle message_pipe_handle, | 464 MojoResult Core::WriteMessage(MojoHandle message_pipe_handle, |
| 464 const void* bytes, | 465 const void* bytes, |
| 465 uint32_t num_bytes, | 466 uint32_t num_bytes, |
| 466 const MojoHandle* handles, | 467 const MojoHandle* handles, |
| 467 uint32_t num_handles, | 468 uint32_t num_handles, |
| 468 MojoWriteMessageFlags flags) { | 469 MojoWriteMessageFlags flags) { |
| 469 RequestContext request_context; | 470 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 470 auto dispatcher = GetDispatcher(message_pipe_handle); | 471 auto dispatcher = GetDispatcher(message_pipe_handle); |
| 471 if (!dispatcher) | 472 if (!dispatcher) |
| 472 return MOJO_RESULT_INVALID_ARGUMENT; | 473 return MOJO_RESULT_INVALID_ARGUMENT; |
| 473 | 474 |
| 474 if (num_handles == 0) // Fast path: no handles. | 475 if (num_handles == 0) // Fast path: no handles. |
| 475 return dispatcher->WriteMessage(bytes, num_bytes, nullptr, 0, flags); | 476 return dispatcher->WriteMessage(bytes, num_bytes, nullptr, 0, flags); |
| 476 | 477 |
| 477 CHECK(handles); | 478 CHECK(handles); |
| 478 | 479 |
| 479 if (num_handles > kMaxHandlesPerMessage) | 480 if (num_handles > kMaxHandlesPerMessage) |
| (...skipping 29 matching lines...) Expand all Loading... |
| 509 | 510 |
| 510 return rv; | 511 return rv; |
| 511 } | 512 } |
| 512 | 513 |
| 513 MojoResult Core::ReadMessage(MojoHandle message_pipe_handle, | 514 MojoResult Core::ReadMessage(MojoHandle message_pipe_handle, |
| 514 void* bytes, | 515 void* bytes, |
| 515 uint32_t* num_bytes, | 516 uint32_t* num_bytes, |
| 516 MojoHandle* handles, | 517 MojoHandle* handles, |
| 517 uint32_t* num_handles, | 518 uint32_t* num_handles, |
| 518 MojoReadMessageFlags flags) { | 519 MojoReadMessageFlags flags) { |
| 519 RequestContext request_context; | 520 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 520 CHECK((!num_handles || !*num_handles || handles) && | 521 CHECK((!num_handles || !*num_handles || handles) && |
| 521 (!num_bytes || !*num_bytes || bytes)); | 522 (!num_bytes || !*num_bytes || bytes)); |
| 522 auto dispatcher = GetDispatcher(message_pipe_handle); | 523 auto dispatcher = GetDispatcher(message_pipe_handle); |
| 523 if (!dispatcher) | 524 if (!dispatcher) |
| 524 return MOJO_RESULT_INVALID_ARGUMENT; | 525 return MOJO_RESULT_INVALID_ARGUMENT; |
| 525 return dispatcher->ReadMessage(bytes, num_bytes, handles, num_handles, flags); | 526 return dispatcher->ReadMessage(bytes, num_bytes, handles, num_handles, flags); |
| 526 } | 527 } |
| 527 | 528 |
| 528 MojoResult Core::FuseMessagePipes(MojoHandle handle0, MojoHandle handle1) { | 529 MojoResult Core::FuseMessagePipes(MojoHandle handle0, MojoHandle handle1) { |
| 529 RequestContext request_context; | 530 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 530 scoped_refptr<Dispatcher> dispatcher0; | 531 scoped_refptr<Dispatcher> dispatcher0; |
| 531 scoped_refptr<Dispatcher> dispatcher1; | 532 scoped_refptr<Dispatcher> dispatcher1; |
| 532 | 533 |
| 533 bool valid_handles = true; | 534 bool valid_handles = true; |
| 534 { | 535 { |
| 535 base::AutoLock lock(handles_lock_); | 536 base::AutoLock lock(handles_lock_); |
| 536 MojoResult result0 = handles_.GetAndRemoveDispatcher(handle0, &dispatcher0); | 537 MojoResult result0 = handles_.GetAndRemoveDispatcher(handle0, &dispatcher0); |
| 537 MojoResult result1 = handles_.GetAndRemoveDispatcher(handle1, &dispatcher1); | 538 MojoResult result1 = handles_.GetAndRemoveDispatcher(handle1, &dispatcher1); |
| 538 if (result0 != MOJO_RESULT_OK || result1 != MOJO_RESULT_OK || | 539 if (result0 != MOJO_RESULT_OK || result1 != MOJO_RESULT_OK || |
| 539 dispatcher0->GetType() != Dispatcher::Type::MESSAGE_PIPE || | 540 dispatcher0->GetType() != Dispatcher::Type::MESSAGE_PIPE || |
| (...skipping 17 matching lines...) Expand all Loading... |
| 557 if (!mpd0->Fuse(mpd1)) | 558 if (!mpd0->Fuse(mpd1)) |
| 558 return MOJO_RESULT_FAILED_PRECONDITION; | 559 return MOJO_RESULT_FAILED_PRECONDITION; |
| 559 | 560 |
| 560 return MOJO_RESULT_OK; | 561 return MOJO_RESULT_OK; |
| 561 } | 562 } |
| 562 | 563 |
| 563 MojoResult Core::CreateDataPipe( | 564 MojoResult Core::CreateDataPipe( |
| 564 const MojoCreateDataPipeOptions* options, | 565 const MojoCreateDataPipeOptions* options, |
| 565 MojoHandle* data_pipe_producer_handle, | 566 MojoHandle* data_pipe_producer_handle, |
| 566 MojoHandle* data_pipe_consumer_handle) { | 567 MojoHandle* data_pipe_consumer_handle) { |
| 567 RequestContext request_context; | 568 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 568 if (options && options->struct_size != sizeof(MojoCreateDataPipeOptions)) | 569 if (options && options->struct_size != sizeof(MojoCreateDataPipeOptions)) |
| 569 return MOJO_RESULT_INVALID_ARGUMENT; | 570 return MOJO_RESULT_INVALID_ARGUMENT; |
| 570 | 571 |
| 571 MojoCreateDataPipeOptions create_options; | 572 MojoCreateDataPipeOptions create_options; |
| 572 create_options.struct_size = sizeof(MojoCreateDataPipeOptions); | 573 create_options.struct_size = sizeof(MojoCreateDataPipeOptions); |
| 573 create_options.flags = options ? options->flags : 0; | 574 create_options.flags = options ? options->flags : 0; |
| 574 create_options.element_num_bytes = options ? options->element_num_bytes : 1; | 575 create_options.element_num_bytes = options ? options->element_num_bytes : 1; |
| 575 // TODO: Use Configuration to get default data pipe capacity. | 576 // TODO: Use Configuration to get default data pipe capacity. |
| 576 create_options.capacity_num_bytes = | 577 create_options.capacity_num_bytes = |
| 577 options && options->capacity_num_bytes ? options->capacity_num_bytes | 578 options && options->capacity_num_bytes ? options->capacity_num_bytes |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 613 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 614 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 614 } | 615 } |
| 615 | 616 |
| 616 return MOJO_RESULT_OK; | 617 return MOJO_RESULT_OK; |
| 617 } | 618 } |
| 618 | 619 |
| 619 MojoResult Core::WriteData(MojoHandle data_pipe_producer_handle, | 620 MojoResult Core::WriteData(MojoHandle data_pipe_producer_handle, |
| 620 const void* elements, | 621 const void* elements, |
| 621 uint32_t* num_bytes, | 622 uint32_t* num_bytes, |
| 622 MojoWriteDataFlags flags) { | 623 MojoWriteDataFlags flags) { |
| 623 RequestContext request_context; | 624 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 624 scoped_refptr<Dispatcher> dispatcher( | 625 scoped_refptr<Dispatcher> dispatcher( |
| 625 GetDispatcher(data_pipe_producer_handle)); | 626 GetDispatcher(data_pipe_producer_handle)); |
| 626 if (!dispatcher) | 627 if (!dispatcher) |
| 627 return MOJO_RESULT_INVALID_ARGUMENT; | 628 return MOJO_RESULT_INVALID_ARGUMENT; |
| 628 | 629 |
| 629 return dispatcher->WriteData(elements, num_bytes, flags); | 630 return dispatcher->WriteData(elements, num_bytes, flags); |
| 630 } | 631 } |
| 631 | 632 |
| 632 MojoResult Core::BeginWriteData(MojoHandle data_pipe_producer_handle, | 633 MojoResult Core::BeginWriteData(MojoHandle data_pipe_producer_handle, |
| 633 void** buffer, | 634 void** buffer, |
| 634 uint32_t* buffer_num_bytes, | 635 uint32_t* buffer_num_bytes, |
| 635 MojoWriteDataFlags flags) { | 636 MojoWriteDataFlags flags) { |
| 636 RequestContext request_context; | 637 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 637 scoped_refptr<Dispatcher> dispatcher( | 638 scoped_refptr<Dispatcher> dispatcher( |
| 638 GetDispatcher(data_pipe_producer_handle)); | 639 GetDispatcher(data_pipe_producer_handle)); |
| 639 if (!dispatcher) | 640 if (!dispatcher) |
| 640 return MOJO_RESULT_INVALID_ARGUMENT; | 641 return MOJO_RESULT_INVALID_ARGUMENT; |
| 641 | 642 |
| 642 return dispatcher->BeginWriteData(buffer, buffer_num_bytes, flags); | 643 return dispatcher->BeginWriteData(buffer, buffer_num_bytes, flags); |
| 643 } | 644 } |
| 644 | 645 |
| 645 MojoResult Core::EndWriteData(MojoHandle data_pipe_producer_handle, | 646 MojoResult Core::EndWriteData(MojoHandle data_pipe_producer_handle, |
| 646 uint32_t num_bytes_written) { | 647 uint32_t num_bytes_written) { |
| 647 RequestContext request_context; | 648 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 648 scoped_refptr<Dispatcher> dispatcher( | 649 scoped_refptr<Dispatcher> dispatcher( |
| 649 GetDispatcher(data_pipe_producer_handle)); | 650 GetDispatcher(data_pipe_producer_handle)); |
| 650 if (!dispatcher) | 651 if (!dispatcher) |
| 651 return MOJO_RESULT_INVALID_ARGUMENT; | 652 return MOJO_RESULT_INVALID_ARGUMENT; |
| 652 | 653 |
| 653 return dispatcher->EndWriteData(num_bytes_written); | 654 return dispatcher->EndWriteData(num_bytes_written); |
| 654 } | 655 } |
| 655 | 656 |
| 656 MojoResult Core::ReadData(MojoHandle data_pipe_consumer_handle, | 657 MojoResult Core::ReadData(MojoHandle data_pipe_consumer_handle, |
| 657 void* elements, | 658 void* elements, |
| 658 uint32_t* num_bytes, | 659 uint32_t* num_bytes, |
| 659 MojoReadDataFlags flags) { | 660 MojoReadDataFlags flags) { |
| 660 RequestContext request_context; | 661 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 661 scoped_refptr<Dispatcher> dispatcher( | 662 scoped_refptr<Dispatcher> dispatcher( |
| 662 GetDispatcher(data_pipe_consumer_handle)); | 663 GetDispatcher(data_pipe_consumer_handle)); |
| 663 if (!dispatcher) | 664 if (!dispatcher) |
| 664 return MOJO_RESULT_INVALID_ARGUMENT; | 665 return MOJO_RESULT_INVALID_ARGUMENT; |
| 665 | 666 |
| 666 return dispatcher->ReadData(elements, num_bytes, flags); | 667 return dispatcher->ReadData(elements, num_bytes, flags); |
| 667 } | 668 } |
| 668 | 669 |
| 669 MojoResult Core::BeginReadData(MojoHandle data_pipe_consumer_handle, | 670 MojoResult Core::BeginReadData(MojoHandle data_pipe_consumer_handle, |
| 670 const void** buffer, | 671 const void** buffer, |
| 671 uint32_t* buffer_num_bytes, | 672 uint32_t* buffer_num_bytes, |
| 672 MojoReadDataFlags flags) { | 673 MojoReadDataFlags flags) { |
| 673 RequestContext request_context; | 674 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 674 scoped_refptr<Dispatcher> dispatcher( | 675 scoped_refptr<Dispatcher> dispatcher( |
| 675 GetDispatcher(data_pipe_consumer_handle)); | 676 GetDispatcher(data_pipe_consumer_handle)); |
| 676 if (!dispatcher) | 677 if (!dispatcher) |
| 677 return MOJO_RESULT_INVALID_ARGUMENT; | 678 return MOJO_RESULT_INVALID_ARGUMENT; |
| 678 | 679 |
| 679 return dispatcher->BeginReadData(buffer, buffer_num_bytes, flags); | 680 return dispatcher->BeginReadData(buffer, buffer_num_bytes, flags); |
| 680 } | 681 } |
| 681 | 682 |
| 682 MojoResult Core::EndReadData(MojoHandle data_pipe_consumer_handle, | 683 MojoResult Core::EndReadData(MojoHandle data_pipe_consumer_handle, |
| 683 uint32_t num_bytes_read) { | 684 uint32_t num_bytes_read) { |
| 684 RequestContext request_context; | 685 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 685 scoped_refptr<Dispatcher> dispatcher( | 686 scoped_refptr<Dispatcher> dispatcher( |
| 686 GetDispatcher(data_pipe_consumer_handle)); | 687 GetDispatcher(data_pipe_consumer_handle)); |
| 687 if (!dispatcher) | 688 if (!dispatcher) |
| 688 return MOJO_RESULT_INVALID_ARGUMENT; | 689 return MOJO_RESULT_INVALID_ARGUMENT; |
| 689 | 690 |
| 690 return dispatcher->EndReadData(num_bytes_read); | 691 return dispatcher->EndReadData(num_bytes_read); |
| 691 } | 692 } |
| 692 | 693 |
| 693 MojoResult Core::CreateSharedBuffer( | 694 MojoResult Core::CreateSharedBuffer( |
| 694 const MojoCreateSharedBufferOptions* options, | 695 const MojoCreateSharedBufferOptions* options, |
| 695 uint64_t num_bytes, | 696 uint64_t num_bytes, |
| 696 MojoHandle* shared_buffer_handle) { | 697 MojoHandle* shared_buffer_handle) { |
| 697 RequestContext request_context; | 698 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 698 MojoCreateSharedBufferOptions validated_options = {}; | 699 MojoCreateSharedBufferOptions validated_options = {}; |
| 699 MojoResult result = SharedBufferDispatcher::ValidateCreateOptions( | 700 MojoResult result = SharedBufferDispatcher::ValidateCreateOptions( |
| 700 options, &validated_options); | 701 options, &validated_options); |
| 701 if (result != MOJO_RESULT_OK) | 702 if (result != MOJO_RESULT_OK) |
| 702 return result; | 703 return result; |
| 703 | 704 |
| 704 scoped_refptr<SharedBufferDispatcher> dispatcher; | 705 scoped_refptr<SharedBufferDispatcher> dispatcher; |
| 705 result = SharedBufferDispatcher::Create( | 706 result = SharedBufferDispatcher::Create( |
| 706 validated_options, GetNodeController(), num_bytes, &dispatcher); | 707 validated_options, GetNodeController(), num_bytes, &dispatcher); |
| 707 if (result != MOJO_RESULT_OK) { | 708 if (result != MOJO_RESULT_OK) { |
| 708 DCHECK(!dispatcher); | 709 DCHECK(!dispatcher); |
| 709 return result; | 710 return result; |
| 710 } | 711 } |
| 711 | 712 |
| 712 *shared_buffer_handle = AddDispatcher(dispatcher); | 713 *shared_buffer_handle = AddDispatcher(dispatcher); |
| 713 if (*shared_buffer_handle == MOJO_HANDLE_INVALID) { | 714 if (*shared_buffer_handle == MOJO_HANDLE_INVALID) { |
| 714 LOG(ERROR) << "Handle table full"; | 715 LOG(ERROR) << "Handle table full"; |
| 715 dispatcher->Close(); | 716 dispatcher->Close(); |
| 716 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 717 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 717 } | 718 } |
| 718 | 719 |
| 719 return MOJO_RESULT_OK; | 720 return MOJO_RESULT_OK; |
| 720 } | 721 } |
| 721 | 722 |
| 722 MojoResult Core::DuplicateBufferHandle( | 723 MojoResult Core::DuplicateBufferHandle( |
| 723 MojoHandle buffer_handle, | 724 MojoHandle buffer_handle, |
| 724 const MojoDuplicateBufferHandleOptions* options, | 725 const MojoDuplicateBufferHandleOptions* options, |
| 725 MojoHandle* new_buffer_handle) { | 726 MojoHandle* new_buffer_handle) { |
| 726 RequestContext request_context; | 727 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 727 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); | 728 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); |
| 728 if (!dispatcher) | 729 if (!dispatcher) |
| 729 return MOJO_RESULT_INVALID_ARGUMENT; | 730 return MOJO_RESULT_INVALID_ARGUMENT; |
| 730 | 731 |
| 731 // Don't verify |options| here; that's the dispatcher's job. | 732 // Don't verify |options| here; that's the dispatcher's job. |
| 732 scoped_refptr<Dispatcher> new_dispatcher; | 733 scoped_refptr<Dispatcher> new_dispatcher; |
| 733 MojoResult result = | 734 MojoResult result = |
| 734 dispatcher->DuplicateBufferHandle(options, &new_dispatcher); | 735 dispatcher->DuplicateBufferHandle(options, &new_dispatcher); |
| 735 if (result != MOJO_RESULT_OK) | 736 if (result != MOJO_RESULT_OK) |
| 736 return result; | 737 return result; |
| 737 | 738 |
| 738 *new_buffer_handle = AddDispatcher(new_dispatcher); | 739 *new_buffer_handle = AddDispatcher(new_dispatcher); |
| 739 if (*new_buffer_handle == MOJO_HANDLE_INVALID) { | 740 if (*new_buffer_handle == MOJO_HANDLE_INVALID) { |
| 740 LOG(ERROR) << "Handle table full"; | 741 LOG(ERROR) << "Handle table full"; |
| 741 dispatcher->Close(); | 742 dispatcher->Close(); |
| 742 return MOJO_RESULT_RESOURCE_EXHAUSTED; | 743 return MOJO_RESULT_RESOURCE_EXHAUSTED; |
| 743 } | 744 } |
| 744 | 745 |
| 745 return MOJO_RESULT_OK; | 746 return MOJO_RESULT_OK; |
| 746 } | 747 } |
| 747 | 748 |
| 748 MojoResult Core::MapBuffer(MojoHandle buffer_handle, | 749 MojoResult Core::MapBuffer(MojoHandle buffer_handle, |
| 749 uint64_t offset, | 750 uint64_t offset, |
| 750 uint64_t num_bytes, | 751 uint64_t num_bytes, |
| 751 void** buffer, | 752 void** buffer, |
| 752 MojoMapBufferFlags flags) { | 753 MojoMapBufferFlags flags) { |
| 753 RequestContext request_context; | 754 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 754 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); | 755 scoped_refptr<Dispatcher> dispatcher(GetDispatcher(buffer_handle)); |
| 755 if (!dispatcher) | 756 if (!dispatcher) |
| 756 return MOJO_RESULT_INVALID_ARGUMENT; | 757 return MOJO_RESULT_INVALID_ARGUMENT; |
| 757 | 758 |
| 758 scoped_ptr<PlatformSharedBufferMapping> mapping; | 759 scoped_ptr<PlatformSharedBufferMapping> mapping; |
| 759 MojoResult result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping); | 760 MojoResult result = dispatcher->MapBuffer(offset, num_bytes, flags, &mapping); |
| 760 if (result != MOJO_RESULT_OK) | 761 if (result != MOJO_RESULT_OK) |
| 761 return result; | 762 return result; |
| 762 | 763 |
| 763 DCHECK(mapping); | 764 DCHECK(mapping); |
| 764 void* address = mapping->GetBase(); | 765 void* address = mapping->GetBase(); |
| 765 { | 766 { |
| 766 base::AutoLock locker(mapping_table_lock_); | 767 base::AutoLock locker(mapping_table_lock_); |
| 767 result = mapping_table_.AddMapping(std::move(mapping)); | 768 result = mapping_table_.AddMapping(std::move(mapping)); |
| 768 } | 769 } |
| 769 if (result != MOJO_RESULT_OK) | 770 if (result != MOJO_RESULT_OK) |
| 770 return result; | 771 return result; |
| 771 | 772 |
| 772 *buffer = address; | 773 *buffer = address; |
| 773 return MOJO_RESULT_OK; | 774 return MOJO_RESULT_OK; |
| 774 } | 775 } |
| 775 | 776 |
| 776 MojoResult Core::UnmapBuffer(void* buffer) { | 777 MojoResult Core::UnmapBuffer(void* buffer) { |
| 777 RequestContext request_context; | 778 RequestContext request_context(RequestContext::Source::LOCAL_API_CALL); |
| 778 base::AutoLock lock(mapping_table_lock_); | 779 base::AutoLock lock(mapping_table_lock_); |
| 779 return mapping_table_.RemoveMapping(buffer); | 780 return mapping_table_.RemoveMapping(buffer); |
| 780 } | 781 } |
| 781 | 782 |
| 782 void Core::GetActiveHandlesForTest(std::vector<MojoHandle>* handles) { | 783 void Core::GetActiveHandlesForTest(std::vector<MojoHandle>* handles) { |
| 783 base::AutoLock lock(handles_lock_); | 784 base::AutoLock lock(handles_lock_); |
| 784 handles_.GetActiveHandlesForTest(handles); | 785 handles_.GetActiveHandlesForTest(handles); |
| 785 } | 786 } |
| 786 | 787 |
| 787 MojoResult Core::WaitManyInternal(const MojoHandle* handles, | 788 MojoResult Core::WaitManyInternal(const MojoHandle* handles, |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 857 scoped_ptr<NodeController> node_controller) { | 858 scoped_ptr<NodeController> node_controller) { |
| 858 // It's OK to leak this reference. At this point we know the IO loop is still | 859 // It's OK to leak this reference. At this point we know the IO loop is still |
| 859 // running, and we know the NodeController will observe its eventual | 860 // running, and we know the NodeController will observe its eventual |
| 860 // destruction. This tells the NodeController to delete itself when that | 861 // destruction. This tells the NodeController to delete itself when that |
| 861 // happens. | 862 // happens. |
| 862 node_controller.release()->DestroyOnIOThreadShutdown(); | 863 node_controller.release()->DestroyOnIOThreadShutdown(); |
| 863 } | 864 } |
| 864 | 865 |
| 865 } // namespace edk | 866 } // namespace edk |
| 866 } // namespace mojo | 867 } // namespace mojo |
| OLD | NEW |