1 /*************************************************************************** 2 ulxr_mtrpc_server.h - a simple multithreaded rpc server 3 ------------------- 4 begin : Wed Oct 10 2003 5 copyright : (C) 2002-2007 by Ewald Arnold 6 email : ulxmlrpcpp@ewald-arnold.de 7 8 $Id: ulxr_mtrpc_server.h 1076 2007-09-02 08:07:32Z ewald-arnold $ 9 10 ***************************************************************************/ 11 12 /************************************************************************** 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU Lesser General Public License as 16 * published by the Free Software Foundation; either version 2 of the License, 17 * or (at your option) any later version. 18 * 19 * This program is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * GNU General Public License for more details. 23 * 24 * You should have received a copy of the GNU Lesser General Public License 25 * along with this program; if not, write to the Free Software 26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 27 * 28 ***************************************************************************/ 29 30 #ifndef ULXR_MTRPC_SERVER_H 31 #define ULXR_MTRPC_SERVER_H 32 33 #include <ulxmlrpcpp/ulxmlrpcpp.h> // always first header 34 35 #ifdef ULXR_MULTITHREADED 36 37 #include <vector> 38 39 #include <ulxmlrpcpp/ulxr_dispatcher.h> 40 #include <ulxmlrpcpp/ulxr_method_adder.h> 41 42 #ifdef __WIN32__ 43 #include <process.h> 44 #include <windows.h> 45 #endif 46 47 #ifdef __unix__ 48 #include <pthread.h> 49 #endif 50 51 52 namespace ulxr { 53 54 55 class Exception; 56 class Protocol; 57 58 /** A multi threaded xml rpc server. 59 * @ingroup grp_ulxr_rpc 60 */ 61 class ULXR_API_DECL0 MultiThreadRpcServer : public MethodAdder 62 { 63 public: 64 class ThreadData; 65 66 typedef void* (*ThreadLoopFunction)(ThreadData*); 67 68 /** Constructs the rpc server. 69 * @param prot communication object 70 * @param num number of simultanous threads to handle requests 71 * @param wbxml_mode true: data is sent as wbxml 72 */ 73 MultiThreadRpcServer(Protocol *prot, unsigned num, bool wbxml_mode = false); 74 75 /** Destrcuts the rpc server. 76 */ 77 virtual ~MultiThreadRpcServer(); 78 79 /** Lauch the rpc server threads which wait for requests. 80 * @return number of threads started 81 */ 82 unsigned dispatchAsync(); 83 84 /** Gets the number of installed threads. 85 * @return number of threads 86 */ 87 unsigned numThreads() const; 88 89 /** Terminates all threads. 90 * The threads only get a message and must terminate themselves. 91 * @param time planned: time in ms to wait before killing. 92 */ 93 void terminateAllThreads(unsigned time = 0); 94 95 /** Signals termination and shuts down all ports. 96 * This is a rather rude way to terminate to stop the servers 97 * @param time planned: time in ms to wait before killing. 98 */ 99 void shutdownAllThreads(unsigned time = 0); 100 101 /** Waits for all threads to complete. 102 * @param term true: signal all threads to shut down as soon as possible. 103 * @param stat true: print some statistical data to stdout. 104 */ 105 void waitAsync(bool term, bool stat = false); 106 107 /** Adds a user defined (static) method to the dispatcher. 108 * You access a remote method by sending the "official" name. Sometimes 109 * a method accepts different parameter sets (overloading in C++). 110 * In this case you add the according signature. Finally you can 111 * add a description to show the usage of this method. 112 * @param adr the pointer to the implementation of the method 113 * @param ret_signature the signature of the return value 114 * @param name the name of the method 115 * @param signature the signature of the parameters 116 * @param help short usage description 117 */ 118 void addMethod (MethodAdder::StaticMethodCall_t adr, 119 const CppString &ret_signature, 120 const CppString &name, 121 const CppString &signature, 122 const CppString &help); 123 124 /** Adds a user defined (dynamic) method to the dispatcher. 125 * You access a remote method by sending the "official" name. Sometimes 126 * a method accepts different parameter sets (overloading in C++). 127 * In this case you add the according signature. Finally you can 128 * add a description to show the usage of this method. 129 * @param wrapper the pointer to the wrapper to the method. 130 * Important: Dispatcher owns now and deletes this wrapper object! 131 * @param ret_signature the signature of the return value 132 * @param name the name of the method 133 * @param signature the signature of the parameters 134 * @param help short usage description 135 */ 136 void addMethod (MethodAdder::DynamicMethodCall_t wrapper, 137 const CppString &ret_signature, 138 const CppString &name, 139 const CppString &signature, 140 const CppString &help); 141 142 /** Adds a system internal method to the dispatcher. 143 * You access a remote method by sending the "official" name. Sometimes 144 * a method accepts different parameter sets (overloading in C++). 145 * In this case you add the according signature. Finally you can 146 * add a description to show the usage of this method. 147 * @param adr the pointer to the implementation of the method 148 * @param ret_signature the signature of the return value 149 * @param name the name of the method 150 * @param signature the signature of the parameters 151 * @param help short usage description 152 */ 153 void addMethod (MethodAdder::SystemMethodCall_t adr, 154 const CppString &ret_signature, 155 const CppString &name, 156 const CppString &signature, 157 const CppString &help); 158 159 /** Adds a user defined (static) method to the dispatcher. 160 * You access a remote method by sending the "official" name. Sometimes 161 * a method accepts different parameter sets (overloading in C++). 162 * In this case you add the according signature. Finally you can 163 * add a description to show the usage of this method. 164 * @param adr the pointer to the implementation of the method 165 * @param ret_signature the signature of the return value 166 * @param name the name of the method 167 * @param signature the signature of the parameters 168 * @param help short usage description 169 */ 170 void addMethod (MethodAdder::StaticMethodCall_t adr, 171 const Signature &ret_signature, 172 const CppString &name, 173 const Signature &signature, 174 const CppString &help); 175 176 /** Adds a user defined (dynamic) method to the dispatcher. 177 * You access a remote method by sending the "official" name. Sometimes 178 * a method accepts different parameter sets (overloading in C++). 179 * In this case you add the according signature. Finally you can 180 * add a description to show the usage of this method. 181 * @param wrapper the pointer to the wrapper to the method. 182 * Important: Dispatcher owns now and deletes this wrapper object! 183 * @param ret_signature the signature of the return value 184 * @param name the name of the method 185 * @param signature the signature of the parameters 186 * @param help short usage description 187 */ 188 void addMethod (MethodAdder::DynamicMethodCall_t wrapper, 189 const Signature &ret_signature, 190 const CppString &name, 191 const Signature &signature, 192 const CppString &help); 193 194 /** Adds a system internal method to the dispatcher. 195 * You access a remote method by sending the "official" name. Sometimes 196 * a method accepts different parameter sets (overloading in C++). 197 * In this case you add the according signature. Finally you can 198 * add a description to show the usage of this method. 199 * @param adr the pointer to the implementation of the method 200 * @param ret_signature the signature of the return value 201 * @param name the name of the method 202 * @param signature the signature of the parameters 203 * @param help short usage description 204 */ 205 void addMethod (MethodAdder::SystemMethodCall_t adr, 206 const Signature &ret_signature, 207 const CppString &name, 208 const Signature &signature, 209 const CppString &help); 210 211 /** Removes a method if available 212 * @param name method name 213 */ 214 void removeMethod(const CppString &name); 215 216 protected: 217 218 /** Forwards error that happen within threads. 219 * @param ex Exception that occured 220 */ 221 virtual void forwardThreadedError(const Exception &ex) const; 222 223 /* The threaded function that does the work. 224 * @param conn pointer to communication object 225 * @param td pointer to working data 226 */ 227 void *serverLoop(Protocol *protocol, ThreadData *td); 228 229 /** Prints some statistics about the running threads. 230 */ 231 void printStatistics() const; 232 233 /** Called when the thread is started and enters the server loop 234 */ 235 virtual void enterLoop(); 236 237 /** Called when the server loop is terminating 238 */ 239 virtual void leaveLoop(); 240 241 /** Processes a call after it has been recieved and before it is dispatched. 242 * @param call last received call 243 */ 244 virtual void preProcessCall(MethodCall &call); 245 246 /** Processes a method response before it is sent back. 247 * @param resp response to send back 248 */ 249 virtual void preProcessResponse(MethodResponse &resp); 250 251 private: 252 253 /** Helper method to start a thread. 254 * @param td pointer to thread data 255 */ 256 static void *startThread(ThreadData *td); 257 258 /** Deletes all allocated thread objects. 259 */ 260 void releaseThreads(); 261 262 typedef void *(Thread_t) (ThreadData*); 263 264 std::vector<ThreadData*> threads; 265 Dispatcher dispatcher; 266 bool wbxml_mode; 267 268 private: 269 270 // forbid them all due to internal pointers 271 MultiThreadRpcServer(const MultiThreadRpcServer&); 272 MultiThreadRpcServer& operator=(const MultiThreadRpcServer&); 273 }; 274 275 276 } // namespace ulxr 277 278 279 #endif // ULXR_MULTITHREADED 280 281 282 #endif // ULXR_MTRPC_SERVER_H 283