X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2FServer.h;h=4fc11faf957359e98c762553bba2a00dde7d415c;hb=cc6c86ff3b7d10bc6a0ea286020f63a75fef9608;hp=31e7c4b7c4307c37cd13ca71c361fed164196970;hpb=fc978618030ebfaa4b624764330a0d7be4bd23e8;p=lyx.git diff --git a/src/Server.h b/src/Server.h index 31e7c4b7c4..4fc11faf95 100644 --- a/src/Server.h +++ b/src/Server.h @@ -25,7 +25,6 @@ namespace lyx { -class LyXFunc; class Server; @@ -41,6 +40,40 @@ class LyXComm : public boost::signals::trackable { #else class LyXComm : public QObject { Q_OBJECT + + friend DWORD WINAPI pipeServerWrapper(void *); + +public: + /// Max number of clients + enum { MAX_CLIENTS = 10 }; + +private: + /// Max number of pipe instances + enum { MAX_PIPES = 2 * MAX_CLIENTS }; + + /// I/O buffer size + enum { PIPE_BUFSIZE = 512 }; + + /// Pipe client time-out + enum { PIPE_TIMEOUT = 5000 }; + + /// Pipe states + enum PipeState { + CONNECTING_STATE, + READING_STATE, + WRITING_STATE + }; + + /// Pipe instances + typedef struct { + OVERLAPPED overlap; + HANDLE handle; + std::string iobuf; + char readbuf[PIPE_BUFSIZE]; + DWORD nbytes; + PipeState state; + bool pending_io; + } PipeInst; #endif public: /** When we receive a message, we send it to a client. @@ -65,12 +98,12 @@ public: #ifndef _WIN32 void read_ready(); #else - void read_ready(HANDLE); - - /// The pipe server - void pipeServer(); + void read_ready(DWORD); #endif + /// Tell whether we asked another instance of LyX to open the files + bool deferredLoading() { return deferred_loading_; } + private: /// the filename of the in pipe std::string const inPipeName() const; @@ -84,6 +117,9 @@ private: /// Close pipes void closeConnection(); + /// Load files in another running instance of LyX + bool loadFilesInOtherInstance(); + #ifndef _WIN32 /// start a pipe int startPipe(std::string const &, bool); @@ -97,7 +133,44 @@ private: /// This is -1 if not open int outfd_; #else - HANDLE outpipe_; + /// The pipe server returns false when exiting due to an error + bool pipeServer(); + + /// Start an overlapped connection + bool startPipe(DWORD); + + /// Reset an overlapped connection + bool resetPipe(DWORD, bool close_handle = false); + + /// Close event and pipe handles + void closeHandles(); + + /// Catch pipe ready-to-be-read notification + bool event(QEvent *); + + /// Check whether the pipe server must be stopped + bool checkStopServer(DWORD timeout = 0); + + /// The filename of a (in or out) pipe instance + std::string const pipeName(DWORD) const; + + /// Pipe instances + PipeInst pipe_[MAX_PIPES]; + + /// Pipe server control events + HANDLE event_[MAX_PIPES + 1]; + + /// Reply buffer + std::string outbuf_; + + /// Synchronize access to outbuf_ + HANDLE outbuf_mutex_; + + /// Windows event for stopping the pipe server + HANDLE stopserver_; + + /// Pipe server thread handle + HANDLE server_thread_; #endif /// Are we up and running? @@ -112,16 +185,8 @@ private: /// The client callback function ClientCallbackfct clientcb_; -#ifdef _WIN32 - /// Catch pipe ready-to-be-read notification - bool event(QEvent *); - - /// Check whether the pipe server must be stopped - BOOL checkStopServerEvent(); - - /// Windows event for stopping the pipe server - HANDLE stopserver_; -#endif + /// Did we defer loading of files to another instance? + bool deferred_loading_; }; @@ -131,19 +196,18 @@ public: // FIXME IN 0.13 // Hack! This should be changed in 0.13 - // The lyx server should not take an argument "LyXFunc" but this is - // how it will be done for 0.12. In 0.13 we must write a non-gui - // bufferview. // IMO lyxserver is atypical, and for the moment the only one, non-gui // bufferview. We just have to find a way to handle situations like if // lyxserver is using a buffer that is being edited with a bufferview. // With a common buffer list this is not a problem, maybe. (Alejandro) /// - Server(LyXFunc * f, std::string const & pip); + Server(std::string const & pip); /// ~Server(); /// void notifyClient(std::string const &); + /// + bool deferredLoadingToOtherInstance() { return pipes_.deferredLoading(); } /// whilst crashing etc. void emergencyCleanup() { pipes_.emergencyCleanup(); } @@ -152,19 +216,24 @@ public: private: /// Names and number of current clients +#ifndef _WIN32 enum { MAX_CLIENTS = 10 }; +#else + enum { MAX_CLIENTS = LyXComm::MAX_CLIENTS }; +#endif /// std::string clients_[MAX_CLIENTS]; /// int numclients_; /// - LyXFunc * func_; - /// LyXComm pipes_; }; /// Implementation is in LyX.cpp -extern Server & theServer(); +Server & theServer(); + +/// Implementation is in LyX.cpp +extern std::vector & theFilesToLoad(); } // namespace lyx