X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FServer.cpp;h=522060e91b6a70682b7ad0163ae9449cafbb240e;hb=f6f936e3d049c05ad0795c32696df895d8b61313;hp=fed89ace5b0ce4813f65745133dd79bb55449667;hpb=33f7c028a2df25a6bd69a50adeb85d59c1fc4fea;p=lyx.git diff --git a/src/Server.cpp b/src/Server.cpp index fed89ace5b..522060e91b 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -56,11 +56,15 @@ #include "support/lstrings.h" #include "support/os.h" -#include "support/bind.h" +#include #ifdef _WIN32 -#include -#include +# include +# include +#else +# ifdef HAVE_UNISTD_H +# include +# endif #endif #include @@ -116,7 +120,7 @@ string errormsg(DWORD const error) return message; } -} // namespace anon +} // namespace DWORD WINAPI pipeServerWrapper(void * arg) @@ -136,14 +140,14 @@ DWORD WINAPI pipeServerWrapper(void * arg) LyXComm::LyXComm(string const & pip, Server * cli, ClientCallbackfct ccb) - : pipename_(pip), client_(cli), clientcb_(ccb), stopserver_(0) + : stopserver_(0), + ready_(false), pipename_(pip), client_(cli), clientcb_(ccb), + deferred_loading_(false) { for (int i = 0; i < MAX_PIPES; ++i) { event_[i] = 0; pipe_[i].handle = INVALID_HANDLE_VALUE; } - ready_ = false; - deferred_loading_ = false; openConnection(); } @@ -171,7 +175,7 @@ bool LyXComm::pipeServer() pipe_[i].overlap.hEvent = event_[i]; pipe_[i].iobuf.erase(); - pipe_[i].handle = CreateNamedPipe(pipename.c_str(), + pipe_[i].handle = CreateNamedPipeA(pipename.c_str(), open_mode | FILE_FLAG_OVERLAPPED, PIPE_WAIT, MAX_CLIENTS, PIPE_BUFSIZE, PIPE_BUFSIZE, PIPE_TIMEOUT, NULL); @@ -198,8 +202,8 @@ bool LyXComm::pipeServer() LYXERR(Debug::LYXSERVER, "LyXComm: Connection established"); ready_ = true; outbuf_.erase(); - DWORD status; - bool success; + DWORD status = 0; + bool success = false; while (!checkStopServer()) { // Indefinitely wait for the completion of an overlapped @@ -209,7 +213,7 @@ bool LyXComm::pipeServer() // Determine which pipe instance completed the operation. i = wait - WAIT_OBJECT_0; - LASSERT(i >= 0 && i <= MAX_PIPES, /**/); + LASSERT(i <= MAX_PIPES, /**/); // Check whether we were waked up for stopping the pipe server. if (i == MAX_PIPES) @@ -355,7 +359,7 @@ bool LyXComm::pipeServer() error = GetLastError(); - if (success && error == ERROR_IO_PENDING) { + if (success && (error == ERROR_IO_PENDING || error == NO_ERROR)) { // The write operation is still pending. // We get here when a reader is started // well before a reply is ready, so delay @@ -377,6 +381,9 @@ bool LyXComm::pipeServer() if (!resetPipe(i, !success)) return false; break; + case CONNECTING_STATE: + LYXERR0("Wrong pipe state"); + break; } } @@ -482,7 +489,7 @@ bool LyXComm::resetPipe(DWORD index, bool close_handle) CloseHandle(pipe_[index].handle); pipe_[index].iobuf.erase(); - pipe_[index].handle = CreateNamedPipe(name.c_str(), + pipe_[index].handle = CreateNamedPipeA(name.c_str(), open_mode | FILE_FLAG_OVERLAPPED, PIPE_WAIT, MAX_CLIENTS, PIPE_BUFSIZE, PIPE_BUFSIZE, PIPE_TIMEOUT, NULL); @@ -520,7 +527,7 @@ void LyXComm::openConnection() } // Check whether the pipe name is being used by some other instance. - if (!stopserver_ && WaitNamedPipe(inPipeName().c_str(), 0)) { + if (!stopserver_ && WaitNamedPipeA(inPipeName().c_str(), 0)) { // Tell the running instance to load the files if (run_mode == USE_REMOTE && loadFilesInOtherInstance()) { deferred_loading_ = true; @@ -695,6 +702,7 @@ string const LyXComm::pipeName(DWORD index) const LyXComm::LyXComm(string const &, Server *, ClientCallbackfct) {} + void LyXComm::openConnection() {} @@ -716,6 +724,7 @@ void LyXComm::endPipe(int & fd, string const & filename, bool write) void LyXComm::emergencyCleanup() {} + void LyXComm::read_ready() {} @@ -726,12 +735,11 @@ void LyXComm::send(string const & msg) #else // defined (HAVE_MKFIFO) - LyXComm::LyXComm(string const & pip, Server * cli, ClientCallbackfct ccb) - : pipename_(pip), client_(cli), clientcb_(ccb) + : infd_(-1), outfd_(-1), + ready_(false), pipename_(pip), client_(cli), clientcb_(ccb), + deferred_loading_(false) { - ready_ = false; - deferred_loading_ = false; openConnection(); } @@ -856,8 +864,12 @@ int LyXComm::startPipe(string const & file, bool write) } if (!write) { - theApp()->registerSocketCallback(fd, - bind(&LyXComm::read_ready, this)); + // Make sure not to call read_ready after destruction. + weak_ptr tracker = tracker_.p(); + theApp()->registerSocketCallback(fd, [this, tracker](){ + if (!tracker.expired()) + read_ready(); + }); } return fd; @@ -877,7 +889,7 @@ void LyXComm::endPipe(int & fd, string const & filename, bool write) << '\n' << strerror(errno) << endl; } - if (FileName(filename).removeFile() < 0) { + if (!FileName(filename).removeFile()) { lyxerr << "LyXComm: Could not remove pipe " << filename << '\n' << strerror(errno) << endl; } @@ -915,7 +927,6 @@ void LyXComm::read_ready() int status; // the single = is intended here. while ((status = ::read(infd_, charbuf, charbuf_size - 1))) { - if (status > 0) { charbuf[status] = '\0'; // turn it into a c string read_buffer_ += rtrim(charbuf, "\r"); @@ -966,7 +977,8 @@ void LyXComm::send(string const & msg) LYXERR(Debug::LYXSERVER, "LyXComm: Sending '" << msg << '\''); - if (pipename_.empty()) return; + if (pipename_.empty()) + return; if (!ready_) { LYXERR0("LyXComm: Pipes are closed. Could not send " << msg); @@ -991,14 +1003,30 @@ struct Sleep : QThread } }; -} // namespace anon +} // namespace -bool LyXComm::loadFilesInOtherInstance() +bool LyXComm::loadFilesInOtherInstance() const { int pipefd; - int loaded_files = 0; FileName const pipe(inPipeName()); + + if (theFilesToLoad().empty()) { + LYXERR0("LyX is already running in another instance\n" + "and 'use single instance' is active."); + // Wait a while for the other instance to reset the connection + Sleep::millisec(200); + pipefd = ::open(pipe.toFilesystemEncoding().c_str(), O_WRONLY); + if (pipefd >= 0) { + string const cmd = "LYXCMD:pipe:window-raise\n"; + if (::write(pipefd, cmd.c_str(), cmd.length()) < 0) + LYXERR0("Cannot communicate with running instance!"); + ::close(pipefd); + } + return true; + } + + int loaded_files = 0; vector::iterator it = theFilesToLoad().begin(); while (it != theFilesToLoad().end()) { FileName fname = fileSearch(string(), os::internal_path(*it), @@ -1068,7 +1096,6 @@ Server::~Server() int compare(char const * a, char const * b, unsigned int len) { - using namespace std; return strncmp(a, b, len); } @@ -1157,7 +1184,7 @@ void Server::callback(string const & msg) << client << " said goodbye"); } else { LYXERR(Debug::LYXSERVER, - "Server: ignoring bye messge from unregistered client" << client); + "Server: ignoring bye message from unregistered client" << client); } } else { LYXERR0("Server: Undefined server command " << cmd << '.'); @@ -1173,10 +1200,10 @@ void Server::callback(string const & msg) // connect to the lyxfunc in the single GuiView we // support currently. (Lgb) - FuncRequest const fr(lyxaction.lookupFunc(cmd), arg); + FuncRequest fr(lyxaction.lookupFunc(cmd), from_utf8(arg)); + fr.setOrigin(FuncRequest::LYXSERVER); DispatchResult dr; theApp()->dispatch(fr, dr); - theApp()->dispatch(FuncRequest(LFUN_PARAGRAPH_UPDATE)); string const rval = to_utf8(dr.message()); // all commands produce an INFO or ERROR message