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.

499 lines
12KB

  1. /*
  2. * Carla Pipe utils based on lv2fil UI code
  3. * Copyright (C) 2009 Nedko Arnaudov <nedko@arnaudov.name>
  4. * Copyright (C) 2013 Filipe Coelho <falktx@falktx.com>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License as
  8. * published by the Free Software Foundation; either version 2 of
  9. * the License, or any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * For a full copy of the GNU General Public License see the doc/GPL.txt file.
  17. */
  18. #ifndef CARLA_PIPE_UTILS_HPP_INCLUDED
  19. #define CARLA_PIPE_UTILS_HPP_INCLUDED
  20. #define WAIT_START_TIMEOUT 3000 /* ms */
  21. #define WAIT_ZOMBIE_TIMEOUT 3000 /* ms */
  22. #define WAIT_STEP 100 /* ms */
  23. #include "CarlaUtils.hpp"
  24. #include "CarlaString.hpp"
  25. #include <cerrno>
  26. #include <clocale>
  27. #include <fcntl.h>
  28. #include <signal.h>
  29. #include <sys/wait.h>
  30. // -----------------------------------------------------------------------
  31. class CarlaPipeServer
  32. {
  33. protected:
  34. CarlaPipeServer()
  35. : fPipeRecv(-1),
  36. fPipeSend(-1),
  37. fPid(-1),
  38. fReading(false)
  39. {
  40. carla_debug("CarlaPipeServer::CarlaPipeServer()");
  41. }
  42. // -------------------------------------------------------------------
  43. public:
  44. virtual ~CarlaPipeServer()
  45. {
  46. carla_debug("CarlaPipeServer::~CarlaPipeServer()");
  47. stop();
  48. }
  49. void start(const char* const filename, const char* const arg1, const char* const arg2)
  50. {
  51. CARLA_SAFE_ASSERT_RETURN(filename != nullptr,);
  52. CARLA_SAFE_ASSERT_RETURN(arg1 != nullptr,);
  53. CARLA_SAFE_ASSERT_RETURN(arg2 != nullptr,);
  54. carla_debug("CarlaPipeServer::start(\"%s\", \"%s\", \"%s\"", filename, arg1, arg2);
  55. //----------------------------------------------------------------
  56. const char* argv[5];
  57. //----------------------------------------------------------------
  58. // argv[0] => filename
  59. argv[0] = filename;
  60. //----------------------------------------------------------------
  61. // argv[1-2] => args
  62. argv[1] = arg1;
  63. argv[2] = arg2;
  64. //----------------------------------------------------------------
  65. // argv[3-4] => pipes
  66. int pipe1[2]; // written by host process, read by plugin UI process
  67. int pipe2[2]; // written by plugin UI process, read by host process
  68. if (pipe(pipe1) != 0)
  69. {
  70. fail("pipe1 creation failed");
  71. return;
  72. }
  73. if (pipe(pipe2) != 0)
  74. {
  75. fail("pipe2 creation failed");
  76. return;
  77. }
  78. char uiPipeRecv[100+1];
  79. char uiPipeSend[100+1];
  80. std::snprintf(uiPipeRecv, 100, "%d", pipe1[0]); /* [0] means reading end */
  81. std::snprintf(uiPipeSend, 100, "%d", pipe2[1]); /* [1] means writting end */
  82. uiPipeRecv[100] = '\0';
  83. uiPipeSend[100] = '\0';
  84. argv[3] = uiPipeRecv; // reading end
  85. argv[4] = uiPipeSend; // writting end
  86. //----------------------------------------------------------------
  87. // fork
  88. int ret = -1;
  89. if ((! fork_exec(argv, &ret)) || ret == -1)
  90. {
  91. close(pipe1[0]);
  92. close(pipe1[1]);
  93. close(pipe2[0]);
  94. close(pipe2[1]);
  95. fail("fork_exec() failed");
  96. return;
  97. }
  98. fPid = ret;
  99. /* fork duplicated the handles, close pipe ends that are used by the child process */
  100. close(pipe1[0]);
  101. close(pipe2[1]);
  102. fPipeSend = pipe1[1]; /* [1] means writting end */
  103. fPipeRecv = pipe2[0]; /* [0] means reading end */
  104. fcntl(fPipeRecv, F_SETFL, fcntl(fPipeRecv, F_GETFL) | O_NONBLOCK);
  105. //----------------------------------------------------------------
  106. // wait a while for child process to confirm it is alive
  107. char ch;
  108. for (int i=0; ;)
  109. {
  110. ssize_t ret2 = read(fPipeRecv, &ch, 1);
  111. switch (ret2)
  112. {
  113. case -1:
  114. if (errno == EAGAIN)
  115. {
  116. if (i < WAIT_START_TIMEOUT / WAIT_STEP)
  117. {
  118. carla_msleep(WAIT_STEP);
  119. i++;
  120. continue;
  121. }
  122. carla_stderr("we have waited for child with pid %d to appear for %.1f seconds and we are giving up", (int)fPid, (float)WAIT_START_TIMEOUT / 1000.0f);
  123. }
  124. else
  125. carla_stderr("read() failed: %s", strerror(errno));
  126. break;
  127. case 1:
  128. if (ch == '\n')
  129. // success
  130. return;
  131. carla_stderr("read() wrong first char '%c'", ch);
  132. break;
  133. default:
  134. carla_stderr("read() returned %d", ret2);
  135. break;
  136. }
  137. break;
  138. }
  139. carla_stderr("force killing misbehaved child %d (start)", (int)fPid);
  140. if (kill(fPid, SIGKILL) == -1)
  141. {
  142. carla_stderr("kill() failed: %s (start)\n", strerror(errno));
  143. }
  144. /* wait a while child to exit, we dont like zombie processes */
  145. wait_child(fPid);
  146. }
  147. void stop()
  148. {
  149. carla_debug("CarlaPipeServer::stop()");
  150. if (fPipeSend == -1 || fPipeRecv == -1 || fPid == -1)
  151. return;
  152. write(fPipeSend, "quit\n", 5);
  153. waitChildClose();
  154. close(fPipeRecv);
  155. close(fPipeSend);
  156. fPipeRecv = -1;
  157. fPipeSend = -1;
  158. fPid = -1;
  159. }
  160. void idle()
  161. {
  162. char* locale = nullptr;
  163. for (;;)
  164. {
  165. char* const msg = readline();
  166. if (msg == nullptr)
  167. break;
  168. if (locale == nullptr)
  169. {
  170. locale = strdup(setlocale(LC_NUMERIC, nullptr));
  171. setlocale(LC_NUMERIC, "POSIX");
  172. }
  173. fReading = true;
  174. msgReceived(msg);
  175. fReading = false;
  176. std::free(msg);
  177. }
  178. if (locale != nullptr)
  179. {
  180. setlocale(LC_NUMERIC, locale);
  181. std::free(locale);
  182. }
  183. }
  184. // -------------------------------------------------------------------
  185. bool readNextLineAsBool(bool& value)
  186. {
  187. if (! fReading)
  188. return false;
  189. if (char* const msg = readline())
  190. {
  191. value = (std::strcmp(msg, "true") == 0);
  192. std::free(msg);
  193. return true;
  194. }
  195. return false;
  196. }
  197. bool readNextLineAsInt(int& value)
  198. {
  199. if (! fReading)
  200. return false;
  201. if (char* const msg = readline())
  202. {
  203. value = std::atoi(msg);
  204. std::free(msg);
  205. return true;
  206. }
  207. return false;
  208. }
  209. bool readNextLineAsFloat(float& value)
  210. {
  211. if (! fReading)
  212. return false;
  213. if (char* const msg = readline())
  214. {
  215. bool ret = (std::sscanf(msg, "%f", &value) == 1);
  216. std::free(msg);
  217. return ret;
  218. }
  219. return false;
  220. }
  221. bool readNextLineAsString(char*& value)
  222. {
  223. if (! fReading)
  224. return false;
  225. if (char* const msg = readline())
  226. {
  227. value = msg;
  228. return true;
  229. }
  230. return false;
  231. }
  232. void writeMsg(const char* const msg)
  233. {
  234. ::write(fPipeSend, msg, std::strlen(msg));
  235. }
  236. void writeMsg(const char* const msg, size_t size)
  237. {
  238. ::write(fPipeSend, msg, size);
  239. }
  240. void writeAndFixMsg(const char* const msg)
  241. {
  242. const size_t size = std::strlen(msg);
  243. char smsg[size+1];
  244. std::strcpy(smsg, msg);
  245. smsg[size-1] = '\n';
  246. smsg[size] = '\0';
  247. for (size_t i=0; i<size; ++i)
  248. {
  249. if (smsg[i] == '\n')
  250. smsg[i] = '\r';
  251. }
  252. ::write(fPipeSend, smsg, size+1);
  253. }
  254. void waitChildClose()
  255. {
  256. if (! wait_child(fPid))
  257. {
  258. carla_stderr2("force killing misbehaved child %d (exit)", (int)fPid);
  259. if (kill(fPid, SIGKILL) == -1)
  260. carla_stderr2("kill() failed: %s (exit)", strerror(errno));
  261. else
  262. wait_child(fPid);
  263. }
  264. }
  265. // -------------------------------------------------------------------
  266. protected:
  267. virtual void fail(const char* const error)
  268. {
  269. carla_stderr2(error);
  270. }
  271. virtual void msgReceived(const char* const msg) = 0;
  272. // -------------------------------------------------------------------
  273. private:
  274. int fPipeRecv; // the pipe end that is used for receiving messages from UI
  275. int fPipeSend; // the pipe end that is used for sending messages to UI
  276. pid_t fPid;
  277. bool fReading;
  278. CarlaString fTempBuf;
  279. // -------------------------------------------------------------------
  280. char* readline()
  281. {
  282. char ch;
  283. ssize_t ret;
  284. char buf[0xff+1];
  285. char* ptr = buf;
  286. fTempBuf.clear();
  287. buf[0xff] = '\0';
  288. for (int i=0;; ++i)
  289. {
  290. ret = read(fPipeRecv, &ch, 1);
  291. if (ret == 1 && ch != '\n')
  292. {
  293. if (ch == '\r')
  294. ch = '\n';
  295. *ptr++ = ch;
  296. if (i+1 == 0xff)
  297. {
  298. i = 0;
  299. ptr = buf;
  300. fTempBuf += buf;
  301. }
  302. continue;
  303. }
  304. if (fTempBuf.isNotEmpty() || ptr != buf)
  305. {
  306. if (ptr != buf)
  307. {
  308. *ptr = '\0';
  309. fTempBuf += buf;
  310. }
  311. return strdup((const char*)fTempBuf);
  312. }
  313. break;
  314. }
  315. return nullptr;
  316. }
  317. static bool fork_exec(const char* const argv[5], int* const retp)
  318. {
  319. pid_t ret = *retp = vfork();
  320. switch (ret)
  321. {
  322. case 0: /* child process */
  323. execlp(argv[0], argv[0], argv[1], argv[2], argv[3], argv[4], nullptr);
  324. carla_stderr2("exec of UI failed: %s", std::strerror(errno));
  325. return false;
  326. case -1: /* error */
  327. carla_stderr2("vfork() failed: %s", std::strerror(errno));
  328. return false;
  329. }
  330. return true;
  331. }
  332. static bool wait_child(const pid_t pid)
  333. {
  334. pid_t ret;
  335. int i;
  336. if (pid == -1)
  337. {
  338. carla_stderr2("Can't wait for pid -1");
  339. return false;
  340. }
  341. for (i = 0; i < WAIT_ZOMBIE_TIMEOUT / WAIT_STEP; ++i)
  342. {
  343. ret = waitpid(pid, nullptr, WNOHANG);
  344. if (ret != 0)
  345. {
  346. if (ret == pid)
  347. return true;
  348. if (ret == -1)
  349. {
  350. carla_stderr2("waitpid(%d) failed: %s", (int)pid, strerror(errno));
  351. return false;
  352. }
  353. carla_stderr2("we have waited for child pid %d to exit but we got pid %d instead", (int)pid, (int)ret);
  354. return false;
  355. }
  356. carla_msleep(WAIT_STEP); /* wait 100 ms */
  357. }
  358. carla_stderr2("we have waited for child with pid %d to exit for %.1f seconds and we are giving up", (int)pid, (float)WAIT_START_TIMEOUT / 1000.0f);
  359. return false;
  360. }
  361. };
  362. // -----------------------------------------------------------------------
  363. class CarlaPipeClient
  364. {
  365. protected:
  366. CarlaPipeClient()
  367. {
  368. carla_debug("CarlaPipeClient::CarlaPipeClient()");
  369. }
  370. // -------------------------------------------------------------------
  371. public:
  372. virtual ~CarlaPipeClient()
  373. {
  374. carla_debug("CarlaPipeClient::~CarlaPipeClient()");
  375. stop();
  376. }
  377. void stop()
  378. {
  379. }
  380. };
  381. // -----------------------------------------------------------------------
  382. #endif // CARLA_PIPE_UTILS_HPP_INCLUDED