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 |