1 /* 2 Copyright (C) 2008 Grame 3 4 This program is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 2 of the License, or 7 (at your option) any later version. 8 9 This program is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with this program; if not, write to the Free Software 16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 18 */ 19 20 #ifndef __JackLockedEngine__ 21 #define __JackLockedEngine__ 22 23 #include "JackEngine.h" 24 #include "JackMutex.h" 25 #include "JackTools.h" 26 #include "JackException.h" 27 28 namespace Jack 29 { 30 31 #define TRY_CALL \ 32 try { \ 33 34 /* 35 See : http://groups.google.com/group/comp.programming.threads/browse_thread/thread/652bcf186fbbf697/f63757846514e5e5 36 37 catch (...) { 38 // Assuming thread cancellation, must rethrow 39 throw; 40 } 41 */ 42 43 #define CATCH_EXCEPTION_RETURN \ 44 } catch (std::bad_alloc& e) { \ 45 jack_error("Memory allocation error..."); \ 46 return -1; \ 47 } catch (...) { \ 48 jack_error("Unknown error..."); \ 49 throw; \ 50 } \ 51 52 #define CATCH_CLOSE_EXCEPTION_RETURN \ 53 } catch (std::bad_alloc& e) { \ 54 jack_error("Memory allocation error..."); \ 55 return -1; \ 56 } catch (JackTemporaryException& e) { \ 57 jack_error("JackTemporaryException : now quits..."); \ 58 JackTools::KillServer(); \ 59 return 0; \ 60 } catch (...) { \ 61 jack_error("Unknown error..."); \ 62 throw; \ 63 } 64 65 #define CATCH_EXCEPTION \ 66 } catch (std::bad_alloc& e) { \ 67 jack_error("Memory allocation error..."); \ 68 } catch (...) { \ 69 jack_error("Unknown error..."); \ 70 throw; \ 71 } \ 72 73 74 /*! 75 \brief Locked Engine, access to methods is serialized using a mutex. 76 */ 77 78 class SERVER_EXPORT JackLockedEngine 79 { 80 private: 81 82 JackEngine fEngine; 83 84 public: 85 JackLockedEngine(JackGraphManager * manager,JackSynchro * table,JackEngineControl * controler,char self_connect_mode)86 JackLockedEngine(JackGraphManager* manager, JackSynchro* table, JackEngineControl* controler, char self_connect_mode): 87 fEngine(manager, table, controler, self_connect_mode) 88 {} ~JackLockedEngine()89 ~JackLockedEngine() 90 {} 91 Lock()92 bool Lock() { return fEngine.Lock(); } Unlock()93 bool Unlock() { return fEngine.Unlock(); } Trylock()94 bool Trylock() { return fEngine.Trylock(); } 95 Open()96 int Open() 97 { 98 // No lock needed 99 TRY_CALL 100 return fEngine.Open(); 101 CATCH_EXCEPTION_RETURN 102 } Close()103 int Close() 104 { 105 // No lock needed 106 TRY_CALL 107 return fEngine.Close(); 108 CATCH_EXCEPTION_RETURN 109 } 110 111 // Client management ClientCheck(const char * name,jack_uuid_t uuid,char * name_res,int protocol,int options,int * status)112 int ClientCheck(const char* name, jack_uuid_t uuid, char* name_res, int protocol, int options, int* status) 113 { 114 TRY_CALL 115 JackLock lock(&fEngine); 116 return fEngine.ClientCheck(name, uuid, name_res, protocol, options, status); 117 CATCH_EXCEPTION_RETURN 118 } ClientExternalOpen(const char * name,int pid,jack_uuid_t uuid,int * ref,int * shared_engine,int * shared_client,int * shared_graph_manager)119 int ClientExternalOpen(const char* name, int pid, jack_uuid_t uuid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager) 120 { 121 TRY_CALL 122 JackLock lock(&fEngine); 123 return fEngine.ClientExternalOpen(name, pid, uuid, ref, shared_engine, shared_client, shared_graph_manager); 124 CATCH_EXCEPTION_RETURN 125 } ClientInternalOpen(const char * name,int * ref,JackEngineControl ** shared_engine,JackGraphManager ** shared_manager,JackClientInterface * client,bool wait)126 int ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, bool wait) 127 { 128 TRY_CALL 129 JackLock lock(&fEngine); 130 return fEngine.ClientInternalOpen(name, ref, shared_engine, shared_manager, client, wait); 131 CATCH_EXCEPTION_RETURN 132 } 133 ClientExternalClose(int refnum)134 int ClientExternalClose(int refnum) 135 { 136 TRY_CALL 137 JackLock lock(&fEngine); 138 return (fEngine.CheckClient(refnum)) ? fEngine.ClientExternalClose(refnum) : -1; 139 CATCH_CLOSE_EXCEPTION_RETURN 140 } ClientInternalClose(int refnum,bool wait)141 int ClientInternalClose(int refnum, bool wait) 142 { 143 TRY_CALL 144 JackLock lock(&fEngine); 145 return (fEngine.CheckClient(refnum)) ? fEngine.ClientInternalClose(refnum, wait) : -1; 146 CATCH_CLOSE_EXCEPTION_RETURN 147 } 148 ClientActivate(int refnum,bool is_real_time)149 int ClientActivate(int refnum, bool is_real_time) 150 { 151 TRY_CALL 152 JackLock lock(&fEngine); 153 return (fEngine.CheckClient(refnum)) ? fEngine.ClientActivate(refnum, is_real_time) : -1; 154 CATCH_EXCEPTION_RETURN 155 } ClientDeactivate(int refnum)156 int ClientDeactivate(int refnum) 157 { 158 TRY_CALL 159 JackLock lock(&fEngine); 160 return (fEngine.CheckClient(refnum)) ? fEngine.ClientDeactivate(refnum) : -1; 161 CATCH_EXCEPTION_RETURN 162 } ClientKill(int refnum)163 void ClientKill(int refnum) 164 { 165 TRY_CALL 166 JackLock lock(&fEngine); 167 fEngine.ClientKill(refnum); 168 CATCH_EXCEPTION 169 } 170 171 // Internal client management GetInternalClientName(int int_ref,char * name_res)172 int GetInternalClientName(int int_ref, char* name_res) 173 { 174 TRY_CALL 175 JackLock lock(&fEngine); 176 return fEngine.GetInternalClientName(int_ref, name_res); 177 CATCH_EXCEPTION_RETURN 178 } InternalClientHandle(const char * client_name,int * status,int * int_ref)179 int InternalClientHandle(const char* client_name, int* status, int* int_ref) 180 { 181 TRY_CALL 182 JackLock lock(&fEngine); 183 return fEngine.InternalClientHandle(client_name, status, int_ref); 184 CATCH_EXCEPTION_RETURN 185 } InternalClientUnload(int refnum,int * status)186 int InternalClientUnload(int refnum, int* status) 187 { 188 TRY_CALL 189 JackLock lock(&fEngine); 190 // Client is tested in fEngine.InternalClientUnload 191 return fEngine.InternalClientUnload(refnum, status); 192 CATCH_EXCEPTION_RETURN 193 } 194 195 // Port management PortRegister(int refnum,const char * name,const char * type,unsigned int flags,unsigned int buffer_size,jack_port_id_t * port)196 int PortRegister(int refnum, const char* name, const char *type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port) 197 { 198 TRY_CALL 199 JackLock lock(&fEngine); 200 return (fEngine.CheckClient(refnum)) ? fEngine.PortRegister(refnum, name, type, flags, buffer_size, port) : -1; 201 CATCH_EXCEPTION_RETURN 202 } PortUnRegister(int refnum,jack_port_id_t port)203 int PortUnRegister(int refnum, jack_port_id_t port) 204 { 205 TRY_CALL 206 JackLock lock(&fEngine); 207 return (fEngine.CheckClient(refnum)) ? fEngine.PortUnRegister(refnum, port) : -1; 208 CATCH_EXCEPTION_RETURN 209 } 210 PortConnect(int refnum,const char * src,const char * dst)211 int PortConnect(int refnum, const char* src, const char* dst) 212 { 213 TRY_CALL 214 JackLock lock(&fEngine); 215 return (fEngine.CheckClient(refnum)) ? fEngine.PortConnect(refnum, src, dst) : -1; 216 CATCH_EXCEPTION_RETURN 217 } PortDisconnect(int refnum,const char * src,const char * dst)218 int PortDisconnect(int refnum, const char* src, const char* dst) 219 { 220 TRY_CALL 221 JackLock lock(&fEngine); 222 return (fEngine.CheckClient(refnum)) ? fEngine.PortDisconnect(refnum, src, dst) : -1; 223 CATCH_EXCEPTION_RETURN 224 } 225 PortConnect(int refnum,jack_port_id_t src,jack_port_id_t dst)226 int PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst) 227 { 228 TRY_CALL 229 JackLock lock(&fEngine); 230 return (fEngine.CheckClient(refnum)) ? fEngine.PortConnect(refnum, src, dst) : -1; 231 CATCH_EXCEPTION_RETURN 232 } PortDisconnect(int refnum,jack_port_id_t src,jack_port_id_t dst)233 int PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst) 234 { 235 TRY_CALL 236 JackLock lock(&fEngine); 237 return (fEngine.CheckClient(refnum)) ? fEngine.PortDisconnect(refnum, src, dst) : -1; 238 CATCH_EXCEPTION_RETURN 239 } 240 PortRename(int refnum,jack_port_id_t port,const char * name)241 int PortRename(int refnum, jack_port_id_t port, const char* name) 242 { 243 TRY_CALL 244 JackLock lock(&fEngine); 245 return (fEngine.CheckClient(refnum)) ? fEngine.PortRename(refnum, port, name) : -1; 246 CATCH_EXCEPTION_RETURN 247 } 248 PortSetDefaultMetadata(int refnum,jack_port_id_t port,const char * pretty_name)249 int PortSetDefaultMetadata(int refnum, jack_port_id_t port, const char* pretty_name) 250 { 251 TRY_CALL 252 JackLock lock(&fEngine); 253 return (fEngine.CheckClient(refnum)) ? fEngine.PortSetDefaultMetadata(port, pretty_name) : -1; 254 CATCH_EXCEPTION_RETURN 255 } 256 ComputeTotalLatencies()257 int ComputeTotalLatencies() 258 { 259 TRY_CALL 260 JackLock lock(&fEngine); 261 return fEngine.ComputeTotalLatencies(); 262 CATCH_EXCEPTION_RETURN 263 } 264 265 // Graph Process(jack_time_t cur_cycle_begin,jack_time_t prev_cycle_end)266 bool Process(jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end) 267 { 268 // RT : no lock 269 return fEngine.Process(cur_cycle_begin, prev_cycle_end); 270 } 271 272 // Notifications NotifyDriverXRun()273 void NotifyDriverXRun() 274 { 275 // Coming from the driver in RT : no lock 276 fEngine.NotifyDriverXRun(); 277 } 278 NotifyClientXRun(int refnum)279 void NotifyClientXRun(int refnum) 280 { 281 TRY_CALL 282 JackLock lock(&fEngine); 283 fEngine.NotifyClientXRun(refnum); 284 CATCH_EXCEPTION 285 } 286 NotifyGraphReorder()287 void NotifyGraphReorder() 288 { 289 TRY_CALL 290 JackLock lock(&fEngine); 291 fEngine.NotifyGraphReorder(); 292 CATCH_EXCEPTION 293 } 294 NotifyBufferSize(jack_nframes_t buffer_size)295 void NotifyBufferSize(jack_nframes_t buffer_size) 296 { 297 TRY_CALL 298 JackLock lock(&fEngine); 299 fEngine.NotifyBufferSize(buffer_size); 300 CATCH_EXCEPTION 301 } NotifySampleRate(jack_nframes_t sample_rate)302 void NotifySampleRate(jack_nframes_t sample_rate) 303 { 304 TRY_CALL 305 JackLock lock(&fEngine); 306 fEngine.NotifySampleRate(sample_rate); 307 CATCH_EXCEPTION 308 } NotifyFreewheel(bool onoff)309 void NotifyFreewheel(bool onoff) 310 { 311 TRY_CALL 312 JackLock lock(&fEngine); 313 fEngine.NotifyFreewheel(onoff); 314 CATCH_EXCEPTION 315 } 316 NotifyFailure(int code,const char * reason)317 void NotifyFailure(int code, const char* reason) 318 { 319 TRY_CALL 320 JackLock lock(&fEngine); 321 fEngine.NotifyFailure(code, reason); 322 CATCH_EXCEPTION 323 } 324 GetClientPID(const char * name)325 int GetClientPID(const char* name) 326 { 327 TRY_CALL 328 JackLock lock(&fEngine); 329 return fEngine.GetClientPID(name); 330 CATCH_EXCEPTION_RETURN 331 } 332 GetClientRefNum(const char * name)333 int GetClientRefNum(const char* name) 334 { 335 TRY_CALL 336 JackLock lock(&fEngine); 337 return fEngine.GetClientRefNum(name); 338 CATCH_EXCEPTION_RETURN 339 } 340 NotifyQuit()341 void NotifyQuit() 342 { 343 // No lock needed 344 TRY_CALL 345 return fEngine.NotifyQuit(); 346 CATCH_EXCEPTION 347 } 348 SessionNotify(int refnum,const char * target,jack_session_event_type_t type,const char * path,detail::JackChannelTransactionInterface * socket,JackSessionNotifyResult ** result)349 void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, detail::JackChannelTransactionInterface *socket, JackSessionNotifyResult** result) 350 { 351 TRY_CALL 352 JackLock lock(&fEngine); 353 fEngine.SessionNotify(refnum, target, type, path, socket, result); 354 CATCH_EXCEPTION 355 } 356 SessionReply(int refnum)357 int SessionReply(int refnum) 358 { 359 TRY_CALL 360 JackLock lock(&fEngine); 361 return fEngine.SessionReply(refnum); 362 CATCH_EXCEPTION_RETURN 363 } 364 GetUUIDForClientName(const char * client_name,char * uuid_res)365 int GetUUIDForClientName(const char *client_name, char *uuid_res) 366 { 367 TRY_CALL 368 JackLock lock(&fEngine); 369 return fEngine.GetUUIDForClientName(client_name, uuid_res); 370 CATCH_EXCEPTION_RETURN 371 } 372 GetClientNameForUUID(const char * uuid,char * name_res)373 int GetClientNameForUUID(const char *uuid, char *name_res) 374 { 375 TRY_CALL 376 JackLock lock(&fEngine); 377 return fEngine.GetClientNameForUUID(uuid, name_res); 378 CATCH_EXCEPTION_RETURN 379 } ReserveClientName(const char * name,const char * uuid)380 int ReserveClientName(const char *name, const char *uuid) 381 { 382 TRY_CALL 383 JackLock lock(&fEngine); 384 return fEngine.ReserveClientName(name, uuid); 385 CATCH_EXCEPTION_RETURN 386 } 387 ClientHasSessionCallback(const char * name)388 int ClientHasSessionCallback(const char *name) 389 { 390 TRY_CALL 391 JackLock lock(&fEngine); 392 return fEngine.ClientHasSessionCallback(name); 393 CATCH_EXCEPTION_RETURN 394 } 395 PropertyChangeNotify(jack_uuid_t subject,const char * key,jack_property_change_t change)396 int PropertyChangeNotify(jack_uuid_t subject, const char* key, jack_property_change_t change) 397 { 398 TRY_CALL 399 JackLock lock(&fEngine); 400 return fEngine.PropertyChangeNotify(subject, key, change); 401 CATCH_EXCEPTION_RETURN 402 } 403 }; 404 405 } // end of namespace 406 407 #endif 408 409