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.

265 lines
6.8KB

  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() 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) noexcept;
  83. /*!
  84. * Read the next line as an integer.
  85. */
  86. bool readNextLineAsInt(int32_t& value) noexcept;
  87. /*!
  88. * Read the next line as an unsigned integer.
  89. */
  90. bool readNextLineAsUInt(uint32_t& value) noexcept;
  91. /*!
  92. * Read the next line as a long integer.
  93. */
  94. bool readNextLineAsLong(int64_t& value) noexcept;
  95. /*!
  96. * Read the next line as a long unsigned integer.
  97. */
  98. bool readNextLineAsULong(uint64_t& value) noexcept;
  99. /*!
  100. * Read the next line as a floating point number (single precision).
  101. */
  102. bool readNextLineAsFloat(float& value) noexcept;
  103. /*!
  104. * Read the next line as a floating point number (double precision).
  105. */
  106. bool readNextLineAsDouble(double& value) noexcept;
  107. /*!
  108. * Read the next line as a string.
  109. * @note: @a value must be deleted if valid.
  110. */
  111. bool readNextLineAsString(const char*& value) noexcept;
  112. // -------------------------------------------------------------------
  113. // write messages, must be locked before calling
  114. /*!
  115. * Write a valid message with unknown size.
  116. * A valid message has only one '\n' character and it's at the end.
  117. */
  118. bool writeMessage(const char* const msg) const noexcept;
  119. /*!
  120. * Write a valid message with known size.
  121. * A valid message has only one '\n' character and it's at the end.
  122. */
  123. bool writeMessage(const char* const msg, std::size_t size) const noexcept;
  124. /*!
  125. * Write and fix a message.
  126. */
  127. bool writeAndFixMessage(const char* const msg) const noexcept;
  128. /*!
  129. * Flush all messages currently in cache.
  130. */
  131. bool flushMessages() const noexcept;
  132. // -------------------------------------------------------------------
  133. protected:
  134. struct PrivateData;
  135. PrivateData* const pData;
  136. // -------------------------------------------------------------------
  137. /*! @internal */
  138. const char* _readline() noexcept;
  139. /*! @internal */
  140. const char* _readlineblock(const uint32_t timeOutMilliseconds = 50) noexcept;
  141. /*! @internal */
  142. bool _writeMsgBuffer(const char* const msg, const std::size_t size) const noexcept;
  143. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeCommon)
  144. };
  145. // -----------------------------------------------------------------------
  146. // CarlaPipeServer class
  147. class CarlaPipeServer : public CarlaPipeCommon
  148. {
  149. public:
  150. /*!
  151. * Constructor.
  152. */
  153. CarlaPipeServer() noexcept;
  154. /*!
  155. * Destructor.
  156. */
  157. ~CarlaPipeServer() noexcept override;
  158. /*!
  159. * Start the pipe server using @a filename with 2 arguments.
  160. * @see fail()
  161. */
  162. bool startPipeServer(const char* const filename, const char* const arg1, const char* const arg2) noexcept;
  163. /*!
  164. * Stop the pipe server.
  165. * This will send a quit message to the client, wait for it to close for @a timeOutMilliseconds, and close the pipes.
  166. */
  167. void stopPipeServer(const uint32_t timeOutMilliseconds) noexcept;
  168. /*!
  169. * Close the pipes without waiting for the child process to terminate.
  170. */
  171. void closePipeServer() noexcept;
  172. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeServer)
  173. };
  174. // -----------------------------------------------------------------------
  175. // CarlaPipeClient class
  176. class CarlaPipeClient : public CarlaPipeCommon
  177. {
  178. public:
  179. /*!
  180. * Constructor.
  181. */
  182. CarlaPipeClient() noexcept;
  183. /*!
  184. * Destructor.
  185. */
  186. ~CarlaPipeClient() noexcept override;
  187. /*!
  188. * Initialize the pipes used by a server.
  189. * @a argv must match the arguments set the by server.
  190. */
  191. bool initPipeClient(const char* argv[]) noexcept;
  192. /*!
  193. * Close the pipes.
  194. */
  195. void closePipeClient() noexcept;
  196. CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeClient)
  197. };
  198. // -----------------------------------------------------------------------
  199. // ScopedLocale class
  200. class ScopedLocale {
  201. public:
  202. ScopedLocale() noexcept;
  203. ~ScopedLocale() noexcept;
  204. private:
  205. const char* const fLocale;
  206. CARLA_DECLARE_NON_COPY_CLASS(ScopedLocale)
  207. CARLA_PREVENT_HEAP_ALLOCATION
  208. };
  209. // -----------------------------------------------------------------------
  210. #endif // CARLA_PIPE_UTILS_HPP_INCLUDED