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 18KB

11 years ago
11 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
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
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
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
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
11 years ago
11 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
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
11 years ago
11 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
11 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
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 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
11 years ago
10 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
11 years ago
10 years ago
11 years ago
11 years ago
10 years ago
11 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
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
10 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
11 years ago
11 years ago
11 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
11 years ago
11 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
10 years ago
10 years ago
11 years ago
10 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
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. /*
  2. * Carla Pipe utils based on lv2fil UI code
  3. * Copyright (C) 2009 Nedko Arnaudov <nedko@arnaudov.name>
  4. * Copyright (C) 2013-2014 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. #include "CarlaMutex.hpp"
  21. #include "CarlaString.hpp"
  22. #include <cerrno>
  23. #include <clocale>
  24. #include <fcntl.h>
  25. #include <signal.h>
  26. #include <sys/wait.h>
  27. #define WAIT_START_TIMEOUT 3000 /* ms */
  28. #define WAIT_ZOMBIE_TIMEOUT 3000 /* ms */
  29. #define WAIT_STEP 100 /* ms */
  30. // -----------------------------------------------------------------------
  31. struct ScopedLocale {
  32. const char* locale;
  33. ScopedLocale() noexcept
  34. : locale(carla_strdup_safe(::setlocale(LC_NUMERIC, nullptr)))
  35. {
  36. ::setlocale(LC_NUMERIC, "C");
  37. }
  38. ~ScopedLocale() noexcept
  39. {
  40. if (locale != nullptr)
  41. {
  42. ::setlocale(LC_NUMERIC, locale);
  43. delete[] locale;
  44. locale = nullptr;
  45. }
  46. }
  47. CARLA_DECLARE_NON_COPY_STRUCT(ScopedLocale)
  48. CARLA_PREVENT_HEAP_ALLOCATION
  49. };
  50. // -----------------------------------------------------------------------
  51. class CarlaPipeServer
  52. {
  53. protected:
  54. CarlaPipeServer()
  55. : fWriteLock(),
  56. fPipeRecv(-1),
  57. fPipeSend(-1),
  58. fIsReading(false),
  59. fPid(-1),
  60. fTmpStr()
  61. {
  62. carla_debug("CarlaPipeServer::CarlaPipeServer()");
  63. carla_zeroChar(fTmpBuf, 0xff+1);
  64. }
  65. // -------------------------------------------------------------------
  66. public:
  67. virtual ~CarlaPipeServer()
  68. {
  69. carla_debug("CarlaPipeServer::~CarlaPipeServer()");
  70. stop();
  71. }
  72. bool isOk() const noexcept
  73. {
  74. return (fPipeRecv != -1 && fPipeSend != -1 && fPid != -1);
  75. }
  76. bool start(const char* const filename, const char* const arg1, const char* const arg2) noexcept
  77. {
  78. CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
  79. CARLA_SAFE_ASSERT_RETURN(arg1 != nullptr, false);
  80. CARLA_SAFE_ASSERT_RETURN(arg2 != nullptr, false);
  81. carla_debug("CarlaPipeServer::start(\"%s\", \"%s\", \"%s\")", filename, arg1, arg2);
  82. const CarlaMutexLocker cml(fWriteLock);
  83. //----------------------------------------------------------------
  84. const char* argv[6];
  85. //----------------------------------------------------------------
  86. // argv[0] => filename
  87. argv[0] = filename;
  88. //----------------------------------------------------------------
  89. // argv[1-2] => args
  90. argv[1] = arg1;
  91. argv[2] = arg2;
  92. //----------------------------------------------------------------
  93. // argv[3-4] => pipes
  94. int pipe1[2]; // written by host process, read by plugin UI process
  95. int pipe2[2]; // written by plugin UI process, read by host process
  96. if (::pipe(pipe1) != 0)
  97. {
  98. fail("pipe1 creation failed");
  99. return false;
  100. }
  101. if (::pipe(pipe2) != 0)
  102. {
  103. try { ::close(pipe1[0]); } catch (...) {}
  104. try { ::close(pipe1[1]); } catch (...) {}
  105. fail("pipe2 creation failed");
  106. return false;
  107. }
  108. char pipeRecv[100+1];
  109. char pipeSend[100+1];
  110. std::snprintf(pipeRecv, 100, "%d", pipe1[0]); // [0] means reading end
  111. std::snprintf(pipeSend, 100, "%d", pipe2[1]); // [1] means writting end
  112. pipeRecv[100] = '\0';
  113. pipeSend[100] = '\0';
  114. argv[3] = pipeRecv; // reading end
  115. argv[4] = pipeSend; // writting end
  116. //----------------------------------------------------------------
  117. // argv[5] => null
  118. argv[5] = nullptr;
  119. //----------------------------------------------------------------
  120. // fork
  121. int ret = -1;
  122. if ((! fork_exec(argv, &ret)) || ret == -1)
  123. {
  124. try { ::close(pipe1[0]); } catch (...) {}
  125. try { ::close(pipe1[1]); } catch (...) {}
  126. try { ::close(pipe2[0]); } catch (...) {}
  127. try { ::close(pipe2[1]); } catch (...) {}
  128. fail("fork_exec() failed");
  129. return false;
  130. }
  131. fPid = ret;
  132. // fork duplicated the handles, close pipe ends that are used by the child process
  133. try { ::close(pipe1[0]); } catch(...) {}
  134. try { ::close(pipe2[1]); } catch(...) {}
  135. fPipeSend = pipe1[1]; // [1] means writting end
  136. fPipeRecv = pipe2[0]; // [0] means reading end
  137. // set non-block
  138. try {
  139. ret = ::fcntl(fPipeRecv, F_SETFL, ::fcntl(fPipeRecv, F_GETFL) | O_NONBLOCK);
  140. } catch (...) {
  141. ret = -1;
  142. fail("failed to set pipe as non-block");
  143. }
  144. //----------------------------------------------------------------
  145. // wait a while for child process to confirm it is alive
  146. if (ret != -1)
  147. {
  148. char ch;
  149. ssize_t ret2;
  150. for (int i=0; ;)
  151. {
  152. try {
  153. ret2 = ::read(fPipeRecv, &ch, 1);
  154. }
  155. catch (...) {
  156. fail("failed to read from pipe");
  157. break;
  158. }
  159. switch (ret2)
  160. {
  161. case -1:
  162. if (errno == EAGAIN)
  163. {
  164. if (i < WAIT_START_TIMEOUT / WAIT_STEP)
  165. {
  166. carla_msleep(WAIT_STEP);
  167. ++i;
  168. continue;
  169. }
  170. 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);
  171. }
  172. else
  173. {
  174. CarlaString error(std::strerror(errno));
  175. carla_stderr("read() failed: %s", error.buffer());
  176. }
  177. break;
  178. case 1:
  179. if (ch == '\n') {
  180. // success
  181. return true;
  182. }
  183. carla_stderr("read() has wrong first char '%c'", ch);
  184. break;
  185. default:
  186. carla_stderr("read() returned %i", int(ret2));
  187. break;
  188. }
  189. break;
  190. }
  191. }
  192. carla_stderr("force killing misbehaved child %i (start)", int(fPid));
  193. if (kill(fPid, SIGKILL) == -1)
  194. {
  195. CarlaString error(std::strerror(errno));
  196. carla_stderr("kill() failed: %s (start)\n", error.buffer());
  197. }
  198. // wait a while child to exit, we dont like zombie processes
  199. wait_child(fPid);
  200. // close pipes
  201. try { ::close(fPipeRecv); } catch (...) {}
  202. try { ::close(fPipeSend); } catch (...) {}
  203. fPipeRecv = -1;
  204. fPipeSend = -1;
  205. fPid = -1;
  206. return false;
  207. }
  208. void stop() noexcept
  209. {
  210. carla_debug("CarlaPipeServer::stop()");
  211. if (fPipeSend == -1 || fPipeRecv == -1 || fPid == -1)
  212. return;
  213. const CarlaMutexLocker cml(fWriteLock);
  214. try {
  215. ssize_t ignore = ::write(fPipeSend, "quit\n", 5);
  216. (void)ignore;
  217. } CARLA_SAFE_EXCEPTION("CarlaPipeServer::stop");
  218. waitChildClose();
  219. try { ::close(fPipeRecv); } catch (...) {}
  220. try { ::close(fPipeSend); } catch (...) {}
  221. fPipeRecv = -1;
  222. fPipeSend = -1;
  223. fPid = -1;
  224. }
  225. void idle()
  226. {
  227. const char* locale = nullptr;
  228. for (;;)
  229. {
  230. const char* const msg(readline());
  231. if (msg == nullptr)
  232. break;
  233. if (locale == nullptr)
  234. {
  235. locale = carla_strdup(::setlocale(LC_NUMERIC, nullptr));
  236. ::setlocale(LC_NUMERIC, "C");
  237. }
  238. fIsReading = true;
  239. msgReceived(msg);
  240. fIsReading = false;
  241. delete[] msg;
  242. }
  243. if (locale != nullptr)
  244. {
  245. ::setlocale(LC_NUMERIC, locale);
  246. delete[] locale;
  247. }
  248. }
  249. // -------------------------------------------------------------------
  250. bool readNextLineAsBool(bool& value) noexcept
  251. {
  252. CARLA_SAFE_ASSERT_RETURN(fIsReading, false);
  253. if (const char* const msg = readline())
  254. {
  255. value = (std::strcmp(msg, "true") == 0);
  256. delete[] msg;
  257. return true;
  258. }
  259. return false;
  260. }
  261. bool readNextLineAsInt(int32_t& value) noexcept
  262. {
  263. CARLA_SAFE_ASSERT_RETURN(fIsReading, false);
  264. if (const char* const msg = readline())
  265. {
  266. value = std::atoi(msg);
  267. delete[] msg;
  268. return true;
  269. }
  270. return false;
  271. }
  272. bool readNextLineAsUInt(uint32_t& value) noexcept
  273. {
  274. CARLA_SAFE_ASSERT_RETURN(fIsReading, false);
  275. if (const char* const msg = readline())
  276. {
  277. int32_t tmp = std::atoi(msg);
  278. delete[] msg;
  279. if (tmp >= 0)
  280. {
  281. value = static_cast<uint32_t>(tmp);
  282. return true;
  283. }
  284. }
  285. return false;
  286. }
  287. bool readNextLineAsLong(int64_t& value) noexcept
  288. {
  289. CARLA_SAFE_ASSERT_RETURN(fIsReading, false);
  290. if (const char* const msg = readline())
  291. {
  292. value = std::atol(msg);
  293. delete[] msg;
  294. return true;
  295. }
  296. return false;
  297. }
  298. bool readNextLineAsULong(uint64_t& value) noexcept
  299. {
  300. CARLA_SAFE_ASSERT_RETURN(fIsReading, false);
  301. if (const char* const msg = readline())
  302. {
  303. int64_t tmp = std::atol(msg);
  304. delete[] msg;
  305. if (tmp >= 0)
  306. {
  307. value = static_cast<uint64_t>(tmp);
  308. return true;
  309. }
  310. }
  311. return false;
  312. }
  313. bool readNextLineAsFloat(float& value) noexcept
  314. {
  315. CARLA_SAFE_ASSERT_RETURN(fIsReading, false);
  316. if (const char* const msg = readline())
  317. {
  318. const bool ret(std::sscanf(msg, "%f", &value) == 1);
  319. delete[] msg;
  320. return ret;
  321. }
  322. return false;
  323. }
  324. bool readNextLineAsString(const char*& value) noexcept
  325. {
  326. CARLA_SAFE_ASSERT_RETURN(fIsReading, false);
  327. if (const char* const msg = readline())
  328. {
  329. value = msg;
  330. return true;
  331. }
  332. return false;
  333. }
  334. // -------------------------------------------------------------------
  335. // must be locked before calling
  336. void writeMsg(const char* const msg) const noexcept
  337. {
  338. CARLA_SAFE_ASSERT_RETURN(fPipeSend != -1,);
  339. // TESTING remove later
  340. const bool wasLocked(! fWriteLock.tryLock());
  341. CARLA_SAFE_ASSERT_RETURN(wasLocked, fWriteLock.unlock());
  342. try {
  343. ssize_t ignore = ::write(fPipeSend, msg, std::strlen(msg));
  344. (void)ignore;
  345. } CARLA_SAFE_EXCEPTION("CarlaPipeServer::writeMsg");
  346. }
  347. void writeMsg(const char* const msg, size_t size) const noexcept
  348. {
  349. CARLA_SAFE_ASSERT_RETURN(fPipeSend != -1,);
  350. // TESTING remove later
  351. const bool wasLocked(! fWriteLock.tryLock());
  352. CARLA_SAFE_ASSERT_RETURN(wasLocked, fWriteLock.unlock());
  353. try {
  354. ssize_t ignore = ::write(fPipeSend, msg, size);
  355. (void)ignore;
  356. } CARLA_SAFE_EXCEPTION("CarlaPipeServer::writeMsg");
  357. }
  358. void writeAndFixMsg(const char* const msg) noexcept
  359. {
  360. CARLA_SAFE_ASSERT_RETURN(fPipeSend != -1,);
  361. // TESTING remove later
  362. const bool wasLocked(! fWriteLock.tryLock());
  363. CARLA_SAFE_ASSERT_RETURN(wasLocked, fWriteLock.unlock());
  364. const size_t size(msg != nullptr ? std::strlen(msg) : 0);
  365. char fixedMsg[size+2];
  366. if (size > 0)
  367. {
  368. std::strcpy(fixedMsg, msg);
  369. for (size_t i=0; i < size; ++i)
  370. {
  371. if (fixedMsg[i] == '\n')
  372. fixedMsg[i] = '\r';
  373. }
  374. if (fixedMsg[size-1] == '\r')
  375. {
  376. fixedMsg[size-1] = '\n';
  377. fixedMsg[size] = '\0';
  378. fixedMsg[size+1] = '\0';
  379. }
  380. else
  381. {
  382. fixedMsg[size] = '\n';
  383. fixedMsg[size+1] = '\0';
  384. }
  385. }
  386. else
  387. {
  388. fixedMsg[0] = '\n';
  389. fixedMsg[1] = '\0';
  390. }
  391. try {
  392. ssize_t ignore = ::write(fPipeSend, fixedMsg, size+1);
  393. (void)ignore;
  394. } CARLA_SAFE_EXCEPTION("CarlaPipeServer::writeAndFixMsg");
  395. }
  396. // -------------------------------------------------------------------
  397. void waitChildClose() noexcept
  398. {
  399. if (! wait_child(fPid))
  400. {
  401. carla_stderr2("force killing misbehaved child %i (exit)", int(fPid));
  402. if (kill(fPid, SIGKILL) == -1)
  403. carla_stderr2("kill() failed: %s (exit)", std::strerror(errno));
  404. else
  405. wait_child(fPid);
  406. }
  407. }
  408. // -------------------------------------------------------------------
  409. protected:
  410. // common write lock
  411. CarlaMutex fWriteLock;
  412. // to possibly send errors somewhere
  413. virtual void fail(const char* const error)
  414. {
  415. carla_stderr2(error);
  416. }
  417. // returns true if msg handled
  418. virtual bool msgReceived(const char* const msg) noexcept = 0;
  419. // -------------------------------------------------------------------
  420. private:
  421. int fPipeRecv; // the pipe end that is used for receiving messages from UI
  422. int fPipeSend; // the pipe end that is used for sending messages to UI
  423. bool fIsReading;
  424. pid_t fPid;
  425. char fTmpBuf[0xff+1];
  426. CarlaString fTmpStr;
  427. // -------------------------------------------------------------------
  428. const char* readline() noexcept
  429. {
  430. char ch;
  431. char* ptr = fTmpBuf;
  432. ssize_t ret;
  433. fTmpStr.clear();
  434. for (int i=0; i < 0xff; ++i)
  435. {
  436. try {
  437. ret = ::read(fPipeRecv, &ch, 1);
  438. }
  439. catch (...) {
  440. break;
  441. }
  442. if (ret == 1 && ch != '\n')
  443. {
  444. if (ch == '\r')
  445. ch = '\n';
  446. *ptr++ = ch;
  447. if (i+1 == 0xff)
  448. {
  449. i = 0;
  450. ptr = fTmpBuf;
  451. fTmpStr += fTmpBuf;
  452. }
  453. continue;
  454. }
  455. if (fTmpStr.isNotEmpty() || ptr != fTmpBuf)
  456. {
  457. if (ptr != fTmpBuf)
  458. {
  459. *ptr = '\0';
  460. fTmpStr += fTmpBuf;
  461. }
  462. try {
  463. return fTmpStr.dup();
  464. }
  465. catch(...) {
  466. return nullptr;
  467. }
  468. }
  469. break;
  470. }
  471. return nullptr;
  472. }
  473. // -------------------------------------------------------------------
  474. static bool fork_exec(const char* const argv[6], int* const retp) noexcept
  475. {
  476. const pid_t ret = *retp = vfork();
  477. switch (ret)
  478. {
  479. case 0: // child process
  480. execvp(argv[0], const_cast<char* const*>(argv));
  481. carla_stderr2("exec failed: %s", std::strerror(errno));
  482. _exit(0); // this is not noexcept safe but doesn't matter anyway
  483. return false;
  484. case -1: // error
  485. carla_stderr2("fork() failed: %s", std::strerror(errno));
  486. _exit(0); // this is not noexcept safe but doesn't matter anyway
  487. return false;
  488. }
  489. return true;
  490. }
  491. static bool wait_child(const pid_t pid) noexcept
  492. {
  493. if (pid <= 0)
  494. {
  495. carla_stderr2("Can't wait for pid %i", int(pid));
  496. return false;
  497. }
  498. pid_t ret;
  499. for (int i=0, maxTime=WAIT_ZOMBIE_TIMEOUT/WAIT_STEP; i < maxTime; ++i)
  500. {
  501. try {
  502. ret = ::waitpid(pid, nullptr, WNOHANG);
  503. } CARLA_SAFE_EXCEPTION_BREAK("wait_child");
  504. if (ret != 0)
  505. {
  506. if (ret == pid)
  507. return true;
  508. if (ret == -1)
  509. {
  510. if (errno == ECHILD)
  511. return true;
  512. CarlaString error(std::strerror(errno));
  513. carla_stderr2("waitpid(%i) failed: %s", int(pid), error.buffer());
  514. return false;
  515. }
  516. carla_stderr2("we waited for child pid %i to exit but we got pid %i instead", int(pid), int(ret));
  517. return false;
  518. }
  519. carla_msleep(WAIT_STEP); /* wait 100 ms */
  520. }
  521. carla_stderr2("we waited for child with pid %i to exit for %.1f seconds and we are giving up", int(pid), float(WAIT_START_TIMEOUT)/1000.0f);
  522. return false;
  523. }
  524. };
  525. // -----------------------------------------------------------------------
  526. #endif // CARLA_PIPE_UTILS_HPP_INCLUDED