+ // Operate according to the pipe state
+ switch (pipe_[i].state) {
+ case READING_STATE:
+ // The pipe instance is connected to a client
+ // and is ready to read a request.
+ LASSERT(!is_outpipe, /**/);
+ success = ReadFile(pipe_[i].handle,
+ pipe_[i].readbuf, PIPE_BUFSIZE - 1,
+ &pipe_[i].nbytes, &pipe_[i].overlap);
+
+ if (success && pipe_[i].nbytes != 0) {
+ // The read operation completed successfully.
+ pipe_[i].pending_io = false;
+ pipe_[i].state = WRITING_STATE;
+ continue;
+ }
+
+ error = GetLastError();
+
+ if (!success && error == ERROR_IO_PENDING) {
+ // The read operation is still pending.
+ pipe_[i].pending_io = true;
+ continue;
+ }
+
+ success = error == ERROR_BROKEN_PIPE;
+
+ // Client closed connection (ERROR_BROKEN_PIPE) or
+ // an error occurred; in either case, reset the pipe.
+ if (!success) {
+ lyxerr << "LyXComm: " << errormsg(error) << endl;
+ if (!pipe_[i].iobuf.empty()) {
+ lyxerr << "LyXComm: truncated command: "
+ << pipe_[i].iobuf << endl;
+ pipe_[i].iobuf.erase();
+ }
+ }
+ if (!resetPipe(i, !success))
+ return false;
+ break;
+
+ case WRITING_STATE:
+ if (!is_outpipe) {
+ // The request was successfully read
+ // from the client; commit it.
+ ReadReadyEvent * event = new ReadReadyEvent(i);
+ QCoreApplication::postEvent(this,
+ static_cast<QEvent *>(event));
+ // Wait for completion
+ while (pipe_[i].nbytes && !checkStopServer(100))
+ ;
+ pipe_[i].pending_io = false;
+ pipe_[i].state = READING_STATE;
+ continue;
+ }
+
+ // This is an output pipe instance. Initiate the
+ // overlapped write operation or monitor its progress.
+
+ if (pipe_[i].pending_io) {
+ success = WriteFile(pipe_[i].handle,
+ pipe_[i].iobuf.c_str(),
+ pipe_[i].iobuf.length(),
+ &status,
+ &pipe_[i].overlap);
+ }
+
+ if (success && !pipe_[i].iobuf.empty()
+ && status == pipe_[i].iobuf.length()) {
+ // The write operation completed successfully.
+ pipe_[i].iobuf.erase();
+ pipe_[i].pending_io = false;
+ if (!resetPipe(i))
+ return false;
+ continue;
+ }
+
+ error = GetLastError();
+
+ if (success && error == ERROR_IO_PENDING) {
+ // The write operation is still pending.
+ // We get here when a reader is started
+ // well before a reply is ready, so delay
+ // a bit in order to not burden the cpu.
+ checkStopServer(100);
+ pipe_[i].pending_io = true;
+ continue;
+ }
+
+ success = error == ERROR_NO_DATA;
+
+ // Client closed connection (ERROR_NO_DATA) or
+ // an error occurred; in either case, reset the pipe.
+ if (!success) {
+ lyxerr << "LyXComm: Error sending message: "
+ << pipe_[i].iobuf << "\nLyXComm: "
+ << errormsg(error) << endl;
+ }
+ if (!resetPipe(i, !success))
+ return false;