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

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: Rebase Created 6 years, 2 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 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 return true; 148 return true;
152 // If ERROR_SEM_TIMEOUT occurred, the pipe exists but is handling another 149 // If ERROR_SEM_TIMEOUT occurred, the pipe exists but is handling another
153 // connection. 150 // connection.
154 return GetLastError() == ERROR_SEM_TIMEOUT; 151 return GetLastError() == ERROR_SEM_TIMEOUT;
155 } 152 }
156 153
157 ChannelWin::ReadState ChannelWin::ReadData( 154 ChannelWin::ReadState ChannelWin::ReadData(
158 char* buffer, 155 char* buffer,
159 int buffer_len, 156 int buffer_len,
160 int* /* bytes_read */) { 157 int* /* bytes_read */) {
161 if (INVALID_HANDLE_VALUE == pipe_) 158 if (!pipe_.IsValid())
162 return READ_FAILED; 159 return READ_FAILED;
163 160
164 debug_flags_ |= READ_MSG; 161 debug_flags_ |= READ_MSG;
165 DWORD bytes_read = 0; 162 DWORD bytes_read = 0;
166 BOOL ok = ReadFile(pipe_, buffer, buffer_len, 163 BOOL ok = ReadFile(pipe_.Get(), buffer, buffer_len,
167 &bytes_read, &input_state_.context.overlapped); 164 &bytes_read, &input_state_.context.overlapped);
168 if (!ok) { 165 if (!ok) {
169 DWORD err = GetLastError(); 166 DWORD err = GetLastError();
170 if (err == ERROR_IO_PENDING) { 167 if (err == ERROR_IO_PENDING) {
171 input_state_.is_pending = true; 168 input_state_.is_pending = true;
172 return READ_PENDING; 169 return READ_PENDING;
173 } 170 }
174 LOG(ERROR) << "pipe error: " << err; 171 LOG(ERROR) << "pipe error: " << err;
175 return READ_FAILED; 172 return READ_FAILED;
176 } 173 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 return base::ASCIIToWide(name.append(channel_id.substr(0, index - 1))); 234 return base::ASCIIToWide(name.append(channel_id.substr(0, index - 1)));
238 } 235 }
239 236
240 // This case is here to support predictable named pipes in tests. 237 // This case is here to support predictable named pipes in tests.
241 if (secret) 238 if (secret)
242 *secret = 0; 239 *secret = 0;
243 return base::ASCIIToWide(name.append(channel_id)); 240 return base::ASCIIToWide(name.append(channel_id));
244 } 241 }
245 242
246 bool ChannelWin::CreatePipe(const IPC::ChannelHandle &channel_handle, 243 bool ChannelWin::CreatePipe(const IPC::ChannelHandle &channel_handle,
247 Mode mode) { 244 Mode mode) {
248 DCHECK_EQ(INVALID_HANDLE_VALUE, pipe_); 245 DCHECK(!pipe_.IsValid());
249 base::string16 pipe_name; 246 base::string16 pipe_name;
250 // If we already have a valid pipe for channel just copy it. 247 // If we already have a valid pipe for channel just copy it.
251 if (channel_handle.pipe.handle) { 248 if (channel_handle.pipe.handle) {
249 // TODO(rvargas) crbug.com/415294: ChannelHandle should either go away in
250 // favor of two independent entities (name/file), or it should be a move-
251 // only type with a base::File member. In any case, this code should not
252 // call DuplicateHandle.
252 DCHECK(channel_handle.name.empty()); 253 DCHECK(channel_handle.name.empty());
253 pipe_name = L"Not Available"; // Just used for LOG 254 pipe_name = L"Not Available"; // Just used for LOG
254 // Check that the given pipe confirms to the specified mode. We can 255 // Check that the given pipe confirms to the specified mode. We can
255 // only check for PIPE_TYPE_MESSAGE & PIPE_SERVER_END flags since the 256 // only check for PIPE_TYPE_MESSAGE & PIPE_SERVER_END flags since the
256 // other flags (PIPE_TYPE_BYTE, and PIPE_CLIENT_END) are defined as 0. 257 // other flags (PIPE_TYPE_BYTE, and PIPE_CLIENT_END) are defined as 0.
257 DWORD flags = 0; 258 DWORD flags = 0;
258 GetNamedPipeInfo(channel_handle.pipe.handle, &flags, NULL, NULL, NULL); 259 GetNamedPipeInfo(channel_handle.pipe.handle, &flags, NULL, NULL, NULL);
259 DCHECK(!(flags & PIPE_TYPE_MESSAGE)); 260 DCHECK(!(flags & PIPE_TYPE_MESSAGE));
260 if (((mode & MODE_SERVER_FLAG) && !(flags & PIPE_SERVER_END)) || 261 if (((mode & MODE_SERVER_FLAG) && !(flags & PIPE_SERVER_END)) ||
261 ((mode & MODE_CLIENT_FLAG) && (flags & PIPE_SERVER_END))) { 262 ((mode & MODE_CLIENT_FLAG) && (flags & PIPE_SERVER_END))) {
262 LOG(WARNING) << "Inconsistent open mode. Mode :" << mode; 263 LOG(WARNING) << "Inconsistent open mode. Mode :" << mode;
263 return false; 264 return false;
264 } 265 }
266 HANDLE local_handle;
265 if (!DuplicateHandle(GetCurrentProcess(), 267 if (!DuplicateHandle(GetCurrentProcess(),
266 channel_handle.pipe.handle, 268 channel_handle.pipe.handle,
267 GetCurrentProcess(), 269 GetCurrentProcess(),
268 &pipe_, 270 &local_handle,
269 0, 271 0,
270 FALSE, 272 FALSE,
271 DUPLICATE_SAME_ACCESS)) { 273 DUPLICATE_SAME_ACCESS)) {
272 LOG(WARNING) << "DuplicateHandle failed. Error :" << GetLastError(); 274 LOG(WARNING) << "DuplicateHandle failed. Error :" << GetLastError();
273 return false; 275 return false;
274 } 276 }
277 pipe_.Set(local_handle);
275 } else if (mode & MODE_SERVER_FLAG) { 278 } else if (mode & MODE_SERVER_FLAG) {
276 DCHECK(!channel_handle.pipe.handle); 279 DCHECK(!channel_handle.pipe.handle);
277 const DWORD open_mode = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | 280 const DWORD open_mode = PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED |
278 FILE_FLAG_FIRST_PIPE_INSTANCE; 281 FILE_FLAG_FIRST_PIPE_INSTANCE;
279 pipe_name = PipeName(channel_handle.name, &client_secret_); 282 pipe_name = PipeName(channel_handle.name, &client_secret_);
280 validate_client_ = !!client_secret_; 283 validate_client_ = !!client_secret_;
281 pipe_ = CreateNamedPipeW(pipe_name.c_str(), 284 pipe_.Set(CreateNamedPipeW(pipe_name.c_str(),
282 open_mode, 285 open_mode,
283 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE, 286 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE,
284 1, 287 1,
285 Channel::kReadBufferSize, 288 Channel::kReadBufferSize,
286 Channel::kReadBufferSize, 289 Channel::kReadBufferSize,
287 5000, 290 5000,
288 NULL); 291 NULL));
289 } else if (mode & MODE_CLIENT_FLAG) { 292 } else if (mode & MODE_CLIENT_FLAG) {
290 DCHECK(!channel_handle.pipe.handle); 293 DCHECK(!channel_handle.pipe.handle);
291 pipe_name = PipeName(channel_handle.name, &client_secret_); 294 pipe_name = PipeName(channel_handle.name, &client_secret_);
292 pipe_ = CreateFileW(pipe_name.c_str(), 295 pipe_.Set(CreateFileW(pipe_name.c_str(),
293 GENERIC_READ | GENERIC_WRITE, 296 GENERIC_READ | GENERIC_WRITE,
294 0, 297 0,
295 NULL, 298 NULL,
296 OPEN_EXISTING, 299 OPEN_EXISTING,
297 SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION | 300 SECURITY_SQOS_PRESENT | SECURITY_IDENTIFICATION |
298 FILE_FLAG_OVERLAPPED, 301 FILE_FLAG_OVERLAPPED,
299 NULL); 302 NULL));
300 } else { 303 } else {
301 NOTREACHED(); 304 NOTREACHED();
302 } 305 }
303 306
304 if (pipe_ == INVALID_HANDLE_VALUE) { 307 if (!pipe_.IsValid()) {
305 // If this process is being closed, the pipe may be gone already. 308 // If this process is being closed, the pipe may be gone already.
306 PLOG(WARNING) << "Unable to create pipe \"" << pipe_name << "\" in " 309 PLOG(WARNING) << "Unable to create pipe \"" << pipe_name << "\" in "
307 << (mode & MODE_SERVER_FLAG ? "server" : "client") << " mode"; 310 << (mode & MODE_SERVER_FLAG ? "server" : "client") << " mode";
308 return false; 311 return false;
309 } 312 }
310 313
311 // Create the Hello message to be sent when Connect is called 314 // Create the Hello message to be sent when Connect is called
312 scoped_ptr<Message> m(new Message(MSG_ROUTING_NONE, 315 scoped_ptr<Message> m(new Message(MSG_ROUTING_NONE,
313 HELLO_MESSAGE_TYPE, 316 HELLO_MESSAGE_TYPE,
314 IPC::Message::PRIORITY_NORMAL)); 317 IPC::Message::PRIORITY_NORMAL));
315 318
316 // Don't send the secret to the untrusted process, and don't send a secret 319 // Don't send the secret to the untrusted process, and don't send a secret
317 // if the value is zero (for IPC backwards compatability). 320 // if the value is zero (for IPC backwards compatability).
318 int32 secret = validate_client_ ? 0 : client_secret_; 321 int32 secret = validate_client_ ? 0 : client_secret_;
319 if (!m->WriteInt(GetCurrentProcessId()) || 322 if (!m->WriteInt(GetCurrentProcessId()) ||
320 (secret && !m->WriteUInt32(secret))) { 323 (secret && !m->WriteUInt32(secret))) {
321 CloseHandle(pipe_); 324 pipe_.Close();
322 pipe_ = INVALID_HANDLE_VALUE;
323 return false; 325 return false;
324 } 326 }
325 327
326 debug_flags_ |= INIT_DONE; 328 debug_flags_ |= INIT_DONE;
327 329
328 output_queue_.push(m.release()); 330 output_queue_.push(m.release());
329 return true; 331 return true;
330 } 332 }
331 333
332 bool ChannelWin::Connect() { 334 bool ChannelWin::Connect() {
333 DLOG_IF(WARNING, thread_check_.get()) << "Connect called more than once"; 335 DLOG_IF(WARNING, thread_check_.get()) << "Connect called more than once";
334 336
335 if (!thread_check_.get()) 337 if (!thread_check_.get())
336 thread_check_.reset(new base::ThreadChecker()); 338 thread_check_.reset(new base::ThreadChecker());
337 339
338 if (pipe_ == INVALID_HANDLE_VALUE) 340 if (!pipe_.IsValid())
339 return false; 341 return false;
340 342
341 base::MessageLoopForIO::current()->RegisterIOHandler(pipe_, this); 343 base::MessageLoopForIO::current()->RegisterIOHandler(pipe_.Get(), this);
342 344
343 // Check to see if there is a client connected to our pipe... 345 // Check to see if there is a client connected to our pipe...
344 if (waiting_connect_) 346 if (waiting_connect_)
345 ProcessConnection(); 347 ProcessConnection();
346 348
347 if (!input_state_.is_pending) { 349 if (!input_state_.is_pending) {
348 // Complete setup asynchronously. By not setting input_state_.is_pending 350 // Complete setup asynchronously. By not setting input_state_.is_pending
349 // to true, we indicate to OnIOCompleted that this is the special 351 // to true, we indicate to OnIOCompleted that this is the special
350 // initialization signal. 352 // initialization signal.
351 base::MessageLoopForIO::current()->PostTask( 353 base::MessageLoopForIO::current()->PostTask(
352 FROM_HERE, 354 FROM_HERE,
353 base::Bind(&ChannelWin::OnIOCompleted, 355 base::Bind(&ChannelWin::OnIOCompleted,
354 weak_factory_.GetWeakPtr(), 356 weak_factory_.GetWeakPtr(),
355 &input_state_.context, 357 &input_state_.context,
356 0, 358 0,
357 0)); 359 0));
358 } 360 }
359 361
360 if (!waiting_connect_) 362 if (!waiting_connect_)
361 ProcessOutgoingMessages(NULL, 0); 363 ProcessOutgoingMessages(NULL, 0);
362 return true; 364 return true;
363 } 365 }
364 366
365 bool ChannelWin::ProcessConnection() { 367 bool ChannelWin::ProcessConnection() {
366 DCHECK(thread_check_->CalledOnValidThread()); 368 DCHECK(thread_check_->CalledOnValidThread());
367 if (input_state_.is_pending) 369 if (input_state_.is_pending)
368 input_state_.is_pending = false; 370 input_state_.is_pending = false;
369 371
370 // Do we have a client connected to our pipe? 372 // Do we have a client connected to our pipe?
371 if (INVALID_HANDLE_VALUE == pipe_) 373 if (!pipe_.IsValid())
372 return false; 374 return false;
373 375
374 BOOL ok = ConnectNamedPipe(pipe_, &input_state_.context.overlapped); 376 BOOL ok = ConnectNamedPipe(pipe_.Get(), &input_state_.context.overlapped);
375 debug_flags_ |= CALLED_CONNECT; 377 debug_flags_ |= CALLED_CONNECT;
376 378
377 DWORD err = GetLastError(); 379 DWORD err = GetLastError();
378 if (ok) { 380 if (ok) {
379 // Uhm, the API documentation says that this function should never 381 // Uhm, the API documentation says that this function should never
380 // return success when used in overlapped mode. 382 // return success when used in overlapped mode.
381 NOTREACHED(); 383 NOTREACHED();
382 return false; 384 return false;
383 } 385 }
384 386
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 // Message was sent. 422 // Message was sent.
421 CHECK(!output_queue_.empty()); 423 CHECK(!output_queue_.empty());
422 Message* m = output_queue_.front(); 424 Message* m = output_queue_.front();
423 output_queue_.pop(); 425 output_queue_.pop();
424 delete m; 426 delete m;
425 } 427 }
426 428
427 if (output_queue_.empty()) 429 if (output_queue_.empty())
428 return true; 430 return true;
429 431
430 if (INVALID_HANDLE_VALUE == pipe_) 432 if (!pipe_.IsValid())
431 return false; 433 return false;
432 434
433 // Write to pipe... 435 // Write to pipe...
434 Message* m = output_queue_.front(); 436 Message* m = output_queue_.front();
435 DCHECK(m->size() <= INT_MAX); 437 DCHECK(m->size() <= INT_MAX);
436 debug_flags_ |= WRITE_MSG; 438 debug_flags_ |= WRITE_MSG;
437 CHECK(!writing_); 439 CHECK(!writing_);
438 writing_ = true; 440 writing_ = true;
439 write_size_ = static_cast<uint32>(m->size()); 441 write_size_ = static_cast<uint32>(m->size());
440 write_error_ = 0; 442 write_error_ = 0;
441 BOOL ok = WriteFile(pipe_, 443 BOOL ok = WriteFile(pipe_.Get(),
442 m->data(), 444 m->data(),
443 write_size_, 445 write_size_,
444 NULL, 446 NULL,
445 &output_state_.context.overlapped); 447 &output_state_.context.overlapped);
446 if (!ok) { 448 if (!ok) {
447 write_error_ = GetLastError(); 449 write_error_ = GetLastError();
448 if (write_error_ == ERROR_IO_PENDING) { 450 if (write_error_ == ERROR_IO_PENDING) {
449 output_state_.is_pending = true; 451 output_state_.is_pending = true;
450 452
451 DVLOG(2) << "sent pending message @" << m << " on channel @" << this 453 DVLOG(2) << "sent pending message @" << m << " on channel @" << this
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 if (input_state_.is_pending) { 496 if (input_state_.is_pending) {
495 // This is the normal case for everything except the initialization step. 497 // This is the normal case for everything except the initialization step.
496 debug_flags_ |= READ_COMPLETED; 498 debug_flags_ |= READ_COMPLETED;
497 if (debug_flags_ & WAIT_FOR_READ) { 499 if (debug_flags_ & WAIT_FOR_READ) {
498 CHECK(!(debug_flags_ & WAIT_FOR_READ_COMPLETE)); 500 CHECK(!(debug_flags_ & WAIT_FOR_READ_COMPLETE));
499 debug_flags_ |= WAIT_FOR_READ_COMPLETE; 501 debug_flags_ |= WAIT_FOR_READ_COMPLETE;
500 } 502 }
501 input_state_.is_pending = false; 503 input_state_.is_pending = false;
502 if (!bytes_transfered) 504 if (!bytes_transfered)
503 ok = false; 505 ok = false;
504 else if (pipe_ != INVALID_HANDLE_VALUE) 506 else if (pipe_.IsValid())
505 ok = AsyncReadComplete(bytes_transfered); 507 ok = AsyncReadComplete(bytes_transfered);
506 } else { 508 } else {
507 DCHECK(!bytes_transfered); 509 DCHECK(!bytes_transfered);
508 } 510 }
509 511
510 // Request more data. 512 // Request more data.
511 if (ok) 513 if (ok)
512 ok = ProcessIncomingMessages(); 514 ok = ProcessIncomingMessages();
513 } else { 515 } else {
514 DCHECK(context == &output_state_.context); 516 DCHECK(context == &output_state_.context);
515 CHECK(writing_); 517 CHECK(writing_);
516 CHECK(output_state_.is_pending); 518 CHECK(output_state_.is_pending);
517 writing_ = false; 519 writing_ = false;
518 debug_flags_ |= WRITE_COMPLETED; 520 debug_flags_ |= WRITE_COMPLETED;
519 if (debug_flags_ & WAIT_FOR_WRITE) { 521 if (debug_flags_ & WAIT_FOR_WRITE) {
520 CHECK(!(debug_flags_ & WAIT_FOR_WRITE_COMPLETE)); 522 CHECK(!(debug_flags_ & WAIT_FOR_WRITE_COMPLETE));
521 debug_flags_ |= WAIT_FOR_WRITE_COMPLETE; 523 debug_flags_ |= WAIT_FOR_WRITE_COMPLETE;
522 } 524 }
523 ok = ProcessOutgoingMessages(context, bytes_transfered); 525 ok = ProcessOutgoingMessages(context, bytes_transfered);
524 } 526 }
525 if (!ok && INVALID_HANDLE_VALUE != pipe_) { 527 if (!ok && pipe_.IsValid()) {
526 // We don't want to re-enter Close(). 528 // We don't want to re-enter Close().
527 Close(); 529 Close();
528 listener()->OnChannelError(); 530 listener()->OnChannelError();
529 } 531 }
530 } 532 }
531 533
532 //------------------------------------------------------------------------------ 534 //------------------------------------------------------------------------------
533 // Channel's methods 535 // Channel's methods
534 536
535 // static 537 // static
(...skipping 22 matching lines...) Expand all
558 int secret; 560 int secret;
559 do { // Guarantee we get a non-zero value. 561 do { // Guarantee we get a non-zero value.
560 secret = base::RandInt(0, std::numeric_limits<int>::max()); 562 secret = base::RandInt(0, std::numeric_limits<int>::max());
561 } while (secret == 0); 563 } while (secret == 0);
562 564
563 id.append(GenerateUniqueRandomChannelID()); 565 id.append(GenerateUniqueRandomChannelID());
564 return id.append(base::StringPrintf("\\%d", secret)); 566 return id.append(base::StringPrintf("\\%d", secret));
565 } 567 }
566 568
567 } // namespace IPC 569 } // 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