in nailgun-server/src/main/java/com/facebook/nailgun/NGWin32NamedPipeServerSocket.java [116:168]
public Socket accept() throws IOException {
HANDLE handle =
API.CreateNamedPipe(
path,
NGWin32NamedPipeLibrary.PIPE_ACCESS_DUPLEX | WinNT.FILE_FLAG_OVERLAPPED,
0,
maxInstances,
BUFFER_SIZE,
BUFFER_SIZE,
0,
null);
if (handle == NGWin32NamedPipeLibrary.INVALID_HANDLE_VALUE) {
throw new IOException(
String.format("Could not create named pipe, error %d", API.GetLastError()));
}
openHandles.add(handle);
HANDLE connWaitable = API.CreateEvent(null, true, false, null);
WinBase.OVERLAPPED olap = new WinBase.OVERLAPPED();
olap.hEvent = connWaitable;
olap.write();
boolean immediate = API.ConnectNamedPipe(handle, olap.getPointer());
if (immediate) {
openHandles.remove(handle);
connectedHandles.add(handle);
return new NGWin32NamedPipeSocket(handle, closeCallback, requireStrictLength);
}
int connectError = API.GetLastError();
if (connectError == WinError.ERROR_PIPE_CONNECTED) {
openHandles.remove(handle);
connectedHandles.add(handle);
return new NGWin32NamedPipeSocket(handle, closeCallback, requireStrictLength);
} else if (connectError == WinError.ERROR_NO_DATA) {
// Client has connected and disconnected between CreateNamedPipe() and ConnectNamedPipe()
// connection is broken, but it is returned it avoid loop here.
// Actual error will happen for NGSession when it will try to read/write from/to pipe
return new NGWin32NamedPipeSocket(handle, closeCallback, requireStrictLength);
} else if (connectError == WinError.ERROR_IO_PENDING) {
if (!API.GetOverlappedResult(handle, olap.getPointer(), new IntByReference(), true)) {
openHandles.remove(handle);
closeOpenPipe(handle);
throw new IOException(
"GetOverlappedResult() failed for connect operation: " + API.GetLastError());
}
openHandles.remove(handle);
connectedHandles.add(handle);
return new NGWin32NamedPipeSocket(handle, closeCallback, requireStrictLength);
} else {
throw new IOException("ConnectNamedPipe() failed with: " + connectError);
}
}