jack2 codebase
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

379 lines
12KB

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