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.
17 #include <boost/signals/trackable.hpp>
31 /** This class managed the pipes used for communicating with clients.
32 Usage: Initialize with pipe-filename-base, client class to receive
33 messages, and callback-function that will be called with the messages.
34 When you want to send, use "send()".
35 This class encapsulates all the dirty communication and thus provides
36 a clean string interface.
39 class LyXComm : public boost::signals::trackable {
41 class LyXComm : public QObject {
44 friend DWORD WINAPI pipeServerWrapper(void *);
47 /// Max number of clients
48 enum { MAX_CLIENTS = 10 };
51 /// Max number of pipe instances
52 enum { MAX_PIPES = 2 * MAX_CLIENTS };
55 enum { PIPE_BUFSIZE = 512 };
57 /// Pipe client time-out
58 enum { PIPE_TIMEOUT = 5000 };
72 char readbuf[PIPE_BUFSIZE];
79 /** When we receive a message, we send it to a client.
80 This is one of the small things that would have been a lot
81 cleaner with a Signal/Slot thing.
83 typedef void (*ClientCallbackfct)(Server *, std::string const &);
85 /// Construct with pipe-basename and callback to receive messages
86 LyXComm(std::string const & pip, Server * cli, ClientCallbackfct ccb = 0);
89 ~LyXComm() { closeConnection(); }
91 /// clean up in emergency
92 void emergencyCleanup();
95 void send(std::string const &);
97 /// asynch ready-to-be-read notification
101 void read_ready(DWORD);
105 /// the filename of the in pipe
106 std::string const inPipeName() const;
108 /// the filename of the out pipe
109 std::string const outPipeName() const;
112 void openConnection();
115 void closeConnection();
119 int startPipe(std::string const &, bool);
122 void endPipe(int &, std::string const &, bool);
124 /// This is -1 if not open
127 /// This is -1 if not open
130 /// The pipe server returns false when exiting due to an error
133 /// Start an overlapped connection
134 bool startPipe(DWORD);
136 /// Reset an overlapped connection
137 bool resetPipe(DWORD, bool close_handle = false);
139 /// Close event and pipe handles
142 /// Catch pipe ready-to-be-read notification
143 bool event(QEvent *);
145 /// Check whether the pipe server must be stopped
146 bool checkStopServer(DWORD timeout = 0);
148 /// The filename of a (in or out) pipe instance
149 std::string const pipeName(DWORD) const;
152 PipeInst pipe_[MAX_PIPES];
154 /// Pipe server control events
155 HANDLE event_[MAX_PIPES + 1];
160 /// Synchronize access to outbuf_
161 HANDLE outbuf_mutex_;
163 /// Windows event for stopping the pipe server
166 /// Pipe server thread handle
167 HANDLE server_thread_;
170 /// Are we up and running?
173 /// Base of pipename including path
174 std::string pipename_;
179 /// The client callback function
180 ClientCallbackfct clientcb_;
188 // Hack! This should be changed in 0.13
190 // IMO lyxserver is atypical, and for the moment the only one, non-gui
191 // bufferview. We just have to find a way to handle situations like if
192 // lyxserver is using a buffer that is being edited with a bufferview.
193 // With a common buffer list this is not a problem, maybe. (Alejandro)
195 Server(std::string const & pip);
199 void notifyClient(std::string const &);
201 /// whilst crashing etc.
202 void emergencyCleanup() { pipes_.emergencyCleanup(); }
204 void callback(std::string const & msg);
207 /// Names and number of current clients
209 enum { MAX_CLIENTS = 10 };
211 enum { MAX_CLIENTS = LyXComm::MAX_CLIENTS };
214 std::string clients_[MAX_CLIENTS];
221 /// Implementation is in LyX.cpp
222 Server & theServer();