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 "ipc/ipc_channel_win.h" | 5 #include "ipc/ipc_channel_win.h" |
6 | 6 |
7 #include <windows.h> | 7 #include <windows.h> |
8 | 8 |
9 #include "base/auto_reset.h" | 9 #include "base/auto_reset.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 // form OnIOCompleted(). | 67 // form OnIOCompleted(). |
68 if (pipe_.IsValid()) | 68 if (pipe_.IsValid()) |
69 pipe_.Close(); | 69 pipe_.Close(); |
70 | 70 |
71 // Make sure all IO has completed. | 71 // Make sure all IO has completed. |
72 while (input_state_.is_pending || output_state_.is_pending) { | 72 while (input_state_.is_pending || output_state_.is_pending) { |
73 base::MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this); | 73 base::MessageLoopForIO::current()->WaitForIOCompletion(INFINITE, this); |
74 } | 74 } |
75 | 75 |
76 while (!output_queue_.empty()) { | 76 while (!output_queue_.empty()) { |
77 Message* m = output_queue_.front(); | 77 OutputElement* element = output_queue_.front(); |
78 output_queue_.pop(); | 78 output_queue_.pop(); |
79 delete m; | 79 delete element; |
80 } | 80 } |
81 } | 81 } |
82 | 82 |
83 bool ChannelWin::Send(Message* message) { | 83 bool ChannelWin::Send(Message* message) { |
84 DCHECK(thread_check_->CalledOnValidThread()); | 84 DCHECK(thread_check_->CalledOnValidThread()); |
85 DVLOG(2) << "sending message @" << message << " on channel @" << this | 85 DVLOG(2) << "sending message @" << message << " on channel @" << this |
86 << " with type " << message->type() | 86 << " with type " << message->type() |
87 << " (" << output_queue_.size() << " in queue)"; | 87 << " (" << output_queue_.size() << " in queue)"; |
88 | 88 |
89 if (!prelim_queue_.empty()) { | 89 if (!prelim_queue_.empty()) { |
(...skipping 29 matching lines...) Expand all Loading... |
119 #ifdef IPC_MESSAGE_LOG_ENABLED | 119 #ifdef IPC_MESSAGE_LOG_ENABLED |
120 Logging::GetInstance()->OnSendMessage(message, ""); | 120 Logging::GetInstance()->OnSendMessage(message, ""); |
121 #endif | 121 #endif |
122 | 122 |
123 TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"), | 123 TRACE_EVENT_WITH_FLOW0(TRACE_DISABLED_BY_DEFAULT("ipc.flow"), |
124 "ChannelWin::ProcessMessageForDelivery", | 124 "ChannelWin::ProcessMessageForDelivery", |
125 message->flags(), | 125 message->flags(), |
126 TRACE_EVENT_FLAG_FLOW_OUT); | 126 TRACE_EVENT_FLAG_FLOW_OUT); |
127 | 127 |
128 // |output_queue_| takes ownership of |message|. | 128 // |output_queue_| takes ownership of |message|. |
129 output_queue_.push(message); | 129 OutputElement* element = new OutputElement(message); |
| 130 output_queue_.push(element); |
| 131 |
| 132 // TODO(erikchen): Serialize the brokerable attachments and add them to the |
| 133 // output_queue_. http://crbug.com/493414. |
| 134 |
130 // ensure waiting to write | 135 // ensure waiting to write |
131 if (!waiting_connect_) { | 136 if (!waiting_connect_) { |
132 if (!output_state_.is_pending) { | 137 if (!output_state_.is_pending) { |
133 if (!ProcessOutgoingMessages(NULL, 0)) | 138 if (!ProcessOutgoingMessages(NULL, 0)) |
134 return false; | 139 return false; |
135 } | 140 } |
136 } | 141 } |
137 | 142 |
138 return true; | 143 return true; |
139 } | 144 } |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 | 361 |
357 // Don't send the secret to the untrusted process, and don't send a secret | 362 // Don't send the secret to the untrusted process, and don't send a secret |
358 // if the value is zero (for IPC backwards compatability). | 363 // if the value is zero (for IPC backwards compatability). |
359 int32 secret = validate_client_ ? 0 : client_secret_; | 364 int32 secret = validate_client_ ? 0 : client_secret_; |
360 if (!m->WriteInt(GetCurrentProcessId()) || | 365 if (!m->WriteInt(GetCurrentProcessId()) || |
361 (secret && !m->WriteUInt32(secret))) { | 366 (secret && !m->WriteUInt32(secret))) { |
362 pipe_.Close(); | 367 pipe_.Close(); |
363 return false; | 368 return false; |
364 } | 369 } |
365 | 370 |
366 output_queue_.push(m.release()); | 371 OutputElement* element = new OutputElement(m.release()); |
| 372 output_queue_.push(element); |
367 return true; | 373 return true; |
368 } | 374 } |
369 | 375 |
370 bool ChannelWin::Connect() { | 376 bool ChannelWin::Connect() { |
371 DLOG_IF(WARNING, thread_check_.get()) << "Connect called more than once"; | 377 DLOG_IF(WARNING, thread_check_.get()) << "Connect called more than once"; |
372 | 378 |
373 if (!thread_check_.get()) | 379 if (!thread_check_.get()) |
374 thread_check_.reset(new base::ThreadChecker()); | 380 thread_check_.reset(new base::ThreadChecker()); |
375 | 381 |
376 if (!pipe_.IsValid()) | 382 if (!pipe_.IsValid()) |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
446 if (output_state_.is_pending) { | 452 if (output_state_.is_pending) { |
447 DCHECK(context); | 453 DCHECK(context); |
448 output_state_.is_pending = false; | 454 output_state_.is_pending = false; |
449 if (!context || bytes_written == 0) { | 455 if (!context || bytes_written == 0) { |
450 DWORD err = GetLastError(); | 456 DWORD err = GetLastError(); |
451 LOG(ERROR) << "pipe error: " << err; | 457 LOG(ERROR) << "pipe error: " << err; |
452 return false; | 458 return false; |
453 } | 459 } |
454 // Message was sent. | 460 // Message was sent. |
455 CHECK(!output_queue_.empty()); | 461 CHECK(!output_queue_.empty()); |
456 Message* m = output_queue_.front(); | 462 OutputElement* element = output_queue_.front(); |
457 output_queue_.pop(); | 463 output_queue_.pop(); |
458 delete m; | 464 delete element; |
459 } | 465 } |
460 | 466 |
461 if (output_queue_.empty()) | 467 if (output_queue_.empty()) |
462 return true; | 468 return true; |
463 | 469 |
464 if (!pipe_.IsValid()) | 470 if (!pipe_.IsValid()) |
465 return false; | 471 return false; |
466 | 472 |
467 // Write to pipe... | 473 // Write to pipe... |
468 Message* m = output_queue_.front(); | 474 OutputElement* element = output_queue_.front(); |
469 DCHECK(m->size() <= INT_MAX); | 475 DCHECK(element->size() <= INT_MAX); |
470 BOOL ok = WriteFile(pipe_.Get(), | 476 BOOL ok = WriteFile(pipe_.Get(), |
471 m->data(), | 477 element->data(), |
472 static_cast<uint32>(m->size()), | 478 static_cast<uint32>(element->size()), |
473 NULL, | 479 NULL, |
474 &output_state_.context.overlapped); | 480 &output_state_.context.overlapped); |
475 if (!ok) { | 481 if (!ok) { |
476 DWORD write_error = GetLastError(); | 482 DWORD write_error = GetLastError(); |
477 if (write_error == ERROR_IO_PENDING) { | 483 if (write_error == ERROR_IO_PENDING) { |
478 output_state_.is_pending = true; | 484 output_state_.is_pending = true; |
479 | 485 |
480 DVLOG(2) << "sent pending message @" << m << " on channel @" << this | 486 const Message* m = element->get_message(); |
481 << " with type " << m->type(); | 487 if (m) { |
| 488 DVLOG(2) << "sent pending message @" << m << " on channel @" << this |
| 489 << " with type " << m->type(); |
| 490 } |
482 | 491 |
483 return true; | 492 return true; |
484 } | 493 } |
485 LOG(ERROR) << "pipe error: " << write_error; | 494 LOG(ERROR) << "pipe error: " << write_error; |
486 return false; | 495 return false; |
487 } | 496 } |
488 | 497 |
489 DVLOG(2) << "sent message @" << m << " on channel @" << this | 498 const Message* m = element->get_message(); |
490 << " with type " << m->type(); | 499 if (m) { |
| 500 DVLOG(2) << "sent message @" << m << " on channel @" << this |
| 501 << " with type " << m->type(); |
| 502 } |
491 | 503 |
492 output_state_.is_pending = true; | 504 output_state_.is_pending = true; |
493 return true; | 505 return true; |
494 } | 506 } |
495 | 507 |
496 void ChannelWin::OnIOCompleted( | 508 void ChannelWin::OnIOCompleted( |
497 base::MessageLoopForIO::IOContext* context, | 509 base::MessageLoopForIO::IOContext* context, |
498 DWORD bytes_transfered, | 510 DWORD bytes_transfered, |
499 DWORD error) { | 511 DWORD error) { |
500 bool ok = true; | 512 bool ok = true; |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 int secret; | 587 int secret; |
576 do { // Guarantee we get a non-zero value. | 588 do { // Guarantee we get a non-zero value. |
577 secret = base::RandInt(0, std::numeric_limits<int>::max()); | 589 secret = base::RandInt(0, std::numeric_limits<int>::max()); |
578 } while (secret == 0); | 590 } while (secret == 0); |
579 | 591 |
580 id.append(GenerateUniqueRandomChannelID()); | 592 id.append(GenerateUniqueRandomChannelID()); |
581 return id.append(base::StringPrintf("\\%d", secret)); | 593 return id.append(base::StringPrintf("\\%d", secret)); |
582 } | 594 } |
583 | 595 |
584 } // namespace IPC | 596 } // namespace IPC |
OLD | NEW |