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

Unified Diff: util/win/registration_protocol_win.cc

Issue 1427643010: win: Explain the CreateFile() client-side pipe-opening loop (Closed) Base URL: https://chromium.googlesource.com/crashpad/crashpad@master
Patch Set: Explain more Created 5 years, 1 month 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..eff27e2855028e1483fb027e5ae9e38837365f88 100644
--- a/util/win/registration_protocol_win.cc
+++ b/util/win/registration_protocol_win.cc
@@ -24,8 +24,22 @@ 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.
+ //
+ // This loop is only intended to retry on ERROR_PIPE_BUSY. Notably, if the
+ // handler is so lazy that it hasn’t even called CreateNamedPipe() yet,
+ // CreateFile() will fail with ERROR_FILE_NOT_FOUND, and this function is
+ // expected to fail without retrying anything. If the handler is started at
+ // around the same time as its client, something external to this code must be
+ // done to guarantee correct ordering. When the client starts the handler
+ // itself, CrashpadClient::StartHandler() provides this synchronization.
+ for (int tries = 0;;) {
ScopedFileHANDLE pipe(
CreateFile(pipe_name.c_str(),
GENERIC_READ | GENERIC_WRITE,
@@ -65,12 +79,12 @@ bool SendToCrashHandlerServer(const base::string16& pipe_name,
&bytes_read,
nullptr);
if (!result) {
- LOG(ERROR) << "TransactNamedPipe: expected " << sizeof(*response)
- << ", 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;
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698