+ return WaitForSingleObject(stopserver_, timeout) == WAIT_OBJECT_0;
+}
+
+
+bool LyXComm::startPipe(DWORD index)
+{
+ pipe_[index].pending_io = false;
+ pipe_[index].overlap.Offset = 0;
+ pipe_[index].overlap.OffsetHigh = 0;
+
+ // Overlapped ConnectNamedPipe should return zero.
+ if (ConnectNamedPipe(pipe_[index].handle, &pipe_[index].overlap)) {
+ DWORD const error = GetLastError();
+ lyxerr << "LyXComm: Could not connect pipe "
+ << external_path(pipeName(index))
+ << "\nLyXComm: " << errormsg(error) << endl;
+ return false;
+ }
+
+ switch (GetLastError()) {
+ case ERROR_IO_PENDING:
+ // The overlapped connection is in progress.
+ pipe_[index].pending_io = true;
+ break;
+
+ case ERROR_PIPE_CONNECTED:
+ // Client is already connected, so signal an event.
+ if (SetEvent(pipe_[index].overlap.hEvent))
+ break;
+ // fall through
+ default:
+ // Anything else is an error.
+ DWORD const error = GetLastError();
+ lyxerr << "LyXComm: An error occurred while connecting pipe "
+ << external_path(pipeName(index))
+ << "\nLyXComm: " << errormsg(error) << endl;
+ return false;
+ }
+
+ return true;
+}
+
+
+bool LyXComm::resetPipe(DWORD index, bool close_handle)
+{
+ // This method is called when an error occurs or when a client
+ // closes the connection. We first disconnect the pipe instance,
+ // then reconnect it, ready to wait for another client.
+
+ if (!DisconnectNamedPipe(pipe_[index].handle)) {
+ DWORD const error = GetLastError();
+ lyxerr << "LyXComm: Could not disconnect pipe "
+ << external_path(pipeName(index))
+ << "\nLyXComm: " << errormsg(error) << endl;
+ // What to do now? Let's try whether re-creating the pipe helps.
+ close_handle = true;
+ }
+
+ bool const is_outpipe = index >= MAX_CLIENTS;
+
+ if (close_handle) {
+ DWORD const open_mode = is_outpipe ? PIPE_ACCESS_OUTBOUND
+ : PIPE_ACCESS_INBOUND;
+ string const name = external_path(pipeName(index));
+
+ CloseHandle(pipe_[index].handle);
+
+ pipe_[index].iobuf.erase();
+ pipe_[index].handle = CreateNamedPipe(name.c_str(),
+ open_mode | FILE_FLAG_OVERLAPPED, PIPE_WAIT,
+ MAX_CLIENTS, PIPE_BUFSIZE, PIPE_BUFSIZE,
+ PIPE_TIMEOUT, NULL);
+
+ if (pipe_[index].handle == INVALID_HANDLE_VALUE) {
+ DWORD const error = GetLastError();
+ lyxerr << "LyXComm: Could not reset pipe " << name
+ << "\nLyXComm: " << errormsg(error) << endl;
+ return false;
+ }
+ }
+
+ if (!startPipe(index))
+ return false;
+ pipe_[index].state = pipe_[index].pending_io ?
+ CONNECTING_STATE : (is_outpipe ? WRITING_STATE
+ : READING_STATE);
+ return true;