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>
32 /** This class managed the pipes used for communicating with clients.
33 Usage: Initialize with pipe-filename-base, client class to receive
34 messages, and callback-function that will be called with the messages.
35 When you want to send, use "send()".
36 This class encapsulates all the dirty communication and thus provides
37 a clean string interface.
40 class LyXComm : public boost::signals::trackable {
42 class LyXComm : public QObject {
45 friend DWORD WINAPI pipeServerWrapper(void *);
48 /// Max number of clients
49 enum { MAX_CLIENTS = 10 };
52 /// Max number of pipe instances
53 enum { MAX_PIPES = 2 * MAX_CLIENTS };
56 enum { PIPE_BUFSIZE = 512 };
58 /// Pipe client time-out
59 enum { PIPE_TIMEOUT = 5000 };
73 char readbuf[PIPE_BUFSIZE];
80 /** When we receive a message, we send it to a client.
81 This is one of the small things that would have been a lot
82 cleaner with a Signal/Slot thing.
84 typedef void (*ClientCallbackfct)(Server *, std::string const &);
86 /// Construct with pipe-basename and callback to receive messages
87 LyXComm(std::string const & pip, Server * cli, ClientCallbackfct ccb = 0);
90 ~LyXComm() { closeConnection(); }
92 /// clean up in emergency
93 void emergencyCleanup();
96 void send(std::string const &);
98 /// asynch ready-to-be-read notification
102 void read_ready(DWORD);
106 /// the filename of the in pipe
107 std::string const inPipeName() const;
109 /// the filename of the out pipe
110 std::string const outPipeName() const;
113 void openConnection();
116 void closeConnection();
120 int startPipe(std::string const &, bool);
123 void endPipe(int &, std::string const &, bool);
125 /// This is -1 if not open
128 /// This is -1 if not open
131 /// The pipe server returns false when exiting due to an error
134 /// Start an overlapped connection
135 bool startPipe(DWORD);
137 /// Reset an overlapped connection
138 bool resetPipe(DWORD, bool close_handle = false);
140 /// Close event and pipe handles
143 /// Catch pipe ready-to-be-read notification
144 bool event(QEvent *);
146 /// Check whether the pipe server must be stopped
147 bool checkStopServer();
149 /// The filename of a (in or out) pipe instance
150 std::string const pipeName(DWORD) const;
153 PipeInst pipe_[MAX_PIPES];
155 /// Pipe server control events
156 HANDLE event_[MAX_PIPES + 1];
161 /// Synchronize access to outbuf_
162 HANDLE outbuf_mutex_;
164 /// Windows event for stopping the pipe server
167 /// Pipe server thread handle
168 HANDLE server_thread_;
171 /// Are we up and running?
174 /// Base of pipename including path
175 std::string pipename_;
180 /// The client callback function
181 ClientCallbackfct clientcb_;
189 // Hack! This should be changed in 0.13
191 // The lyx server should not take an argument "LyXFunc" but this is
192 // how it will be done for 0.12. In 0.13 we must write a non-gui
194 // IMO lyxserver is atypical, and for the moment the only one, non-gui
195 // bufferview. We just have to find a way to handle situations like if
196 // lyxserver is using a buffer that is being edited with a bufferview.
197 // With a common buffer list this is not a problem, maybe. (Alejandro)
199 Server(LyXFunc * f, std::string const & pip);
203 void notifyClient(std::string const &);
205 /// whilst crashing etc.
206 void emergencyCleanup() { pipes_.emergencyCleanup(); }
208 void callback(std::string const & msg);
211 /// Names and number of current clients
213 enum { MAX_CLIENTS = 10 };
215 enum { MAX_CLIENTS = LyXComm::MAX_CLIENTS };
218 std::string clients_[MAX_CLIENTS];
227 /// Implementation is in LyX.cpp
228 extern Server & theServer();