4 * This file is part of LyX, the document processor.
5 * Licence details can be found in the file COPYING.
7 * \author Lars Gullik Bjønnes
8 * \author Jean-Marc Lasgouttes
9 * \author Enrico Forestieri
11 * Full author contact details are available in file CREDITS.
33 /// A small utility to track the lifetime of an object.
36 Trackable() : p_(std::make_shared<int>(0)) {}
37 Trackable(Trackable const &) : Trackable() {}
38 Trackable(Trackable &&) : Trackable() {}
39 Trackable & operator=(Trackable const &) { return *this; }
40 Trackable & operator=(Trackable &&) { return *this; }
41 // This weak pointer lets you know if the parent object has been destroyed
42 std::weak_ptr<void> p() const { return p_; }
44 std::shared_ptr<void> const p_;
48 /** This class manages the pipes used for communicating with clients.
49 Usage: Initialize with pipe-filename-base, client class to receive
50 messages, and callback-function that will be called with the messages.
51 When you want to send, use "send()".
52 This class encapsulates all the dirty communication and thus provides
53 a clean string interface.
58 class LyXComm : public QObject {
61 friend DWORD WINAPI pipeServerWrapper(void *);
64 /// Max number of clients
65 enum { MAX_CLIENTS = 10 };
68 /// Max number of pipe instances
69 enum { MAX_PIPES = 2 * MAX_CLIENTS };
72 enum { PIPE_BUFSIZE = 512 };
74 /// Pipe client time-out
75 enum { PIPE_TIMEOUT = 5000 };
89 char readbuf[PIPE_BUFSIZE];
96 /** When we receive a message, we send it to a client.
97 This is one of the small things that would have been a lot
98 cleaner with a Signal/Slot thing.
100 typedef void (*ClientCallbackfct)(Server *, std::string const &);
102 /// Construct with pipe-basename and callback to receive messages
103 LyXComm(std::string const & pip, Server * cli, ClientCallbackfct ccb = 0);
106 ~LyXComm() { closeConnection(); }
108 /// clean up in emergency
109 void emergencyCleanup();
112 void send(std::string const &);
114 /// asynch ready-to-be-read notification
118 void read_ready(DWORD);
121 /// Tell whether we asked another instance of LyX to open the files
122 bool deferredLoading() const { return deferred_loading_; }
125 /// the filename of the in pipe
126 std::string const inPipeName() const;
128 /// the filename of the out pipe
129 std::string const outPipeName() const;
132 void openConnection();
135 void closeConnection();
137 /// Load files in another running instance of LyX
138 bool loadFilesInOtherInstance() const;
142 int startPipe(std::string const &, bool);
145 void endPipe(int &, std::string const &, bool);
147 /// This is -1 if not open
150 /// This is -1 if not open
153 /// The pipe server returns false when exiting due to an error
156 /// Start an overlapped connection
157 bool startPipe(DWORD);
159 /// Reset an overlapped connection
160 bool resetPipe(DWORD, bool close_handle = false);
162 /// Close event and pipe handles
165 /// Catch pipe ready-to-be-read notification
166 bool event(QEvent *);
168 /// Check whether the pipe server must be stopped
169 bool checkStopServer(DWORD timeout = 0);
171 /// The filename of a (in or out) pipe instance
172 std::string const pipeName(DWORD) const;
175 PipeInst pipe_[MAX_PIPES];
177 /// Pipe server control events
178 HANDLE event_[MAX_PIPES + 1];
183 /// Synchronize access to outbuf_
184 HANDLE outbuf_mutex_;
186 /// Windows event for stopping the pipe server
189 /// Pipe server thread handle
190 HANDLE server_thread_;
193 /// Are we up and running?
196 /// Base of pipename including path
197 std::string pipename_;
202 /// The client callback function
203 ClientCallbackfct clientcb_;
205 /// Did we defer loading of files to another instance?
206 bool deferred_loading_;
208 /// Track object's liveness
217 // Hack! This should be changed in 0.13
219 // IMO lyxserver is atypical, and for the moment the only one, non-gui
220 // bufferview. We just have to find a way to handle situations like if
221 // lyxserver is using a buffer that is being edited with a bufferview.
222 // With a common buffer list this is not a problem, maybe. (Alejandro)
224 Server(std::string const & pipes);
228 void notifyClient(std::string const &);
230 bool deferredLoadingToOtherInstance() const { return pipes_.deferredLoading(); }
232 /// whilst crashing etc.
233 void emergencyCleanup() { pipes_.emergencyCleanup(); }
235 void callback(std::string const & msg);
238 /// Names and number of current clients
240 enum { MAX_CLIENTS = 10 };
242 enum { MAX_CLIENTS = LyXComm::MAX_CLIENTS };
245 std::string clients_[MAX_CLIENTS];
252 /// Implementation is in LyX.cpp
253 Server & theServer();
255 /// Implementation is in LyX.cpp
256 extern std::vector<std::string> & theFilesToLoad();