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.

388 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. void ClientKill(int refnum)
  137. {
  138. TRY_CALL
  139. JackLock lock(&fEngine);
  140. fEngine.ClientKill(refnum);
  141. CATCH_EXCEPTION
  142. }
  143. // Internal client management
  144. int GetInternalClientName(int int_ref, char* name_res)
  145. {
  146. TRY_CALL
  147. JackLock lock(&fEngine);
  148. return fEngine.GetInternalClientName(int_ref, name_res);
  149. CATCH_EXCEPTION_RETURN
  150. }
  151. int InternalClientHandle(const char* client_name, int* status, int* int_ref)
  152. {
  153. TRY_CALL
  154. JackLock lock(&fEngine);
  155. return fEngine.InternalClientHandle(client_name, status, int_ref);
  156. CATCH_EXCEPTION_RETURN
  157. }
  158. int InternalClientUnload(int refnum, int* status)
  159. {
  160. TRY_CALL
  161. JackLock lock(&fEngine);
  162. // Client is tested in fEngine.InternalClientUnload
  163. return fEngine.InternalClientUnload(refnum, status);
  164. CATCH_EXCEPTION_RETURN
  165. }
  166. // Port management
  167. int PortRegister(int refnum, const char* name, const char *type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port)
  168. {
  169. TRY_CALL
  170. JackLock lock(&fEngine);
  171. return (fEngine.CheckClient(refnum)) ? fEngine.PortRegister(refnum, name, type, flags, buffer_size, port) : -1;
  172. CATCH_EXCEPTION_RETURN
  173. }
  174. int PortUnRegister(int refnum, jack_port_id_t port)
  175. {
  176. TRY_CALL
  177. JackLock lock(&fEngine);
  178. return (fEngine.CheckClient(refnum)) ? fEngine.PortUnRegister(refnum, port) : -1;
  179. CATCH_EXCEPTION_RETURN
  180. }
  181. int PortConnect(int refnum, const char* src, const char* dst)
  182. {
  183. TRY_CALL
  184. JackLock lock(&fEngine);
  185. return (fEngine.CheckClient(refnum)) ? fEngine.PortConnect(refnum, src, dst) : -1;
  186. CATCH_EXCEPTION_RETURN
  187. }
  188. int PortDisconnect(int refnum, const char* src, const char* dst)
  189. {
  190. TRY_CALL
  191. JackLock lock(&fEngine);
  192. return (fEngine.CheckClient(refnum)) ? fEngine.PortDisconnect(refnum, src, dst) : -1;
  193. CATCH_EXCEPTION_RETURN
  194. }
  195. int PortConnect(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.PortConnect(refnum, src, dst) : -1;
  200. CATCH_EXCEPTION_RETURN
  201. }
  202. int PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst)
  203. {
  204. TRY_CALL
  205. JackLock lock(&fEngine);
  206. return (fEngine.CheckClient(refnum)) ? fEngine.PortDisconnect(refnum, src, dst) : -1;
  207. CATCH_EXCEPTION_RETURN
  208. }
  209. int PortRename(int refnum, jack_port_id_t port, const char* name)
  210. {
  211. TRY_CALL
  212. JackLock lock(&fEngine);
  213. return (fEngine.CheckClient(refnum)) ? fEngine.PortRename(refnum, port, name) : -1;
  214. CATCH_EXCEPTION_RETURN
  215. }
  216. int ComputeTotalLatencies()
  217. {
  218. TRY_CALL
  219. JackLock lock(&fEngine);
  220. return fEngine.ComputeTotalLatencies();
  221. CATCH_EXCEPTION_RETURN
  222. }
  223. // Graph
  224. bool Process(jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end)
  225. {
  226. // RT : no lock
  227. return fEngine.Process(cur_cycle_begin, prev_cycle_end);
  228. }
  229. // Notifications
  230. void NotifyDriverXRun()
  231. {
  232. // Coming from the driver in RT : no lock
  233. fEngine.NotifyDriverXRun();
  234. }
  235. void NotifyClientXRun(int refnum)
  236. {
  237. TRY_CALL
  238. JackLock lock(&fEngine);
  239. fEngine.NotifyClientXRun(refnum);
  240. CATCH_EXCEPTION
  241. }
  242. void NotifyGraphReorder()
  243. {
  244. TRY_CALL
  245. JackLock lock(&fEngine);
  246. fEngine.NotifyGraphReorder();
  247. CATCH_EXCEPTION
  248. }
  249. void NotifyBufferSize(jack_nframes_t buffer_size)
  250. {
  251. TRY_CALL
  252. JackLock lock(&fEngine);
  253. fEngine.NotifyBufferSize(buffer_size);
  254. CATCH_EXCEPTION
  255. }
  256. void NotifySampleRate(jack_nframes_t sample_rate)
  257. {
  258. TRY_CALL
  259. JackLock lock(&fEngine);
  260. fEngine.NotifySampleRate(sample_rate);
  261. CATCH_EXCEPTION
  262. }
  263. void NotifyFreewheel(bool onoff)
  264. {
  265. TRY_CALL
  266. JackLock lock(&fEngine);
  267. fEngine.NotifyFreewheel(onoff);
  268. CATCH_EXCEPTION
  269. }
  270. void NotifyFailure(int code, const char* reason)
  271. {
  272. TRY_CALL
  273. JackLock lock(&fEngine);
  274. fEngine.NotifyFailure(code, reason);
  275. CATCH_EXCEPTION
  276. }
  277. int GetClientPID(const char* name)
  278. {
  279. TRY_CALL
  280. JackLock lock(&fEngine);
  281. return fEngine.GetClientPID(name);
  282. CATCH_EXCEPTION_RETURN
  283. }
  284. int GetClientRefNum(const char* name)
  285. {
  286. TRY_CALL
  287. JackLock lock(&fEngine);
  288. return fEngine.GetClientRefNum(name);
  289. CATCH_EXCEPTION_RETURN
  290. }
  291. void NotifyQuit()
  292. {
  293. // No lock needed
  294. TRY_CALL
  295. return fEngine.NotifyQuit();
  296. CATCH_EXCEPTION
  297. }
  298. void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, detail::JackChannelTransactionInterface *socket, JackSessionNotifyResult** result)
  299. {
  300. TRY_CALL
  301. JackLock lock(&fEngine);
  302. fEngine.SessionNotify(refnum, target, type, path, socket, result);
  303. CATCH_EXCEPTION
  304. }
  305. int SessionReply(int refnum)
  306. {
  307. TRY_CALL
  308. JackLock lock(&fEngine);
  309. return fEngine.SessionReply(refnum);
  310. CATCH_EXCEPTION_RETURN
  311. }
  312. int GetUUIDForClientName(const char *client_name, char *uuid_res)
  313. {
  314. TRY_CALL
  315. JackLock lock(&fEngine);
  316. return fEngine.GetUUIDForClientName(client_name, uuid_res);
  317. CATCH_EXCEPTION_RETURN
  318. }
  319. int GetClientNameForUUID(const char *uuid, char *name_res)
  320. {
  321. TRY_CALL
  322. JackLock lock(&fEngine);
  323. return fEngine.GetClientNameForUUID(uuid, name_res);
  324. CATCH_EXCEPTION_RETURN
  325. }
  326. int ReserveClientName(const char *name, const char *uuid)
  327. {
  328. TRY_CALL
  329. JackLock lock(&fEngine);
  330. return fEngine.ReserveClientName(name, uuid);
  331. CATCH_EXCEPTION_RETURN
  332. }
  333. int ClientHasSessionCallback(const char *name)
  334. {
  335. TRY_CALL
  336. JackLock lock(&fEngine);
  337. return fEngine.ClientHasSessionCallback(name);
  338. CATCH_EXCEPTION_RETURN
  339. }
  340. };
  341. } // end of namespace
  342. #endif