Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1949)

Side by Side Diff: ipc/ipc_channel_win.cc

Issue 588383003: IPC: Use ScopedHandle instead of a raw HANDLE for the private members. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ipc/ipc_channel_win.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « ipc/ipc_channel_win.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698