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.
32 /// A small utility to track the lifetime of an object.
35 Trackable() : p_(std::make_shared<int>(0)) {}
36 Trackable(Trackable const &) : Trackable() {}
37 Trackable(Trackable &&) : Trackable() {}
38 Trackable & operator=(Trackable const &) { return *this; }
39 Trackable & operator=(Trackable &&) { return *this; }
40 // This weak pointer lets you know if the parent object has been destroyed
41 std::weak_ptr<void> p() const { return p_; }
43 std::shared_ptr<void> const p_;
47 /** This class manages the pipes used for communicating with clients.
48 Usage: Initialize with pipe-filename-base, client class to receive
49 messages, and callback-function that will be called with the messages.
50 When you want to send, use "send()".
51 This class encapsulates all the dirty communication and thus provides
52 a clean string interface.
57 class LyXComm : public QObject {
60 friend DWORD WINAPI pipeServerWrapper(void *);
63 /// Max number of clients
64 enum { MAX_CLIENTS = 10 };
67 /// Max number of pipe instances
68 enum { MAX_PIPES = 2 * MAX_CLIENTS };
71 enum { PIPE_BUFSIZE = 512 };
73 /// Pipe client time-out
74 enum { PIPE_TIMEOUT = 5000 };
88 char readbuf[PIPE_BUFSIZE];
95 /** When we receive a message, we send it to a client.
96 This is one of the small things that would have been a lot
97 cleaner with a Signal/Slot thing.
99 typedef void (*ClientCallbackfct)(Server *, std::string const &);
101 /// Construct with pipe-basename and callback to receive messages
102 LyXComm(std::string const & pip, Server * cli, ClientCallbackfct ccb = 0);
105 ~LyXComm() { closeConnection(); }
107 /// clean up in emergency
108 void emergencyCleanup();
111 void send(std::string const &);
113 /// asynch ready-to-be-read notification
117 void read_ready(DWORD);
120 /// Tell whether we asked another instance of LyX to open the files
121 bool deferredLoading() const { return deferred_loading_; }
124 /// the filename of the in pipe
125 std::string const inPipeName() const;
127 /// the filename of the out pipe
128 std::string const outPipeName() const;
131 void openConnection();
134 void closeConnection();
136 /// Load files in another running instance of LyX
137 bool loadFilesInOtherInstance() const;
141 int startPipe(std::string const &, bool);
144 void endPipe(int &, std::string const &, bool);
146 /// This is -1 if not open
149 /// This is -1 if not open
152 /// The pipe server returns false when exiting due to an error
155 /// Start an overlapped connection
156 bool startPipe(DWORD);
158 /// Reset an overlapped connection
159 bool resetPipe(DWORD, bool close_handle = false);
161 /// Close event and pipe handles
164 /// Catch pipe ready-to-be-read notification
165 bool event(QEvent *);
167 /// Check whether the pipe server must be stopped
168 bool checkStopServer(DWORD timeout = 0);
170 /// The filename of a (in or out) pipe instance
171 std::string const pipeName(DWORD) const;
174 PipeInst pipe_[MAX_PIPES];
176 /// Pipe server control events
177 HANDLE event_[MAX_PIPES + 1];
182 /// Synchronize access to outbuf_
183 HANDLE outbuf_mutex_;
185 /// Windows event for stopping the pipe server
188 /// Pipe server thread handle
189 HANDLE server_thread_;
192 /// Are we up and running?
195 /// Base of pipename including path
196 std::string pipename_;
201 /// The client callback function
202 ClientCallbackfct clientcb_;
204 /// Did we defer loading of files to another instance?
205 bool deferred_loading_;
207 /// Track object's liveness
216 // Hack! This should be changed in 0.13
218 // IMO lyxserver is atypical, and for the moment the only one, non-gui
219 // bufferview. We just have to find a way to handle situations like if
220 // lyxserver is using a buffer that is being edited with a bufferview.
221 // With a common buffer list this is not a problem, maybe. (Alejandro)
223 Server(std::string const & pipes);
227 void notifyClient(std::string const &);
229 bool deferredLoadingToOtherInstance() const { return pipes_.deferredLoading(); }
231 /// whilst crashing etc.
232 void emergencyCleanup() { pipes_.emergencyCleanup(); }
234 void callback(std::string const & msg);
237 /// Names and number of current clients
239 enum { MAX_CLIENTS = 10 };
241 enum { MAX_CLIENTS = LyXComm::MAX_CLIENTS };
244 std::string clients_[MAX_CLIENTS];
251 /// Implementation is in LyX.cpp
252 Server & theServer();
254 /// Implementation is in LyX.cpp
255 extern std::vector<std::string> & theFilesToLoad();