Chromium Code Reviews| Index: util/win/registration_protocol_win.cc |
| diff --git a/util/win/registration_protocol_win.cc b/util/win/registration_protocol_win.cc |
| index 38b1b45195a6b86f2353da09e1da04e8f5f9252d..af7f522508cdcdfc9c9c9f2653b0afc3b6e94b10 100644 |
| --- a/util/win/registration_protocol_win.cc |
| +++ b/util/win/registration_protocol_win.cc |
| @@ -24,8 +24,14 @@ namespace crashpad { |
| bool SendToCrashHandlerServer(const base::string16& pipe_name, |
| const crashpad::ClientToServerMessage& message, |
| crashpad::ServerToClientMessage* response) { |
| - int tries = 0; |
| - for (;;) { |
| + // Retry CreateFile() in a loop. If the handler isn’t actively waiting in |
| + // ConnectNamedPipe() on a pipe instance because it’s busy doing something |
| + // else, CreateFile() will fail with ERROR_PIPE_BUSY. WaitNamedPipe() waits |
| + // until a pipe instance is ready, but there’s no way to wait for this |
| + // condition and atomically open the client side of the pipe in a single |
| + // operation. CallNamedPipe() implements similar retry logic to this, also in |
| + // user-mode code. |
|
scottmg
2015/11/10 20:02:20
You could maybe also note that this means we don't
Mark Mentovai
2015/11/10 20:12:19
scottmg wrote:
|
| + for (int tries = 0;;) { |
| ScopedFileHANDLE pipe( |
| CreateFile(pipe_name.c_str(), |
| GENERIC_READ | GENERIC_WRITE, |
| @@ -65,12 +71,12 @@ bool SendToCrashHandlerServer(const base::string16& pipe_name, |
| &bytes_read, |
| nullptr); |
| if (!result) { |
| - LOG(ERROR) << "TransactNamedPipe: expected " << sizeof(*response) |
|
scottmg
2015/11/10 20:02:19
Duh, oops.
|
| - << ", observed " << bytes_read; |
| + PLOG(ERROR) << "TransactNamedPipe"; |
| return false; |
| } |
| if (bytes_read != sizeof(*response)) { |
| - LOG(ERROR) << "TransactNamedPipe read incorrect number of bytes"; |
| + LOG(ERROR) << "TransactNamedPipe: expected " << sizeof(*response) |
| + << ", observed " << bytes_read; |
| return false; |
| } |
| return true; |