Audio plugin host https://kx.studio/carla
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.

CarlaPipeUtils.hpp 10KB

11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
6 years ago
6 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
10 years ago
11 years ago
10 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. /*
  2. * Carla Pipe utils
  3. * Copyright (C) 2013-2023 Filipe Coelho <falktx@falktx.com>
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation; either version 2 of
  8. * the License, or any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  16. */
  17. #ifndef CARLA_PIPE_UTILS_HPP_INCLUDED
  18. #define CARLA_PIPE_UTILS_HPP_INCLUDED
  19. #include "CarlaJuceUtils.hpp"
  20. #include "CarlaMutex.hpp"
  21. #ifdef BUILDING_CARLA
  22. # include "lv2/atom.h"
  23. #else
  24. # include "lv2/atom/atom.h"
  25. #endif
  26. // -----------------------------------------------------------------------
  27. // CarlaPipeCommon class
  28. class CarlaPipeCommon
  29. {
  30. protected:
  31. /*!
  32. * Constructor.
  33. */
  34. CarlaPipeCommon() noexcept;
  35. /*!
  36. * Destructor.
  37. */
  38. virtual ~CarlaPipeCommon() /*noexcept*/;
  39. /*!
  40. * A message has been received (in the context of idlePipe()).
  41. * If extra data is required, use any of the readNextLineAs* functions.
  42. * Returning true means the message has been handled and should not propagate to subclasses.
  43. */
  44. virtual bool msgReceived(const char* msg) noexcept = 0;
  45. /*!
  46. * An error has occurred during the current requested operation.
  47. * Reimplementing this method allows to catch these errors as strings.
  48. * By default the error is simply printed to stderr.
  49. */
  50. virtual void fail(const char* error) noexcept
  51. {
  52. carla_stderr2(error);
  53. }
  54. public:
  55. /*!
  56. * Check if the pipe is running.
  57. */
  58. bool isPipeRunning() const noexcept;
  59. /*!
  60. * Check the pipe for new messages and send them to msgReceived().
  61. */
  62. void idlePipe(bool onlyOnce = false) noexcept;
  63. // -------------------------------------------------------------------
  64. // write lock
  65. /*!
  66. * Lock the pipe write mutex.
  67. */
  68. void lockPipe() const noexcept;
  69. /*!
  70. * Try locking the pipe write mutex.
  71. * Returns true if successful.
  72. */
  73. bool tryLockPipe() const noexcept;
  74. /*!
  75. * Unlock the pipe write mutex.
  76. */
  77. void unlockPipe() const noexcept;
  78. /*!
  79. * Get the pipe write lock.
  80. */
  81. CarlaMutex& getPipeLock() const noexcept;
  82. // -------------------------------------------------------------------
  83. // read lines, must only be called in the context of msgReceived()
  84. /*!
  85. * Read the next line as a boolean.
  86. */
  87. bool readNextLineAsBool(bool& value) const noexcept;
  88. /*!
  89. * Read the next line as a byte.
  90. */
  91. bool readNextLineAsByte(uint8_t& value) const noexcept;
  92. /*!
  93. * Read the next line as an integer.
  94. */
  95. bool readNextLineAsInt(int32_t& value) const noexcept;
  96. /*!
  97. * Read the next line as an unsigned integer.
  98. */
  99. bool readNextLineAsUInt(uint32_t& value) const noexcept;
  100. /*!
  101. * Read the next line as a long integer.
  102. */
  103. bool readNextLineAsLong(int64_t& value) const noexcept;
  104. /*!
  105. * Read the next line as a long unsigned integer.
  106. */
  107. bool readNextLineAsULong(uint64_t& value) const noexcept;
  108. /*!
  109. * Read the next line as a floating point number (single precision).
  110. */
  111. bool readNextLineAsFloat(float& value) const noexcept;
  112. /*!
  113. * Read the next line as a floating point number (double precision).
  114. */
  115. bool readNextLineAsDouble(double& value) const noexcept;
  116. /*!
  117. * Read the next line as a string.
  118. * @note: @a value must be freed if valid and allocateString is true.
  119. */
  120. bool readNextLineAsString(const char*& value, bool allocateString, uint32_t size = 0) const noexcept;
  121. /*!
  122. * Read the next line as a string, returning an allocated copy that needs to be freed.
  123. */
  124. char* readNextLineAsString() const noexcept;
  125. // -------------------------------------------------------------------
  126. // write messages, must be locked before calling
  127. /*!
  128. * Write a valid message with unknown size.
  129. * A valid message has only one '\n' character and it's at the end.
  130. */
  131. bool writeMessage(const char* msg) const noexcept;
  132. /*!
  133. * Write a valid message with known size.
  134. * A valid message has only one '\n' character and it's at the end.
  135. */
  136. bool writeMessage(const char* msg, std::size_t size) const noexcept;
  137. /*!
  138. * Write and fix a message.
  139. */
  140. bool writeAndFixMessage(const char* msg) const noexcept;
  141. /*!
  142. * Write an empty message, which means a single '\n'.
  143. */
  144. bool writeEmptyMessage() const noexcept;
  145. /*!
  146. * Sync all messages currently in cache.
  147. * This call will forcely write any messages in cache to any relevant IO.
  148. */
  149. bool syncMessages() const noexcept;
  150. // -------------------------------------------------------------------
  151. // write prepared messages, no lock or flush needed (done internally)
  152. /*!
  153. * Write an "error" message.
  154. */
  155. bool writeErrorMessage(const char* error) const noexcept;
  156. /*!
  157. * Write a "control" message used for parameter/control changes.
  158. */
  159. bool writeControlMessage(uint32_t index, float value, bool withWriteLock = true) const noexcept;
  160. /*!
  161. * Write a "configure" message used for state changes.
  162. */
  163. bool writeConfigureMessage(const char* key, const char* value) const noexcept;
  164. /*!
  165. * Write a "program" message (using index).
  166. */
  167. bool writeProgramMessage(uint32_t index) const noexcept;
  168. /*!
  169. * Write a "program" message (using channel, bank and program).
  170. */
  171. bool writeProgramMessage(uint8_t channel, uint32_t bank, uint32_t program) const noexcept;
  172. /*!
  173. * Write a "midiprogram" message (using bank and program).
  174. */
  175. bool writeMidiProgramMessage(uint32_t bank, uint32_t program) const noexcept;
  176. /*!
  177. * Write a "reloadprograms" message.
  178. */
  179. bool writeReloadProgramsMessage(int32_t index) const noexcept;
  180. /*!
  181. * Write a MIDI "note" message.
  182. */
  183. bool writeMidiNoteMessage(bool onOff, uint8_t channel, uint8_t note, uint8_t velocity) const noexcept;
  184. /*!
  185. * Write an lv2 "atom" message.
  186. */
  187. bool writeLv2AtomMessage(uint32_t index, const LV2_Atom* atom) const noexcept;
  188. /*!
  189. * Write an lv2 "parameter" message.
  190. */
  191. bool writeLv2ParameterMessage(const char* uri, float value, bool withWriteLock = true) const noexcept;
  192. /*!
  193. * Write an lv2 "urid" message.
  194. */
  195. bool writeLv2UridMessage(uint32_t urid, const char* uri) const noexcept;
  196. // -------------------------------------------------------------------
  197. protected:
  198. struct PrivateData;
  199. PrivateData* const pData;
  200. // -------------------------------------------------------------------
  201. /*! @internal */
  202. const char* _readline(bool allocReturn, uint16_t size, bool& readSucess) const noexcept;
  203. /*! @internal */
  204. const char* _readlineblock(bool allocReturn, uint16_t size = 0, uint32_t timeOutMilliseconds = 50) const noexcept;
  205. /*! @internal */
  206. bool _writeMsgBuffer(const char* msg, std::size_t size) const noexcept;
  207. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeCommon)
  208. };
  209. // -----------------------------------------------------------------------
  210. // CarlaPipeServer class
  211. class CarlaPipeServer : public CarlaPipeCommon
  212. {
  213. public:
  214. /*!
  215. * Constructor.
  216. */
  217. CarlaPipeServer() noexcept;
  218. /*!
  219. * Destructor.
  220. */
  221. ~CarlaPipeServer() /*noexcept*/ override;
  222. /*!
  223. * Get the process ID of this pipe's matching client.
  224. * Will return 0 if client is not running.
  225. * @note: Unsupported on Windows
  226. */
  227. uintptr_t getPID() const noexcept;
  228. /*!
  229. * Start the pipe server using @a filename with 2 arguments.
  230. * @see fail()
  231. */
  232. bool startPipeServer(const char* helperTool,
  233. const char* filename, const char* arg1, const char* arg2, int size = -1) noexcept;
  234. /*!
  235. * Start the pipe server using @a filename with 2 arguments.
  236. * @see fail()
  237. */
  238. bool startPipeServer(const char* filename, const char* arg1, const char* arg2, int size = -1) noexcept;
  239. /*!
  240. * Stop the pipe server.
  241. * This will send a quit message to the client, wait for it to close for @a timeOutMilliseconds, and close the pipes.
  242. */
  243. void stopPipeServer(uint32_t timeOutMilliseconds) noexcept;
  244. /*!
  245. * Close the pipes without waiting for the child process to terminate.
  246. */
  247. void closePipeServer() noexcept;
  248. // -------------------------------------------------------------------
  249. // write prepared messages, no lock or flush needed (done internally)
  250. /*!
  251. * Write a single "show" message.
  252. */
  253. void writeShowMessage() const noexcept;
  254. /*!
  255. * Write a single "focus" message.
  256. */
  257. void writeFocusMessage() const noexcept;
  258. /*!
  259. * Write a single "hide" message.
  260. */
  261. void writeHideMessage() const noexcept;
  262. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeServer)
  263. };
  264. // -----------------------------------------------------------------------
  265. // CarlaPipeClient class
  266. class CarlaPipeClient : public CarlaPipeCommon
  267. {
  268. public:
  269. /*!
  270. * Constructor.
  271. */
  272. CarlaPipeClient() noexcept;
  273. /*!
  274. * Destructor.
  275. */
  276. ~CarlaPipeClient() /*noexcept*/ override;
  277. /*!
  278. * Initialize the pipes used by a server.
  279. * @a argv must match the arguments set the by server.
  280. */
  281. bool initPipeClient(const char* argv[]) noexcept;
  282. /*!
  283. * Close the pipes.
  284. */
  285. void closePipeClient() noexcept;
  286. // -------------------------------------------------------------------
  287. // write prepared messages, no lock or flush needed (done internally)
  288. /*!
  289. * Write a single "exiting" message and wait for server to respond.
  290. */
  291. void writeExitingMessageAndWait() noexcept;
  292. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeClient)
  293. };
  294. // -----------------------------------------------------------------------
  295. #endif // CARLA_PIPE_UTILS_HPP_INCLUDED