Chromium Code Reviews| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 ChannelWin::State::~State() { | 52 ChannelWin::State::~State() { |
| 53 COMPILE_ASSERT(!offsetof(ChannelWin::State, context), | 53 COMPILE_ASSERT(!offsetof(ChannelWin::State, context), |
| 54 starts_with_io_context); | 54 starts_with_io_context); |
| 55 } | 55 } |
| 56 | 56 |
| 57 ChannelWin::ChannelWin(const IPC::ChannelHandle &channel_handle, | 57 ChannelWin::ChannelWin(const IPC::ChannelHandle &channel_handle, |
| 58 Mode mode, Listener* listener) | 58 Mode mode, Listener* listener) |
| 59 : ChannelReader(listener), | 59 : ChannelReader(listener), |
| 60 input_state_(this), | 60 input_state_(this), |
| 61 output_state_(this), | 61 output_state_(this), |
| 62 pipe_(INVALID_HANDLE_VALUE), | |
| 63 peer_pid_(base::kNullProcessId), | 62 peer_pid_(base::kNullProcessId), |
| 64 waiting_connect_(mode & MODE_SERVER_FLAG), | 63 waiting_connect_(mode & MODE_SERVER_FLAG), |
| 65 processing_incoming_(false), | 64 processing_incoming_(false), |
| 66 validate_client_(false), | 65 validate_client_(false), |
| 67 writing_(false), | 66 writing_(false), |
| 68 debug_flags_(0), | 67 debug_flags_(0), |
| 69 write_error_(0), | 68 write_error_(0), |
| 70 last_write_error_(0), | 69 last_write_error_(0), |
| 71 write_size_(0), | 70 write_size_(0), |
| 72 client_secret_(0), | 71 client_secret_(0), |
| 73 weak_factory_(this) { | 72 weak_factory_(this) { |
| 74 CreatePipe(channel_handle, mode); | 73 CreatePipe(channel_handle, mode); |
| 75 } | 74 } |
| 76 | 75 |
| 77 ChannelWin::~ChannelWin() { | 76 ChannelWin::~ChannelWin() { |
| 78 Close(); | 77 Close(); |
| 79 } | 78 } |
| 80 | 79 |
| 81 void ChannelWin::Close() { | 80 void ChannelWin::Close() { |
| 82 if (thread_check_.get()) { | 81 if (thread_check_.get()) { |
| 83 DCHECK(thread_check_->CalledOnValidThread()); | 82 DCHECK(thread_check_->CalledOnValidThread()); |
| 84 } | 83 } |
| 85 debug_flags_ |= CLOSED; | 84 debug_flags_ |= CLOSED; |
| 86 | 85 |
| 87 if (input_state_.is_pending || output_state_.is_pending) | 86 if (input_state_.is_pending || output_state_.is_pending) |
| 88 CancelIo(pipe_); | 87 CancelIo(pipe_.Get()); |
| 89 | 88 |
| 90 // Closing the handle at this point prevents us from issuing more requests | 89 // Closing the handle at this point prevents us from issuing more requests |
| 91 // form OnIOCompleted(). | 90 // form OnIOCompleted(). |
| 92 if (pipe_ != INVALID_HANDLE_VALUE) { | 91 if (pipe_.IsValid()) |
| 93 CloseHandle(pipe_); | 92 pipe_.Close(); |
| 94 pipe_ = INVALID_HANDLE_VALUE; | |
| 95 } | |
| 96 | 93 |
| 97 if (input_state_.is_pending) | 94 if (input_state_.is_pending) |
| 98 debug_flags_ |= WAIT_FOR_READ; | 95 debug_flags_ |= WAIT_FOR_READ; |
| 99 | 96 |
| 100 if (output_state_.is_pending) | 97 if (output_state_.is_pending) |
| 101 debug_flags_ |= WAIT_FOR_WRITE; | 98 debug_flags_ |= WAIT_FOR_WRITE; |
| 102 | 99 |
| 103 // Make sure all IO has completed. | 100 // Make sure all IO has completed. |
| 104 base::Time start = base::Time::Now(); | 101 base::Time start = base::Time::Now(); |
| 105 while (input_state_.is_pending || output_state_.is_pending) { | 102 while (input_state_.is_pending || output_state_.is_pending) { |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 136 return true; | 133 return true; |
| 137 } | 134 } |
| 138 | 135 |
| 139 base::ProcessId ChannelWin::GetPeerPID() const { | 136 base::ProcessId ChannelWin::GetPeerPID() const { |
| 140 return peer_pid_; | 137 return peer_pid_; |
| 141 } | 138 } |
| 142 | 139 |
| 143 base::ProcessId ChannelWin::GetSelfPID() const { | 140 base::ProcessId ChannelWin::GetSelfPID() const { |
| 144 return GetCurrentProcessId(); | 141 return GetCurrentProcessId(); |
| 145 } | 142 } |
| 146 | 143 |
|
cpu_(ooo_6.6-7.5)
2014/09/25 23:07:27
morita has a lgtmed change here.
rvargas (doing something else)
2014/09/25 23:26:20
Yes, I know. This part is just for completeness.
| |
| 147 ChannelHandle ChannelWin::TakePipeHandle() { | 144 ChannelHandle ChannelWin::TakePipeHandle() { |
| 148 ChannelHandle handle = ChannelHandle(pipe_); | 145 return ChannelHandle(pipe_.Take()); |
| 149 pipe_ = INVALID_HANDLE_VALUE; | |
| 150 return handle; | |
| 151 } | 146 } |
| 152 | 147 |
| 153 // static | 148 // static |
| 154 bool ChannelWin::IsNamedServerInitialized( | 149 bool ChannelWin::IsNamedServerInitialized( |
| 155 const std::string& channel_id) { | 150 const std::string& channel_id) { |
| 156 if (WaitNamedPipe(PipeName(channel_id, NULL).c_str(), 1)) | 151 if (WaitNamedPipe(PipeName(channel_id, NULL).c_str(), 1)) |
| 157 return true; | 152 return true; |
| 158 // If ERROR_SEM_TIMEOUT occurred, the pipe exists but is handling another | 153 // If ERROR_SEM_TIMEOUT occurred, the pipe exists but is handling another |
| 159 // connection. | 154 // connection. |
| 160 return GetLastError() == ERROR_SEM_TIMEOUT; | 155 return GetLastError() == ERROR_SEM_TIMEOUT; |
| 161 } | 156 } |
| 162 | 157 |
| 163 ChannelWin::ReadState ChannelWin::ReadData( | 158 ChannelWin::ReadState ChannelWin::ReadData( |
| 164 char* buffer, | 159 char* buffer, |
| 165 int buffer_len, | 160 int buffer_len, |
| 166 int* /* bytes_read */) { | 161 int* /* bytes_read */) { |
| 167 if (INVALID_HANDLE_VALUE == pipe_) | 162 if (!pipe_.IsValid()) |
| 168 return READ_FAILED; | 163 return READ_FAILED; |
| 169 | 164 |
| 170 debug_flags_ |= READ_MSG; | 165 debug_flags_ |= READ_MSG; |
| 171 DWORD bytes_read = 0; | 166 DWORD bytes_read = 0; |
| 172 BOOL ok = ReadFile(pipe_, buffer, buffer_len, | 167 BOOL ok = ReadFile(pipe_.Get(), buffer, buffer_len, |
| 173 &bytes_read, &input_state_.context.overlapped); | 168 &bytes_read, &input_state_.context.overlapped); |
| 174 if (!ok) { | 169 if (!ok) { |
| 175 DWORD err = GetLastError(); | 170 DWORD err = GetLastError(); |
| 176 if (err == ERROR_IO_PENDING) { | 171 if (err == ERROR_IO_PENDING) { |
| 177 input_state_.is_pending = true; | 172 input_state_.is_pending = true; |
| 178 return READ_PENDING; | 173 return READ_PENDING; |
| 179 } | 174 } |
| 180 LOG(ERROR) << "pipe error: " << err; | 175 LOG(ERROR) << "pipe error: " << err; |
| 181 return READ_FAILED; | 176 return READ_FAILED; |
| 182 } | 177 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 243 return base::ASCIIToWide(name.append(channel_id.substr(0, index - 1))); | 238 return base::ASCIIToWide(name.append(channel_id.substr(0, index - 1))); |
| 244 } | 239 } |
| 245 | 240 |
| 246 // This case is here to support predictable named pipes in tests. | 241 // This case is here to support predictable named pipes in tests. |
| 247 if (secret) | 242 if (secret) |
| 248 *secret = 0; | 243 *secret = 0; |
| 249 return base::ASCIIToWide(name.append(channel_id)); | 244 return base::ASCIIToWide(name.append(channel_id)); |
| 250 } | 245 } |
| 251 | 246 |
| 252 bool ChannelWin::CreatePipe(const IPC::ChannelHandle &channel_handle, | 247 bool ChannelWin::CreatePipe(const IPC::ChannelHandle &channel_handle, |
| 253 Mode mode) { | 248 Mode mode) { |
| 254 DCHECK_EQ(INVALID_HANDLE_VALUE, pipe_); | 249 DCHECK(!pipe_.IsValid()); |
| 255 base::string16 pipe_name; | 250 base::string16 pipe_name; |
| 256 // If we already have a valid pipe for channel just copy it. | 251 // If we already have a valid pipe for channel just copy it. |
| 257 if (channel_handle.pipe.handle) { | 252 if (channel_handle.pipe.handle) { |
| 253 // TODO(rvargas) crbug.com/415294: ChannelHandle should either go away in | |
| 254 // favor of two independent entities (name/file), or it should be a move- | |
| 255 // only type with a base::File member. In any case, this code should not | |
|
cpu_(ooo_6.6-7.5)
2014/09/25 23:07:27
is this justin thing I was talking about?
rvargas (doing something else)
2014/09/25 23:26:20
Nope. Amit added this long time ago... it's not us
| |
| 256 // call DuplicateHandle. | |
| 258 DCHECK(channel_handle.name.empty()); | 257 DCHECK(channel_handle.name.empty()); |
| 259 pipe_name = L"Not Available"; // Just used for LOG | 258 pipe_name = L"Not Available"; // Just used for LOG |
| 260 // Check that the given pipe confirms to the specified mode. We can | 259 // Check that the given pipe confirms to the specified mode. We can |
| 261 // only check for PIPE_TYPE_MESSAGE & PIPE_SERVER_END flags since the | 260 // only check for PIPE_TYPE_MESSAGE & PIPE_SERVER_END flags since the |
| 262 // other flags (PIPE_TYPE_BYTE, and PIPE_CLIENT_END) are defined as 0. | 261 // other flags (PIPE_TYPE_BYTE, and PIPE_CLIENT_END) are defined as 0. |
| 263 DWORD flags = 0; | 262 DWORD flags = 0; |
| 264 GetNamedPipeInfo(channel_handle.pipe.handle, &flags, NULL, NULL, NULL); | 263 GetNamedPipeInfo(channel_handle.pipe.handle, &flags, NULL, NULL, NULL); |
| 265 DCHECK(!(flags & PIPE_TYPE_MESSAGE)); | 264 DCHECK(!(flags & PIPE_TYPE_MESSAGE)); |
| 266 if (((mode & MODE_SERVER_FLAG) && !(flags & PIPE_SERVER_END)) || | 265 if (((mode & MODE_SERVER_FLAG) && !(flags & PIPE_SERVER_END)) || |
| 267 ((mode & MODE_CLIENT_FLAG) && (flags & PIPE_SERVER_END))) { | 266 ((mode & MODE_CLIENT_FLAG) && (flags & PIPE_SERVER_END))) { |
| 268 LOG(WARNING) << "Inconsistent open mode. Mode :" << mode; | 267 LOG(WARNING) << "Inconsistent open mode. Mode :" << mode; |
| 269 return false; | 268 return false; |
| 270 } | 269 } |
| 270 HANDLE local_handle; | |
| 271 if (!DuplicateHandle(GetCurrentProcess(), | 271 if (!DuplicateHandle(GetCurrentProcess(), |
| 272 channel_handle.pipe.handle, | 272 channel_handle.pipe.handle, |
| 273 GetCurrentProcess(), | 273 GetCurrentProcess(), |
| 274 &pipe_, | 274 &local_handle, |
| 275 0, | 275 0, |
| 276 FALSE, | 276 FALSE, |
| 277 DUPLICATE_SAME_ACCESS)) { | 277 DUPLICATE_SAME_ACCESS)) { |
| 278 LOG(WARNING) << "DuplicateHandle failed. Error :" << GetLastError(); | 278 LOG(WARNING) << "DuplicateHandle failed. Error :" << GetLastError(); |
| 279 return false; | 279 return false; |
| 280 } | 280 } |
| 281 pipe_.Set(local_handle); | |
| 281 } else if (mode & MODE_SERVER_FLAG) { | 282 } else if (mode & MODE_SERVER_FLAG) { |
| 282 DCHECK(!channel_handle.pipe.handle); | 283 DCHECK(!channel_handle.pipe.handle); |
| 283 const DWORD open_mode = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | | 284 const DWORD open_mode = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | |
| 284 FILE_FLAG_FIRST_PIPE_INSTANCE; | 285 FILE_FLAG_FIRST_PIPE_INSTANCE; |
| 285 pipe_name = PipeName(channel_handle.name, &client_secret_); | 286 pipe_name = PipeName(channel_handle.name, &client_secret_); |
| 286 validate_client_ = !!client_secret_; | 287 validate_client_ = !!client_secret_; |
| 287 pipe_ = CreateNamedPipeW(pipe_name.c_str(), | 288 pipe_.Set(CreateNamedPipeW(pipe_name.c_str(), |
| 288 open_mode, | 289 open_mode, |
| 289 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, | 290 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, |
| 290 1, | 291 1, |
| 291 Channel::kReadBufferSize, | 292 Channel::kReadBufferSize, |
| 292 Channel::kReadBufferSize, | 293 Channel::kReadBufferSize, |
| 293 5000, | 294 5000, |
| 294 NULL); | 295 NULL)); |
| 295 } else if (mode & MODE_CLIENT_FLAG) { | 296 } else if (mode & MODE_CLIENT_FLAG) { |
| 296 DCHECK(!channel_handle.pipe.handle); | 297 DCHECK(!channel_handle.pipe.handle); |
| 297 pipe_name = PipeName(channel_handle.name, &client_secret_); | 298 pipe_name = PipeName(channel_handle.name, &client_secret_); |
| 298 pipe_ = CreateFileW(pipe_name.c_str(), | 299 pipe_.Set(CreateFileW(pipe_name.c_str(), |
| 299 GENERIC_READ | GENERIC_WRITE, | 300 GENERIC_READ | GENERIC_WRITE, |
| 300 0, | 301 0, |
| 301 NULL, | 302 NULL, |
| 302 OPEN_EXISTING, | 303 OPEN_EXISTING, |
| 303 SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION | | 304 SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION | |
| 304 FILE_FLAG_OVERLAPPED, | 305 FILE_FLAG_OVERLAPPED, |
| 305 NULL); | 306 NULL)); |
| 306 } else { | 307 } else { |
| 307 NOTREACHED(); | 308 NOTREACHED(); |
| 308 } | 309 } |
| 309 | 310 |
| 310 if (pipe_ == INVALID_HANDLE_VALUE) { | 311 if (!pipe_.IsValid()) { |
| 311 // If this process is being closed, the pipe may be gone already. | 312 // If this process is being closed, the pipe may be gone already. |
| 312 PLOG(WARNING) << "Unable to create pipe \"" << pipe_name << "\" in " | 313 PLOG(WARNING) << "Unable to create pipe \"" << pipe_name << "\" in " |
| 313 << (mode & MODE_SERVER_FLAG ? "server" : "client") << " mode"; | 314 << (mode & MODE_SERVER_FLAG ? "server" : "client") << " mode"; |
| 314 return false; | 315 return false; |
| 315 } | 316 } |
| 316 | 317 |
| 317 // Create the Hello message to be sent when Connect is called | 318 // Create the Hello message to be sent when Connect is called |
| 318 scoped_ptr<Message> m(new Message(MSG_ROUTING_NONE, | 319 scoped_ptr<Message> m(new Message(MSG_ROUTING_NONE, |
| 319 HELLO_MESSAGE_TYPE, | 320 HELLO_MESSAGE_TYPE, |
| 320 IPC::Message::PRIORITY_NORMAL)); | 321 IPC::Message::PRIORITY_NORMAL)); |
| 321 | 322 |
| 322 // Don't send the secret to the untrusted process, and don't send a secret | 323 // Don't send the secret to the untrusted process, and don't send a secret |
| 323 // if the value is zero (for IPC backwards compatability). | 324 // if the value is zero (for IPC backwards compatability). |
| 324 int32 secret = validate_client_ ? 0 : client_secret_; | 325 int32 secret = validate_client_ ? 0 : client_secret_; |
| 325 if (!m->WriteInt(GetCurrentProcessId()) || | 326 if (!m->WriteInt(GetCurrentProcessId()) || |
| 326 (secret && !m->WriteUInt32(secret))) { | 327 (secret && !m->WriteUInt32(secret))) { |
| 327 CloseHandle(pipe_); | 328 pipe_.Close(); |
| 328 pipe_ = INVALID_HANDLE_VALUE; | |
| 329 return false; | 329 return false; |
| 330 } | 330 } |
| 331 | 331 |
| 332 debug_flags_ |= INIT_DONE; | 332 debug_flags_ |= INIT_DONE; |
| 333 | 333 |
| 334 output_queue_.push(m.release()); | 334 output_queue_.push(m.release()); |
| 335 return true; | 335 return true; |
| 336 } | 336 } |
| 337 | 337 |
| 338 bool ChannelWin::Connect() { | 338 bool ChannelWin::Connect() { |
| 339 DLOG_IF(WARNING, thread_check_.get()) << "Connect called more than once"; | 339 DLOG_IF(WARNING, thread_check_.get()) << "Connect called more than once"; |
| 340 | 340 |
| 341 if (!thread_check_.get()) | 341 if (!thread_check_.get()) |
| 342 thread_check_.reset(new base::ThreadChecker()); | 342 thread_check_.reset(new base::ThreadChecker()); |
| 343 | 343 |
| 344 if (pipe_ == INVALID_HANDLE_VALUE) | 344 if (!pipe_.IsValid()) |
| 345 return false; | 345 return false; |
| 346 | 346 |
| 347 base::MessageLoopForIO::current()->RegisterIOHandler(pipe_, this); | 347 base::MessageLoopForIO::current()->RegisterIOHandler(pipe_.Get(), this); |
| 348 | 348 |
| 349 // Check to see if there is a client connected to our pipe... | 349 // Check to see if there is a client connected to our pipe... |
| 350 if (waiting_connect_) | 350 if (waiting_connect_) |
| 351 ProcessConnection(); | 351 ProcessConnection(); |
| 352 | 352 |
| 353 if (!input_state_.is_pending) { | 353 if (!input_state_.is_pending) { |
| 354 // Complete setup asynchronously. By not setting input_state_.is_pending | 354 // Complete setup asynchronously. By not setting input_state_.is_pending |
| 355 // to true, we indicate to OnIOCompleted that this is the special | 355 // to true, we indicate to OnIOCompleted that this is the special |
| 356 // initialization signal. | 356 // initialization signal. |
| 357 base::MessageLoopForIO::current()->PostTask( | 357 base::MessageLoopForIO::current()->PostTask( |
| 358 FROM_HERE, | 358 FROM_HERE, |
| 359 base::Bind(&ChannelWin::OnIOCompleted, | 359 base::Bind(&ChannelWin::OnIOCompleted, |
| 360 weak_factory_.GetWeakPtr(), | 360 weak_factory_.GetWeakPtr(), |
| 361 &input_state_.context, | 361 &input_state_.context, |
| 362 0, | 362 0, |
| 363 0)); | 363 0)); |
| 364 } | 364 } |
| 365 | 365 |
| 366 if (!waiting_connect_) | 366 if (!waiting_connect_) |
| 367 ProcessOutgoingMessages(NULL, 0); | 367 ProcessOutgoingMessages(NULL, 0); |
| 368 return true; | 368 return true; |
| 369 } | 369 } |
| 370 | 370 |
| 371 bool ChannelWin::ProcessConnection() { | 371 bool ChannelWin::ProcessConnection() { |
| 372 DCHECK(thread_check_->CalledOnValidThread()); | 372 DCHECK(thread_check_->CalledOnValidThread()); |
| 373 if (input_state_.is_pending) | 373 if (input_state_.is_pending) |
| 374 input_state_.is_pending = false; | 374 input_state_.is_pending = false; |
| 375 | 375 |
| 376 // Do we have a client connected to our pipe? | 376 // Do we have a client connected to our pipe? |
| 377 if (INVALID_HANDLE_VALUE == pipe_) | 377 if (!pipe_.IsValid()) |
| 378 return false; | 378 return false; |
| 379 | 379 |
| 380 BOOL ok = ConnectNamedPipe(pipe_, &input_state_.context.overlapped); | 380 BOOL ok = ConnectNamedPipe(pipe_.Get(), &input_state_.context.overlapped); |
| 381 debug_flags_ |= CALLED_CONNECT; | 381 debug_flags_ |= CALLED_CONNECT; |
| 382 | 382 |
| 383 DWORD err = GetLastError(); | 383 DWORD err = GetLastError(); |
| 384 if (ok) { | 384 if (ok) { |
| 385 // Uhm, the API documentation says that this function should never | 385 // Uhm, the API documentation says that this function should never |
| 386 // return success when used in overlapped mode. | 386 // return success when used in overlapped mode. |
| 387 NOTREACHED(); | 387 NOTREACHED(); |
| 388 return false; | 388 return false; |
| 389 } | 389 } |
| 390 | 390 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 426 // Message was sent. | 426 // Message was sent. |
| 427 CHECK(!output_queue_.empty()); | 427 CHECK(!output_queue_.empty()); |
| 428 Message* m = output_queue_.front(); | 428 Message* m = output_queue_.front(); |
| 429 output_queue_.pop(); | 429 output_queue_.pop(); |
| 430 delete m; | 430 delete m; |
| 431 } | 431 } |
| 432 | 432 |
| 433 if (output_queue_.empty()) | 433 if (output_queue_.empty()) |
| 434 return true; | 434 return true; |
| 435 | 435 |
| 436 if (INVALID_HANDLE_VALUE == pipe_) | 436 if (!pipe_.IsValid()) |
| 437 return false; | 437 return false; |
| 438 | 438 |
| 439 // Write to pipe... | 439 // Write to pipe... |
| 440 Message* m = output_queue_.front(); | 440 Message* m = output_queue_.front(); |
| 441 DCHECK(m->size() <= INT_MAX); | 441 DCHECK(m->size() <= INT_MAX); |
| 442 debug_flags_ |= WRITE_MSG; | 442 debug_flags_ |= WRITE_MSG; |
| 443 CHECK(!writing_); | 443 CHECK(!writing_); |
| 444 writing_ = true; | 444 writing_ = true; |
| 445 write_size_ = static_cast<uint32>(m->size()); | 445 write_size_ = static_cast<uint32>(m->size()); |
| 446 write_error_ = 0; | 446 write_error_ = 0; |
| 447 BOOL ok = WriteFile(pipe_, | 447 BOOL ok = WriteFile(pipe_.Get(), |
| 448 m->data(), | 448 m->data(), |
| 449 write_size_, | 449 write_size_, |
| 450 NULL, | 450 NULL, |
| 451 &output_state_.context.overlapped); | 451 &output_state_.context.overlapped); |
| 452 if (!ok) { | 452 if (!ok) { |
| 453 write_error_ = GetLastError(); | 453 write_error_ = GetLastError(); |
| 454 if (write_error_ == ERROR_IO_PENDING) { | 454 if (write_error_ == ERROR_IO_PENDING) { |
| 455 output_state_.is_pending = true; | 455 output_state_.is_pending = true; |
| 456 | 456 |
| 457 DVLOG(2) << "sent pending message @" << m << " on channel @" << this | 457 DVLOG(2) << "sent pending message @" << m << " on channel @" << this |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 500 if (input_state_.is_pending) { | 500 if (input_state_.is_pending) { |
| 501 // This is the normal case for everything except the initialization step. | 501 // This is the normal case for everything except the initialization step. |
| 502 debug_flags_ |= READ_COMPLETED; | 502 debug_flags_ |= READ_COMPLETED; |
| 503 if (debug_flags_ & WAIT_FOR_READ) { | 503 if (debug_flags_ & WAIT_FOR_READ) { |
| 504 CHECK(!(debug_flags_ & WAIT_FOR_READ_COMPLETE)); | 504 CHECK(!(debug_flags_ & WAIT_FOR_READ_COMPLETE)); |
| 505 debug_flags_ |= WAIT_FOR_READ_COMPLETE; | 505 debug_flags_ |= WAIT_FOR_READ_COMPLETE; |
| 506 } | 506 } |
| 507 input_state_.is_pending = false; | 507 input_state_.is_pending = false; |
| 508 if (!bytes_transfered) | 508 if (!bytes_transfered) |
| 509 ok = false; | 509 ok = false; |
| 510 else if (pipe_ != INVALID_HANDLE_VALUE) | 510 else if (pipe_.IsValid()) |
| 511 ok = AsyncReadComplete(bytes_transfered); | 511 ok = AsyncReadComplete(bytes_transfered); |
| 512 } else { | 512 } else { |
| 513 DCHECK(!bytes_transfered); | 513 DCHECK(!bytes_transfered); |
| 514 } | 514 } |
| 515 | 515 |
| 516 // Request more data. | 516 // Request more data. |
| 517 if (ok) | 517 if (ok) |
| 518 ok = ProcessIncomingMessages(); | 518 ok = ProcessIncomingMessages(); |
| 519 } else { | 519 } else { |
| 520 DCHECK(context == &output_state_.context); | 520 DCHECK(context == &output_state_.context); |
| 521 CHECK(writing_); | 521 CHECK(writing_); |
| 522 CHECK(output_state_.is_pending); | 522 CHECK(output_state_.is_pending); |
| 523 writing_ = false; | 523 writing_ = false; |
| 524 debug_flags_ |= WRITE_COMPLETED; | 524 debug_flags_ |= WRITE_COMPLETED; |
| 525 if (debug_flags_ & WAIT_FOR_WRITE) { | 525 if (debug_flags_ & WAIT_FOR_WRITE) { |
| 526 CHECK(!(debug_flags_ & WAIT_FOR_WRITE_COMPLETE)); | 526 CHECK(!(debug_flags_ & WAIT_FOR_WRITE_COMPLETE)); |
| 527 debug_flags_ |= WAIT_FOR_WRITE_COMPLETE; | 527 debug_flags_ |= WAIT_FOR_WRITE_COMPLETE; |
| 528 } | 528 } |
| 529 ok = ProcessOutgoingMessages(context, bytes_transfered); | 529 ok = ProcessOutgoingMessages(context, bytes_transfered); |
| 530 } | 530 } |
| 531 if (!ok && INVALID_HANDLE_VALUE != pipe_) { | 531 if (!ok && pipe_.IsValid()) { |
| 532 // We don't want to re-enter Close(). | 532 // We don't want to re-enter Close(). |
| 533 Close(); | 533 Close(); |
| 534 listener()->OnChannelError(); | 534 listener()->OnChannelError(); |
| 535 } | 535 } |
| 536 } | 536 } |
| 537 | 537 |
| 538 //------------------------------------------------------------------------------ | 538 //------------------------------------------------------------------------------ |
| 539 // Channel's methods | 539 // Channel's methods |
| 540 | 540 |
| 541 // static | 541 // static |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 564 int secret; | 564 int secret; |
| 565 do { // Guarantee we get a non-zero value. | 565 do { // Guarantee we get a non-zero value. |
| 566 secret = base::RandInt(0, std::numeric_limits<int>::max()); | 566 secret = base::RandInt(0, std::numeric_limits<int>::max()); |
| 567 } while (secret == 0); | 567 } while (secret == 0); |
| 568 | 568 |
| 569 id.append(GenerateUniqueRandomChannelID()); | 569 id.append(GenerateUniqueRandomChannelID()); |
| 570 return id.append(base::StringPrintf("\\%d", secret)); | 570 return id.append(base::StringPrintf("\\%d", secret)); |
| 571 } | 571 } |
| 572 | 572 |
| 573 } // namespace IPC | 573 } // namespace IPC |
| OLD | NEW |