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.

270 lines
7.0KB

  1. /*
  2. * Carla Pipe utils
  3. * Copyright (C) 2013-2014 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. // -----------------------------------------------------------------------
  22. // CarlaPipeCommon class
  23. class CarlaPipeCommon
  24. {
  25. protected:
  26. /*!
  27. * Constructor.
  28. */
  29. CarlaPipeCommon() noexcept;
  30. /*!
  31. * Destructor.
  32. */
  33. virtual ~CarlaPipeCommon() noexcept;
  34. /*!
  35. * A message has been received (in the context of idlePipe()).
  36. * If extra data is required, use any of the readNextLineAs* functions.
  37. * Returning true means the message has been handled and should not propagate to subclasses.
  38. */
  39. virtual bool msgReceived(const char* const msg) noexcept = 0;
  40. /*!
  41. * An error has occurred during the current requested operation.
  42. * Reimplementing this method allows to catch these errors as strings.
  43. * By default the error is simply printed to stderr.
  44. */
  45. virtual void fail(const char* const error) noexcept
  46. {
  47. carla_stderr2(error);
  48. }
  49. public:
  50. /*!
  51. * Check if the pipe is running.
  52. */
  53. bool isPipeRunning() const noexcept;
  54. /*!
  55. * Check the pipe for new messages and send them to msgReceived().
  56. */
  57. void idlePipe() noexcept;
  58. // -------------------------------------------------------------------
  59. // write lock
  60. /*!
  61. * Lock the pipe write mutex.
  62. */
  63. void lockPipe() const noexcept;
  64. /*!
  65. * Try locking the pipe write mutex.
  66. * Returns true if successful.
  67. */
  68. bool tryLockPipe() const noexcept;
  69. /*!
  70. * Unlock the pipe write mutex.
  71. */
  72. void unlockPipe() const noexcept;
  73. /*!
  74. * Get the pipe write lock.
  75. */
  76. CarlaMutex& getPipeLock() const noexcept;
  77. // -------------------------------------------------------------------
  78. // read lines, must only be called in the context of msgReceived()
  79. /*!
  80. * Read the next line as a boolean.
  81. */
  82. bool readNextLineAsBool(bool& value) const noexcept;
  83. /*!
  84. * Read the next line as a byte.
  85. */
  86. bool readNextLineAsByte(uint8_t& value) const noexcept;
  87. /*!
  88. * Read the next line as an integer.
  89. */
  90. bool readNextLineAsInt(int32_t& value) const noexcept;
  91. /*!
  92. * Read the next line as an unsigned integer.
  93. */
  94. bool readNextLineAsUInt(uint32_t& value) const noexcept;
  95. /*!
  96. * Read the next line as a long integer.
  97. */
  98. bool readNextLineAsLong(int64_t& value) const noexcept;
  99. /*!
  100. * Read the next line as a long unsigned integer.
  101. */
  102. bool readNextLineAsULong(uint64_t& value) const noexcept;
  103. /*!
  104. * Read the next line as a floating point number (single precision).
  105. */
  106. bool readNextLineAsFloat(float& value) const noexcept;
  107. /*!
  108. * Read the next line as a floating point number (double precision).
  109. */
  110. bool readNextLineAsDouble(double& value) const noexcept;
  111. /*!
  112. * Read the next line as a string.
  113. * @note: @a value must be deleted if valid.
  114. */
  115. bool readNextLineAsString(const char*& value) const noexcept;
  116. // -------------------------------------------------------------------
  117. // write messages, must be locked before calling
  118. /*!
  119. * Write a valid message with unknown size.
  120. * A valid message has only one '\n' character and it's at the end.
  121. */
  122. bool writeMessage(const char* const msg) const noexcept;
  123. /*!
  124. * Write a valid message with known size.
  125. * A valid message has only one '\n' character and it's at the end.
  126. */
  127. bool writeMessage(const char* const msg, std::size_t size) const noexcept;
  128. /*!
  129. * Write and fix a message.
  130. */
  131. bool writeAndFixMessage(const char* const msg) const noexcept;
  132. /*!
  133. * Flush all messages currently in cache.
  134. */
  135. bool flushMessages() const noexcept;
  136. // -------------------------------------------------------------------
  137. protected:
  138. struct PrivateData;
  139. PrivateData* const pData;
  140. // -------------------------------------------------------------------
  141. /*! @internal */
  142. const char* _readline() const noexcept;
  143. /*! @internal */
  144. const char* _readlineblock(const uint32_t timeOutMilliseconds = 50) const noexcept;
  145. /*! @internal */
  146. bool _writeMsgBuffer(const char* const msg, const std::size_t size) const noexcept;
  147. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeCommon)
  148. };
  149. // -----------------------------------------------------------------------
  150. // CarlaPipeServer class
  151. class CarlaPipeServer : public CarlaPipeCommon
  152. {
  153. public:
  154. /*!
  155. * Constructor.
  156. */
  157. CarlaPipeServer() noexcept;
  158. /*!
  159. * Destructor.
  160. */
  161. ~CarlaPipeServer() noexcept override;
  162. /*!
  163. * Start the pipe server using @a filename with 2 arguments.
  164. * @see fail()
  165. */
  166. bool startPipeServer(const char* const filename, const char* const arg1, const char* const arg2) noexcept;
  167. /*!
  168. * Stop the pipe server.
  169. * This will send a quit message to the client, wait for it to close for @a timeOutMilliseconds, and close the pipes.
  170. */
  171. void stopPipeServer(const uint32_t timeOutMilliseconds) noexcept;
  172. /*!
  173. * Close the pipes without waiting for the child process to terminate.
  174. */
  175. void closePipeServer() noexcept;
  176. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeServer)
  177. };
  178. // -----------------------------------------------------------------------
  179. // CarlaPipeClient class
  180. class CarlaPipeClient : public CarlaPipeCommon
  181. {
  182. public:
  183. /*!
  184. * Constructor.
  185. */
  186. CarlaPipeClient() noexcept;
  187. /*!
  188. * Destructor.
  189. */
  190. ~CarlaPipeClient() noexcept override;
  191. /*!
  192. * Initialize the pipes used by a server.
  193. * @a argv must match the arguments set the by server.
  194. */
  195. bool initPipeClient(const char* argv[]) noexcept;
  196. /*!
  197. * Close the pipes.
  198. */
  199. void closePipeClient() noexcept;
  200. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeClient)
  201. };
  202. // -----------------------------------------------------------------------
  203. // ScopedLocale class
  204. class ScopedLocale {
  205. public:
  206. ScopedLocale() noexcept;
  207. ~ScopedLocale() noexcept;
  208. private:
  209. const char* const fLocale;
  210. CARLA_DECLARE_NON_COPY_CLASS(ScopedLocale)
  211. CARLA_PREVENT_HEAP_ALLOCATION
  212. };
  213. // -----------------------------------------------------------------------
  214. #endif // CARLA_PIPE_UTILS_HPP_INCLUDED