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.

409 lines
13KB

  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, char self_connect_mode):
  68. fEngine(manager, table, controler, self_connect_mode)
  69. {}
  70. ~JackLockedEngine()
  71. {}
  72. bool Lock() { return fEngine.Lock(); }
  73. bool Unlock() { return fEngine.Unlock(); }
  74. bool Trylock() { return fEngine.Trylock(); }
  75. int Open()
  76. {
  77. // No lock needed
  78. TRY_CALL
  79. return fEngine.Open();
  80. CATCH_EXCEPTION_RETURN
  81. }
  82. int Close()
  83. {
  84. // No lock needed
  85. TRY_CALL
  86. return fEngine.Close();
  87. CATCH_EXCEPTION_RETURN
  88. }
  89. // Client management
  90. int ClientCheck(const char* name, jack_uuid_t uuid, char* name_res, int protocol, int options, int* status)
  91. {
  92. TRY_CALL
  93. JackLock lock(&fEngine);
  94. return fEngine.ClientCheck(name, uuid, name_res, protocol, options, status);
  95. CATCH_EXCEPTION_RETURN
  96. }
  97. int ClientExternalOpen(const char* name, int pid, jack_uuid_t uuid, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager)
  98. {
  99. TRY_CALL
  100. JackLock lock(&fEngine);
  101. return fEngine.ClientExternalOpen(name, pid, uuid, ref, shared_engine, shared_client, shared_graph_manager);
  102. CATCH_EXCEPTION_RETURN
  103. }
  104. int ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, bool wait)
  105. {
  106. TRY_CALL
  107. JackLock lock(&fEngine);
  108. return fEngine.ClientInternalOpen(name, ref, shared_engine, shared_manager, client, wait);
  109. CATCH_EXCEPTION_RETURN
  110. }
  111. int ClientExternalClose(int refnum)
  112. {
  113. TRY_CALL
  114. JackLock lock(&fEngine);
  115. return (fEngine.CheckClient(refnum)) ? fEngine.ClientExternalClose(refnum) : -1;
  116. CATCH_CLOSE_EXCEPTION_RETURN
  117. }
  118. int ClientInternalClose(int refnum, bool wait)
  119. {
  120. TRY_CALL
  121. JackLock lock(&fEngine);
  122. return (fEngine.CheckClient(refnum)) ? fEngine.ClientInternalClose(refnum, wait) : -1;
  123. CATCH_CLOSE_EXCEPTION_RETURN
  124. }
  125. int ClientActivate(int refnum, bool is_real_time)
  126. {
  127. TRY_CALL
  128. JackLock lock(&fEngine);
  129. return (fEngine.CheckClient(refnum)) ? fEngine.ClientActivate(refnum, is_real_time) : -1;
  130. CATCH_EXCEPTION_RETURN
  131. }
  132. int ClientDeactivate(int refnum)
  133. {
  134. TRY_CALL
  135. JackLock lock(&fEngine);
  136. return (fEngine.CheckClient(refnum)) ? fEngine.ClientDeactivate(refnum) : -1;
  137. CATCH_EXCEPTION_RETURN
  138. }
  139. void ClientKill(int refnum)
  140. {
  141. TRY_CALL
  142. JackLock lock(&fEngine);
  143. fEngine.ClientKill(refnum);
  144. CATCH_EXCEPTION
  145. }
  146. // Internal client management
  147. int GetInternalClientName(int int_ref, char* name_res)
  148. {
  149. TRY_CALL
  150. JackLock lock(&fEngine);
  151. return fEngine.GetInternalClientName(int_ref, name_res);
  152. CATCH_EXCEPTION_RETURN
  153. }
  154. int InternalClientHandle(const char* client_name, int* status, int* int_ref)
  155. {
  156. TRY_CALL
  157. JackLock lock(&fEngine);
  158. return fEngine.InternalClientHandle(client_name, status, int_ref);
  159. CATCH_EXCEPTION_RETURN
  160. }
  161. int InternalClientUnload(int refnum, int* status)
  162. {
  163. TRY_CALL
  164. JackLock lock(&fEngine);
  165. // Client is tested in fEngine.InternalClientUnload
  166. return fEngine.InternalClientUnload(refnum, status);
  167. CATCH_EXCEPTION_RETURN
  168. }
  169. // Port management
  170. int PortRegister(int refnum, const char* name, const char *type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port)
  171. {
  172. TRY_CALL
  173. JackLock lock(&fEngine);
  174. return (fEngine.CheckClient(refnum)) ? fEngine.PortRegister(refnum, name, type, flags, buffer_size, port) : -1;
  175. CATCH_EXCEPTION_RETURN
  176. }
  177. int PortUnRegister(int refnum, jack_port_id_t port)
  178. {
  179. TRY_CALL
  180. JackLock lock(&fEngine);
  181. return (fEngine.CheckClient(refnum)) ? fEngine.PortUnRegister(refnum, port) : -1;
  182. CATCH_EXCEPTION_RETURN
  183. }
  184. int PortConnect(int refnum, const char* src, const char* dst)
  185. {
  186. TRY_CALL
  187. JackLock lock(&fEngine);
  188. return (fEngine.CheckClient(refnum)) ? fEngine.PortConnect(refnum, src, dst) : -1;
  189. CATCH_EXCEPTION_RETURN
  190. }
  191. int PortDisconnect(int refnum, const char* src, const char* dst)
  192. {
  193. TRY_CALL
  194. JackLock lock(&fEngine);
  195. return (fEngine.CheckClient(refnum)) ? fEngine.PortDisconnect(refnum, src, dst) : -1;
  196. CATCH_EXCEPTION_RETURN
  197. }
  198. int PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst)
  199. {
  200. TRY_CALL
  201. JackLock lock(&fEngine);
  202. return (fEngine.CheckClient(refnum)) ? fEngine.PortConnect(refnum, src, dst) : -1;
  203. CATCH_EXCEPTION_RETURN
  204. }
  205. int PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst)
  206. {
  207. TRY_CALL
  208. JackLock lock(&fEngine);
  209. return (fEngine.CheckClient(refnum)) ? fEngine.PortDisconnect(refnum, src, dst) : -1;
  210. CATCH_EXCEPTION_RETURN
  211. }
  212. int PortRename(int refnum, jack_port_id_t port, const char* name)
  213. {
  214. TRY_CALL
  215. JackLock lock(&fEngine);
  216. return (fEngine.CheckClient(refnum)) ? fEngine.PortRename(refnum, port, name) : -1;
  217. CATCH_EXCEPTION_RETURN
  218. }
  219. int PortSetDefaultMetadata(int refnum, jack_port_id_t port, const char* pretty_name)
  220. {
  221. TRY_CALL
  222. JackLock lock(&fEngine);
  223. return (fEngine.CheckClient(refnum)) ? fEngine.PortSetDefaultMetadata(port, pretty_name) : -1;
  224. CATCH_EXCEPTION_RETURN
  225. }
  226. int ComputeTotalLatencies()
  227. {
  228. TRY_CALL
  229. JackLock lock(&fEngine);
  230. return fEngine.ComputeTotalLatencies();
  231. CATCH_EXCEPTION_RETURN
  232. }
  233. // Graph
  234. bool Process(jack_time_t cur_cycle_begin, jack_time_t prev_cycle_end)
  235. {
  236. // RT : no lock
  237. return fEngine.Process(cur_cycle_begin, prev_cycle_end);
  238. }
  239. // Notifications
  240. void NotifyDriverXRun()
  241. {
  242. // Coming from the driver in RT : no lock
  243. fEngine.NotifyDriverXRun();
  244. }
  245. void NotifyClientXRun(int refnum)
  246. {
  247. TRY_CALL
  248. JackLock lock(&fEngine);
  249. fEngine.NotifyClientXRun(refnum);
  250. CATCH_EXCEPTION
  251. }
  252. void NotifyGraphReorder()
  253. {
  254. TRY_CALL
  255. JackLock lock(&fEngine);
  256. fEngine.NotifyGraphReorder();
  257. CATCH_EXCEPTION
  258. }
  259. void NotifyBufferSize(jack_nframes_t buffer_size)
  260. {
  261. TRY_CALL
  262. JackLock lock(&fEngine);
  263. fEngine.NotifyBufferSize(buffer_size);
  264. CATCH_EXCEPTION
  265. }
  266. void NotifySampleRate(jack_nframes_t sample_rate)
  267. {
  268. TRY_CALL
  269. JackLock lock(&fEngine);
  270. fEngine.NotifySampleRate(sample_rate);
  271. CATCH_EXCEPTION
  272. }
  273. void NotifyFreewheel(bool onoff)
  274. {
  275. TRY_CALL
  276. JackLock lock(&fEngine);
  277. fEngine.NotifyFreewheel(onoff);
  278. CATCH_EXCEPTION
  279. }
  280. void NotifyFailure(int code, const char* reason)
  281. {
  282. TRY_CALL
  283. JackLock lock(&fEngine);
  284. fEngine.NotifyFailure(code, reason);
  285. CATCH_EXCEPTION
  286. }
  287. int GetClientPID(const char* name)
  288. {
  289. TRY_CALL
  290. JackLock lock(&fEngine);
  291. return fEngine.GetClientPID(name);
  292. CATCH_EXCEPTION_RETURN
  293. }
  294. int GetClientRefNum(const char* name)
  295. {
  296. TRY_CALL
  297. JackLock lock(&fEngine);
  298. return fEngine.GetClientRefNum(name);
  299. CATCH_EXCEPTION_RETURN
  300. }
  301. void NotifyQuit()
  302. {
  303. // No lock needed
  304. TRY_CALL
  305. return fEngine.NotifyQuit();
  306. CATCH_EXCEPTION
  307. }
  308. void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, detail::JackChannelTransactionInterface *socket, JackSessionNotifyResult** result)
  309. {
  310. TRY_CALL
  311. JackLock lock(&fEngine);
  312. fEngine.SessionNotify(refnum, target, type, path, socket, result);
  313. CATCH_EXCEPTION
  314. }
  315. int SessionReply(int refnum)
  316. {
  317. TRY_CALL
  318. JackLock lock(&fEngine);
  319. return fEngine.SessionReply(refnum);
  320. CATCH_EXCEPTION_RETURN
  321. }
  322. int GetUUIDForClientName(const char *client_name, char *uuid_res)
  323. {
  324. TRY_CALL
  325. JackLock lock(&fEngine);
  326. return fEngine.GetUUIDForClientName(client_name, uuid_res);
  327. CATCH_EXCEPTION_RETURN
  328. }
  329. int GetClientNameForUUID(const char *uuid, char *name_res)
  330. {
  331. TRY_CALL
  332. JackLock lock(&fEngine);
  333. return fEngine.GetClientNameForUUID(uuid, name_res);
  334. CATCH_EXCEPTION_RETURN
  335. }
  336. int ReserveClientName(const char *name, const char *uuid)
  337. {
  338. TRY_CALL
  339. JackLock lock(&fEngine);
  340. return fEngine.ReserveClientName(name, uuid);
  341. CATCH_EXCEPTION_RETURN
  342. }
  343. int ClientHasSessionCallback(const char *name)
  344. {
  345. TRY_CALL
  346. JackLock lock(&fEngine);
  347. return fEngine.ClientHasSessionCallback(name);
  348. CATCH_EXCEPTION_RETURN
  349. }
  350. int PropertyChangeNotify(jack_uuid_t subject, const char* key, jack_property_change_t change)
  351. {
  352. TRY_CALL
  353. JackLock lock(&fEngine);
  354. return fEngine.PropertyChangeNotify(subject, key, change);
  355. CATCH_EXCEPTION_RETURN
  356. }
  357. };
  358. } // end of namespace
  359. #endif