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
6 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
10 years ago
11 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. /*
  2. * Carla Pipe utils
  3. * Copyright (C) 2013-2018 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/lv2plug.in/ns/ext/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* const 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* const 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(const 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 deleted if valid.
  119. */
  120. bool readNextLineAsString(const char*& value) const noexcept;
  121. // -------------------------------------------------------------------
  122. // write messages, must be locked before calling
  123. /*!
  124. * Write a valid message with unknown size.
  125. * A valid message has only one '\n' character and it's at the end.
  126. */
  127. bool writeMessage(const char* const msg) const noexcept;
  128. /*!
  129. * Write a valid message with known size.
  130. * A valid message has only one '\n' character and it's at the end.
  131. */
  132. bool writeMessage(const char* const msg, std::size_t size) const noexcept;
  133. /*!
  134. * Write and fix a message.
  135. */
  136. bool writeAndFixMessage(const char* const msg) const noexcept;
  137. /*!
  138. * Flush all messages currently in cache.
  139. */
  140. bool flushMessages() const noexcept;
  141. // -------------------------------------------------------------------
  142. // write prepared messages, no lock or flush needed (done internally)
  143. /*!
  144. * Write an "error" message.
  145. */
  146. void writeErrorMessage(const char* const error) const noexcept;
  147. /*!
  148. * Write a "control" message used for parameter changes.
  149. */
  150. void writeControlMessage(const uint32_t index, const float value) const noexcept;
  151. /*!
  152. * Write a "configure" message used for state changes.
  153. */
  154. void writeConfigureMessage(const char* const key, const char* const value) const noexcept;
  155. /*!
  156. * Write a "program" message (using index).
  157. */
  158. void writeProgramMessage(const uint32_t index) const noexcept;
  159. /*!
  160. * Write a "program" message (using channel, bank and program).
  161. */
  162. void writeProgramMessage(const uint8_t channel, const uint32_t bank, const uint32_t program) const noexcept;
  163. /*!
  164. * Write a "midiprogram" message (using bank and program).
  165. */
  166. void writeMidiProgramMessage(const uint32_t bank, const uint32_t program) const noexcept;
  167. /*!
  168. * Write a "reloadprograms" message.
  169. */
  170. void writeReloadProgramsMessage(const int32_t index) const noexcept;
  171. /*!
  172. * Write a MIDI "note" message.
  173. */
  174. void writeMidiNoteMessage(const bool onOff, const uint8_t channel, const uint8_t note, const uint8_t velocity) const noexcept;
  175. /*!
  176. * Write an lv2 "atom" message.
  177. */
  178. void writeLv2AtomMessage(const uint32_t index, const LV2_Atom* const atom) const noexcept;
  179. /*!
  180. * Write an lv2 "urid" message.
  181. */
  182. void writeLv2UridMessage(const uint32_t urid, const char* const uri) const noexcept;
  183. // -------------------------------------------------------------------
  184. protected:
  185. struct PrivateData;
  186. PrivateData* const pData;
  187. // -------------------------------------------------------------------
  188. /*! @internal */
  189. const char* _readline() const noexcept;
  190. /*! @internal */
  191. const char* _readlineblock(const uint32_t timeOutMilliseconds = 50) const noexcept;
  192. /*! @internal */
  193. bool _writeMsgBuffer(const char* const msg, const std::size_t size) const noexcept;
  194. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeCommon)
  195. };
  196. // -----------------------------------------------------------------------
  197. // CarlaPipeServer class
  198. class CarlaPipeServer : public CarlaPipeCommon
  199. {
  200. public:
  201. /*!
  202. * Constructor.
  203. */
  204. CarlaPipeServer() noexcept;
  205. /*!
  206. * Destructor.
  207. */
  208. ~CarlaPipeServer() /*noexcept*/ override;
  209. /*!
  210. * Get the process ID of this pipe's matching client.
  211. * Will return 0 if client is not running.
  212. * @note: Unsupported on Windows
  213. */
  214. uintptr_t getPID() const noexcept;
  215. /*!
  216. * Start the pipe server using @a filename with 2 arguments.
  217. * @see fail()
  218. */
  219. bool startPipeServer(const char* const filename, const char* const arg1, const char* const arg2, const int size = -1) noexcept;
  220. /*!
  221. * Stop the pipe server.
  222. * This will send a quit message to the client, wait for it to close for @a timeOutMilliseconds, and close the pipes.
  223. */
  224. void stopPipeServer(const uint32_t timeOutMilliseconds) noexcept;
  225. /*!
  226. * Close the pipes without waiting for the child process to terminate.
  227. */
  228. void closePipeServer() noexcept;
  229. // -------------------------------------------------------------------
  230. // write prepared messages, no lock or flush needed (done internally)
  231. /*!
  232. * Write a single "show" message.
  233. */
  234. void writeShowMessage() const noexcept;
  235. /*!
  236. * Write a single "focus" message.
  237. */
  238. void writeFocusMessage() const noexcept;
  239. /*!
  240. * Write a single "hide" message.
  241. */
  242. void writeHideMessage() const noexcept;
  243. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeServer)
  244. };
  245. // -----------------------------------------------------------------------
  246. // CarlaPipeClient class
  247. class CarlaPipeClient : public CarlaPipeCommon
  248. {
  249. public:
  250. /*!
  251. * Constructor.
  252. */
  253. CarlaPipeClient() noexcept;
  254. /*!
  255. * Destructor.
  256. */
  257. ~CarlaPipeClient() /*noexcept*/ override;
  258. /*!
  259. * Initialize the pipes used by a server.
  260. * @a argv must match the arguments set the by server.
  261. */
  262. bool initPipeClient(const char* argv[]) noexcept;
  263. /*!
  264. * Close the pipes.
  265. */
  266. void closePipeClient() noexcept;
  267. // -------------------------------------------------------------------
  268. // write prepared messages, no lock or flush needed (done internally)
  269. /*!
  270. * Write a single "exiting" message and wait for server to respond.
  271. */
  272. void writeExitingMessageAndWait() noexcept;
  273. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeClient)
  274. };
  275. // -----------------------------------------------------------------------
  276. // ScopedEnvVar class
  277. class ScopedEnvVar {
  278. public:
  279. ScopedEnvVar(const char* const key, const char* const value) noexcept;
  280. ~ScopedEnvVar() noexcept;
  281. private:
  282. const char* fKey;
  283. const char* fOrigValue;
  284. CARLA_DECLARE_NON_COPY_CLASS(ScopedEnvVar)
  285. CARLA_PREVENT_HEAP_ALLOCATION
  286. };
  287. // -----------------------------------------------------------------------
  288. // ScopedLocale class
  289. class ScopedLocale {
  290. public:
  291. ScopedLocale() noexcept;
  292. ~ScopedLocale() noexcept;
  293. private:
  294. const char* const fLocale;
  295. CARLA_DECLARE_NON_COPY_CLASS(ScopedLocale)
  296. CARLA_PREVENT_HEAP_ALLOCATION
  297. };
  298. // -----------------------------------------------------------------------
  299. #endif // CARLA_PIPE_UTILS_HPP_INCLUDED