]> git.lyx.org Git - lyx.git/blob - src/Server.h
Mark a number of coverity false positives.
[lyx.git] / src / Server.h
1 // -*- C++ -*-
2 /**
3  * \file Server.h
4  * This file is part of LyX, the document processor.
5  * Licence details can be found in the file COPYING.
6  *
7  * \author Lars Gullik Bjønnes
8  * \author Jean-Marc Lasgouttes
9  * \author Enrico Forestieri
10  *
11  * Full author contact details are available in file CREDITS.
12  */
13
14 #ifndef SERVER_H
15 #define SERVER_H
16
17 #include <boost/signals2/trackable.hpp>
18
19 #include <vector>
20 #include <sstream>
21
22 #ifdef _WIN32
23 #include <windows.h>
24 #include <QObject>
25 #include <QEvent>
26 #endif
27
28
29 namespace lyx {
30
31 class Server;
32
33
34 /** This class managed the pipes used for communicating with clients.
35  Usage: Initialize with pipe-filename-base, client class to receive
36  messages, and callback-function that will be called with the messages.
37  When you want to send, use "send()".
38  This class encapsulates all the dirty communication and thus provides
39  a clean string interface.
40  */
41 #ifndef _WIN32
42 class LyXComm : public boost::signals2::trackable {
43 #else
44 class LyXComm : public QObject {
45         Q_OBJECT
46
47         friend DWORD WINAPI pipeServerWrapper(void *);
48
49 public:
50         /// Max number of clients
51         enum { MAX_CLIENTS = 10 };
52
53 private:
54         /// Max number of pipe instances
55         enum { MAX_PIPES = 2 * MAX_CLIENTS };
56
57         /// I/O buffer size
58         enum { PIPE_BUFSIZE = 512 };
59
60         /// Pipe client time-out
61         enum { PIPE_TIMEOUT = 5000 };
62
63         /// Pipe states
64         enum PipeState {
65                 CONNECTING_STATE,
66                 READING_STATE,
67                 WRITING_STATE
68         };
69
70         /// Pipe instances
71         typedef struct {
72                 OVERLAPPED overlap;
73                 HANDLE handle;
74                 std::string iobuf;
75                 char readbuf[PIPE_BUFSIZE];
76                 DWORD nbytes;
77                 PipeState state;
78                 bool pending_io;
79         } PipeInst;
80 #endif
81 public:
82         /** When we receive a message, we send it to a client.
83           This is one of the small things that would have been a lot
84           cleaner with a Signal/Slot thing.
85          */
86         typedef void (*ClientCallbackfct)(Server *, std::string const &);
87
88         /// Construct with pipe-basename and callback to receive messages
89         LyXComm(std::string const & pip, Server * cli, ClientCallbackfct ccb = 0);
90
91         ///
92         ~LyXComm() { closeConnection(); }
93
94         /// clean up in emergency
95         void emergencyCleanup();
96
97         /// Send message
98         void send(std::string const &);
99
100         /// asynch ready-to-be-read notification
101 #ifndef _WIN32
102         void read_ready();
103 #else
104         void read_ready(DWORD);
105 #endif
106
107         /// Tell whether we asked another instance of LyX to open the files
108         bool deferredLoading() { return deferred_loading_; }
109
110 private:
111         /// the filename of the in pipe
112         std::string const inPipeName() const;
113
114         /// the filename of the out pipe
115         std::string const outPipeName() const;
116
117         /// Open pipes
118         void openConnection();
119
120         /// Close pipes
121         void closeConnection();
122
123         /// Load files in another running instance of LyX
124         bool loadFilesInOtherInstance();
125
126 #ifndef _WIN32
127         /// start a pipe
128         int startPipe(std::string const &, bool);
129
130         /// finish a pipe
131         void endPipe(int &, std::string const &, bool);
132
133         /// This is -1 if not open
134         int infd_;
135
136         /// This is -1 if not open
137         int outfd_;
138 #else
139         /// The pipe server returns false when exiting due to an error
140         bool pipeServer();
141
142         /// Start an overlapped connection
143         bool startPipe(DWORD);
144
145         /// Reset an overlapped connection
146         bool resetPipe(DWORD, bool close_handle = false);
147
148         /// Close event and pipe handles
149         void closeHandles();
150
151         /// Catch pipe ready-to-be-read notification
152         bool event(QEvent *);
153
154         /// Check whether the pipe server must be stopped
155         bool checkStopServer(DWORD timeout = 0);
156
157         /// The filename of a (in or out) pipe instance
158         std::string const pipeName(DWORD) const;
159
160         /// Pipe instances
161         PipeInst pipe_[MAX_PIPES];
162
163         /// Pipe server control events
164         HANDLE event_[MAX_PIPES + 1];
165
166         /// Reply buffer
167         std::string outbuf_;
168
169         /// Synchronize access to outbuf_
170         HANDLE outbuf_mutex_;
171
172         /// Windows event for stopping the pipe server
173         HANDLE stopserver_;
174
175         /// Pipe server thread handle
176         HANDLE server_thread_;
177 #endif
178
179         /// Are we up and running?
180         bool ready_;
181
182         /// Base of pipename including path
183         std::string pipename_;
184
185         /// The client
186         Server * client_;
187
188         /// The client callback function
189         ClientCallbackfct clientcb_;
190
191         /// Did we defer loading of files to another instance?
192         bool deferred_loading_;
193 };
194
195
196 ///
197 class Server {
198 public:
199         // FIXME IN 0.13
200         // Hack! This should be changed in 0.13
201
202         // IMO lyxserver is atypical, and for the moment the only one, non-gui
203         // bufferview. We just have to find a way to handle situations like if
204         // lyxserver is using a buffer that is being edited with a bufferview.
205         // With a common buffer list this is not a problem, maybe. (Alejandro)
206         ///
207         Server(std::string const & pip);
208         ///
209         ~Server();
210         ///
211         void notifyClient(std::string const &);
212         ///
213         bool deferredLoadingToOtherInstance() { return pipes_.deferredLoading(); }
214
215         /// whilst crashing etc.
216         void emergencyCleanup() { pipes_.emergencyCleanup(); }
217         ///
218         void callback(std::string const & msg);
219
220 private:
221         /// Names and number of current clients
222 #ifndef _WIN32
223         enum { MAX_CLIENTS = 10 };
224 #else
225         enum { MAX_CLIENTS = LyXComm::MAX_CLIENTS };
226 #endif
227         ///
228         std::string clients_[MAX_CLIENTS];
229         ///
230         int numclients_;
231         ///
232         LyXComm pipes_;
233 };
234
235 /// Implementation is in LyX.cpp
236 Server & theServer();
237
238 /// Implementation is in LyX.cpp
239 extern std::vector<std::string> & theFilesToLoad();
240
241
242 } // namespace lyx
243
244 #endif // SERVER_H