LMMS
Loading...
Searching...
No Matches
CarlaPipeUtils.cpp
Go to the documentation of this file.
1/*
2 * Carla Pipe Utilities
3 * Copyright (C) 2013-2024 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
18#include "CarlaPipeUtils.hpp"
19#include "CarlaProcessUtils.hpp"
20#include "CarlaString.hpp"
21#include "CarlaTimeUtils.hpp"
22#include "CarlaMIDI.h"
23
24// needed for atom-util
25#ifndef nullptr
26# undef NULL
27# define NULL nullptr
28#endif
29
30#ifdef BUILDING_CARLA
31# include "lv2/atom-util.h"
32#else
33# include "lv2/atom/util.h"
34#endif
35
36#include <fcntl.h>
37
38#ifdef CARLA_OS_WIN
39# include "water/text/String.h"
40# include <ctime>
41#else
42# include <cerrno>
43# include <signal.h>
44# include <sys/wait.h>
45# ifdef CARLA_OS_LINUX
46# include <sys/prctl.h>
47# ifndef F_SETPIPE_SZ
48# define F_SETPIPE_SZ 1031
49# endif
50# endif
51#endif
52
53#ifdef CARLA_OS_WIN
54# define INVALID_PIPE_VALUE INVALID_HANDLE_VALUE
55#else
56# define INVALID_PIPE_VALUE -1
57#endif
58
59#ifdef CARLA_OS_WIN
60// -----------------------------------------------------------------------
61// win32 stuff
62
63static inline
64bool waitForAsyncObject(const HANDLE object, const HANDLE process = INVALID_HANDLE_VALUE)
65{
66 DWORD dw, dw2;
67 MSG msg;
68
69 // we give it a max
70 for (int i=20000; --i>=0;)
71 {
72 if (process != INVALID_HANDLE_VALUE)
73 {
75 {
76 case WAIT_OBJECT_0:
77 case WAIT_FAILED:
78 carla_stderr("waitForAsyncObject process has stopped");
79 return false;
80 }
81 }
82
83 carla_debug("waitForAsyncObject loop start");
84 dw = ::MsgWaitForMultipleObjectsEx(1, &object, INFINITE, QS_POSTMESSAGE|QS_TIMER, 0);
85 carla_debug("waitForAsyncObject initial code is: %u", dw);
86
87 if (dw == WAIT_OBJECT_0)
88 {
89 carla_debug("waitForAsyncObject WAIT_OBJECT_0");
90 return true;
91 }
92
93 dw2 = ::GetLastError();
94
95 if (dw == WAIT_OBJECT_0 + 1)
96 {
97 carla_debug("waitForAsyncObject loop +1");
98
99 while (::PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
100 ::DispatchMessage(&msg);
101
102 continue;
103 }
104
105 if (dw2 == 0)
106 {
107 carla_debug("waitForAsyncObject loop stop");
108 return true;
109 }
110
111 carla_stderr2("waitForAsyncObject loop end reached, error was: %u", dw2);
112 carla_msleep(5);
113 }
114
115 carla_stderr2("waitForAsyncObject reached the end, this should not happen");
116 return false;
117}
118
119static inline
120ssize_t ReadFileWin32(const HANDLE pipeh, const HANDLE event, void* const buf, const DWORD numBytes)
121{
122 DWORD dw, dsize = numBytes;
123 DWORD available = 0;
124
125 if (::PeekNamedPipe(pipeh, nullptr, 0, nullptr, &available, nullptr) == FALSE || available == 0)
126 return -1;
127
128 OVERLAPPED ov;
129 carla_zeroStruct(ov);
130 ov.hEvent = event;
131
132 if (::ReadFile(pipeh, buf, dsize, nullptr, &ov))
133 {
134 if (! ::GetOverlappedResult(pipeh, &ov, &dw, FALSE))
135 {
136 carla_stderr("ReadFileWin32 GetOverlappedResult failed, error was: %u", ::GetLastError());
137 return -1;
138 }
139
140 return static_cast<ssize_t>(dsize);
141 }
142
143 dw = ::GetLastError();
144
145 if (dw == ERROR_IO_PENDING)
146 {
147 if (! waitForAsyncObject(event))
148 {
149 carla_stderr("ReadFileWin32 waitForAsyncObject failed, error was: %u", ::GetLastError());
150 return -1;
151 }
152
153 if (! ::GetOverlappedResult(pipeh, &ov, &dw, FALSE))
154 {
155 carla_stderr("ReadFileWin32 GetOverlappedResult of pending failed, error was: %u", ::GetLastError());
156 return -1;
157 }
158
159 return static_cast<ssize_t>(dsize);
160 }
161
162 carla_stderr("ReadFileWin32 failed, error was: %u", dw);
163 return -1;
164}
165
166static inline
167ssize_t WriteFileWin32(const HANDLE pipeh, const HANDLE event, const void* const buf, const DWORD numBytes)
168{
169 DWORD dw, dsize = numBytes;
170
171 OVERLAPPED ov;
172 carla_zeroStruct(ov);
173 ov.hEvent = event;
174
175 if (::WriteFile(pipeh, buf, dsize, nullptr, &ov))
176 {
177 if (! ::GetOverlappedResult(pipeh, &ov, &dw, FALSE))
178 {
179 carla_stderr("WriteFileWin32 GetOverlappedResult failed, error was: %u", ::GetLastError());
180 return -1;
181 }
182
183 return static_cast<ssize_t>(dsize);
184 }
185
186 dw = ::GetLastError();
187
188 if (dw == ERROR_IO_PENDING)
189 {
190 if (! waitForAsyncObject(event))
191 {
192 carla_stderr("WriteFileWin32 waitForAsyncObject failed, error was: %u", ::GetLastError());
193 return -1;
194 }
195
196 if (! ::GetOverlappedResult(pipeh, &ov, &dw, FALSE))
197 {
198 carla_stderr("WriteFileWin32 GetOverlappedResult of pending failed, error was: %u", ::GetLastError());
199 return -1;
200 }
201
202 return static_cast<ssize_t>(dsize);
203 }
204
205 if (dw == ERROR_PIPE_NOT_CONNECTED)
206 {
207 carla_stdout("WriteFileWin32 failed, client has closed");
208 return -2;
209 }
210
211 carla_stderr("WriteFileWin32 failed, error was: %u", dw);
212 return -1;
213}
214#endif // CARLA_OS_WIN
215
216// -----------------------------------------------------------------------
217// startProcess
218
219#ifdef CARLA_OS_WIN
220static inline
221bool startProcess(const char* const argv[], PROCESS_INFORMATION* const processInfo)
222{
223 CARLA_SAFE_ASSERT_RETURN(processInfo != nullptr, false);
224
225 using water::String;
226
227 String command;
228
229 for (int i=0; argv[i] != nullptr; ++i)
230 {
231 String arg(argv[i]);
232
233 // If there are spaces, surround it with quotes. If there are quotes,
234 // replace them with \" so that CommandLineToArgv will correctly parse them.
235 if (arg.containsAnyOf("\" "))
236 arg = arg.replace("\"", "\\\"").quoted();
237
238 command << arg << ' ';
239 }
240
241 command = command.trim();
242
243 STARTUPINFOA startupInfo;
244 carla_zeroStruct(startupInfo);
245 startupInfo.cb = sizeof(startupInfo);
246
247 if (::CreateProcessA(nullptr, const_cast<LPSTR>(command.toRawUTF8()),
248 nullptr, nullptr, TRUE, CREATE_NO_WINDOW | CREATE_UNICODE_ENVIRONMENT,
249 nullptr, nullptr, &startupInfo, processInfo) != FALSE)
250 return true;
251
252 carla_stderr2("startProcess failed, error was: %u", ::GetLastError());
253 return false;
254}
255
256static inline
257bool waitForClientConnect(const HANDLE pipe, const HANDLE event, const HANDLE process, const uint32_t timeOutMilliseconds) noexcept
258{
260 CARLA_SAFE_ASSERT_RETURN(timeOutMilliseconds > 0, false);
261
262 DWORD dw;
263
264 OVERLAPPED ov;
265 carla_zeroStruct(ov);
266 ov.hEvent = event;
267
268 const uint32_t timeoutEnd = carla_gettime_ms() + timeOutMilliseconds;
269
270 for (;;)
271 {
272 if (::ConnectNamedPipe(pipe, &ov))
273 {
274 if (! ::GetOverlappedResult(pipe, &ov, &dw, FALSE))
275 {
276 carla_stderr2("ConnectNamedPipe GetOverlappedResult failed, error was: %u", ::GetLastError());
277 return false;
278 }
279
280 return true;
281 }
282
283 const DWORD err = ::GetLastError();
284
285 switch (err)
286 {
287 case ERROR_PIPE_CONNECTED:
288 return true;
289
290 case ERROR_IO_PENDING:
291 if (! waitForAsyncObject(event, process))
292 {
293 carla_stderr2("ConnectNamedPipe waitForAsyncObject failed, error was: %u", ::GetLastError());
294 return false;
295 }
296
297 if (! ::GetOverlappedResult(pipe, &ov, &dw, FALSE))
298 {
299 carla_stderr2("ConnectNamedPipe GetOverlappedResult of pending failed, error was: %u", ::GetLastError());
300 return false;
301 }
302
303 return true;
304
305 case ERROR_PIPE_LISTENING:
306 if (carla_gettime_ms() < timeoutEnd)
307 {
308 carla_msleep(5);
309 continue;
310 }
311 carla_stderr2("ConnectNamedPipe listening timed out");
312 return false;
313
314 default:
315 carla_stderr2("ConnectNamedPipe failed, error was: %u", err);
316 return false;
317 }
318 }
319
320 return true;
321}
322#else
323static inline
324bool startProcess(const char* const argv[], pid_t& pidinst) noexcept
325{
326 const CarlaScopedEnvVar sev1("LD_LIBRARY_PATH", nullptr);
327 const CarlaScopedEnvVar sev2("LD_PRELOAD", nullptr);
328
329 #ifdef __clang__
330 #pragma clang diagnostic push
331 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
332 #endif
333 const pid_t ret = pidinst = vfork();
334 #ifdef __clang__
335 #pragma clang diagnostic pop
336 #endif
337
338 switch (ret)
339 {
340 case 0: { // child process
341 execvp(argv[0], const_cast<char* const*>(argv));
342
343 CarlaString error(std::strerror(errno));
344 carla_stderr2("exec failed: %s", error.buffer());
345
346 _exit(1); // this is not noexcept safe but doesn't matter anyway
347 } break;
348
349 case -1: { // error
350 CarlaString error(std::strerror(errno));
351 carla_stderr2("vfork() failed: %s", error.buffer());
352 } break;
353 }
354
355 return (ret > 0);
356}
357#endif
358
359// -----------------------------------------------------------------------
360// waitForClientFirstMessage
361
362template<typename P>
363static inline
364bool waitForClientFirstMessage(const P& pipe, void* const ovRecv, void* const process, const uint32_t timeOutMilliseconds) noexcept
365{
367 CARLA_SAFE_ASSERT_RETURN(timeOutMilliseconds > 0, false);
368
369 char c;
370 ssize_t ret;
371 const uint32_t timeoutEnd = carla_gettime_ms() + timeOutMilliseconds;
372
373#ifdef CARLA_OS_WIN
374 if (! waitForClientConnect(pipe, (HANDLE)ovRecv, (HANDLE)process, timeOutMilliseconds))
375 return false;
376#endif
377
378 for (;;)
379 {
380 try {
381#ifdef CARLA_OS_WIN
382 ret = ReadFileWin32(pipe, (HANDLE)ovRecv, &c, 1);
383#else
384 ret = ::read(pipe, &c, 1);
385#endif
386 } CARLA_SAFE_EXCEPTION_RETURN("read pipe", false);
387
388 switch (ret)
389 {
390 case 1:
391 if (c == '\n')
392 return true;
393
394 carla_stderr("waitForClientFirstMessage() - read has wrong first char '%c'", c);return false;
395 return false;
396
397 case -1: // failed to read
398#ifdef CARLA_OS_WIN
399 if (::GetLastError() == ERROR_NO_DATA)
400#else
401 if (errno == EAGAIN)
402#endif
403 {
404 if (carla_gettime_ms() < timeoutEnd)
405 {
406 carla_msleep(5);
407 continue;
408 }
409 carla_stderr("waitForClientFirstMessage() - read timed out");
410 }
411 else
412 {
413#ifdef CARLA_OS_WIN
414 carla_stderr("waitForClientFirstMessage() - read failed");
415#else
416 CarlaString error(std::strerror(errno));
417 carla_stderr("waitForClientFirstMessage() - read failed: %s", error.buffer());
418#endif
419 }
420 return false;
421
422 default: // ???
423 carla_stderr("waitForClientFirstMessage() - read returned %i", int(ret));
424 return false;
425 }
426 }
427
428 // maybe unused
429 (void)ovRecv; (void)process;
430}
431
432// -----------------------------------------------------------------------
433// waitForChildToStop / waitForProcessToStop
434
435#ifdef CARLA_OS_WIN
436static inline
437bool waitForProcessToStop(const HANDLE process, const uint32_t timeOutMilliseconds, bool sendTerminate) noexcept
438{
439 CARLA_SAFE_ASSERT_RETURN(process != INVALID_HANDLE_VALUE, false);
440 CARLA_SAFE_ASSERT_RETURN(timeOutMilliseconds > 0, false);
441
442 const uint32_t timeoutEnd = carla_gettime_ms() + timeOutMilliseconds;
443
444 for (;;)
445 {
446 switch (::WaitForSingleObject(process, 0))
447 {
448 case WAIT_OBJECT_0:
449 case WAIT_FAILED:
450 return true;
451 }
452
453 if (sendTerminate)
454 {
455 sendTerminate = false;
456 ::TerminateProcess(process, 15);
457 }
458
459 if (carla_gettime_ms() >= timeoutEnd)
460 break;
461
462 carla_msleep(5);
463 }
464
465 return false;
466}
467
468static inline
469void waitForProcessToStopOrKillIt(const HANDLE process, const uint32_t timeOutMilliseconds) noexcept
470{
471 CARLA_SAFE_ASSERT_RETURN(process != INVALID_HANDLE_VALUE,);
472 CARLA_SAFE_ASSERT_RETURN(timeOutMilliseconds > 0,);
473
474 if (! waitForProcessToStop(process, timeOutMilliseconds, true))
475 {
476 carla_stderr("waitForProcessToStopOrKillIt() - process didn't stop, force termination");
477
478 if (::TerminateProcess(process, 9) != FALSE)
479 {
480 // wait for process to stop
481 waitForProcessToStop(process, timeOutMilliseconds, false);
482 }
483 }
484}
485#else
486static inline
487bool waitForChildToStop(const pid_t pid, const uint32_t timeOutMilliseconds, bool sendTerminate) noexcept
488{
489 CARLA_SAFE_ASSERT_RETURN(pid > 0, false);
490 CARLA_SAFE_ASSERT_RETURN(timeOutMilliseconds > 0, false);
491
492 pid_t ret;
493 const uint32_t timeoutEnd = carla_gettime_ms() + timeOutMilliseconds;
494
495 for (;;)
496 {
497 try {
498 ret = ::waitpid(pid, nullptr, WNOHANG);
499 } CARLA_SAFE_EXCEPTION_BREAK("waitpid");
500
501 switch (ret)
502 {
503 case -1:
504 if (errno == ECHILD)
505 {
506 // success, child doesn't exist
507 return true;
508 }
509 else
510 {
511 CarlaString error(std::strerror(errno));
512 carla_stderr("waitForChildToStop() - waitpid failed: %s", error.buffer());
513 return false;
514 }
515 break;
516
517 case 0:
518 if (sendTerminate)
519 {
520 sendTerminate = false;
521 ::kill(pid, SIGTERM);
522 }
523 if (carla_gettime_ms() < timeoutEnd)
524 {
525 carla_msleep(5);
526 continue;
527 }
528 carla_stderr("waitForChildToStop() - timed out");
529 break;
530
531 default:
532 if (ret == pid)
533 {
534 // success
535 return true;
536 }
537 else
538 {
539 carla_stderr("waitForChildToStop() - got wrong pid %i (requested was %i)", int(ret), int(pid));
540 return false;
541 }
542 }
543
544 break;
545 }
546
547 return false;
548}
549
550static inline
551void waitForChildToStopOrKillIt(pid_t& pid, const uint32_t timeOutMilliseconds) noexcept
552{
553 CARLA_SAFE_ASSERT_RETURN(pid > 0,);
554 CARLA_SAFE_ASSERT_RETURN(timeOutMilliseconds > 0,);
555
556 if (! waitForChildToStop(pid, timeOutMilliseconds, true))
557 {
558 carla_stderr("waitForChildToStopOrKillIt() - process didn't stop, force killing");
559
560 if (::kill(pid, SIGKILL) != -1)
561 {
562 // wait for killing to take place
563 waitForChildToStop(pid, timeOutMilliseconds, false);
564 }
565 else
566 {
567 CarlaString error(std::strerror(errno));
568 carla_stderr("waitForChildToStopOrKillIt() - kill failed: %s", error.buffer());
569 }
570 }
571}
572#endif
573
574// -----------------------------------------------------------------------
575
577 // pipes
578#ifdef CARLA_OS_WIN
579 PROCESS_INFORMATION processInfo;
582 HANDLE ovRecv;
583 HANDLE ovSend;
584#else
585 pid_t pid;
588#endif
589
590 // read functions must only be called in context of idlePipe()
592
593 // the client side is closing down, only waiting for response from server
595
596 // other side of pipe has closed
598
599 // print error only once
601
602 // for debugging
604
605 // common write lock
607
608 // temporary buffers for _readline()
609 mutable char tmpBuf[0xffff];
610 mutable CarlaString tmpStr;
611
613#ifdef CARLA_OS_WIN
614 : processInfo(),
615#else
616 : pid(-1),
617#endif
620 isReading(false),
621 clientClosingDown(false),
622 pipeClosed(true),
623 lastMessageFailed(false),
624 isServer(false),
625 writeLock(),
626 tmpBuf(),
627 tmpStr()
628 {
629#ifdef CARLA_OS_WIN
630 carla_zeroStruct(processInfo);
631 processInfo.hProcess = INVALID_HANDLE_VALUE;
632 processInfo.hThread = INVALID_HANDLE_VALUE;
633
634 ovRecv = ::CreateEvent(nullptr, FALSE, FALSE, nullptr);
635 ovSend = ::CreateEvent(nullptr, FALSE, FALSE, nullptr);
636#endif
637
638 carla_zeroChars(tmpBuf, 0xffff);
639 }
640
642};
643
644// -----------------------------------------------------------------------
645
646CarlaPipeCommon::CarlaPipeCommon() noexcept
647 : pData(new PrivateData())
648{
649 carla_debug("CarlaPipeCommon::CarlaPipeCommon()");
650}
651
652CarlaPipeCommon::~CarlaPipeCommon() /*noexcept*/
653{
654 carla_debug("CarlaPipeCommon::~CarlaPipeCommon()");
655
656 delete pData;
657}
658
659// -------------------------------------------------------------------
660
661bool CarlaPipeCommon::isPipeRunning() const noexcept
662{
663 return (pData->pipeRecv != INVALID_PIPE_VALUE && pData->pipeSend != INVALID_PIPE_VALUE && ! pData->pipeClosed);
664}
665
666void CarlaPipeCommon::idlePipe(const bool onlyOnce) noexcept
667{
668 bool readSucess;
669
670 for (;;)
671 {
672 readSucess = false;
673 const char* const msg = _readline(true, 0, readSucess);
674
675 if (! readSucess)
676 break;
677 if (msg == nullptr)
678 continue;
679
680 pData->isReading = true;
681
682 if (std::strcmp(msg, "__carla-quit__") == 0)
683 {
684 pData->pipeClosed = true;
685 }
686 else if (! pData->clientClosingDown)
687 {
688 try {
689 msgReceived(msg);
690 } CARLA_SAFE_EXCEPTION("msgReceived");
691 }
692
693 pData->isReading = false;
694
695 std::free(const_cast<char*>(msg));
696
697 if (onlyOnce || pData->pipeRecv == INVALID_PIPE_VALUE)
698 break;
699 }
700}
701
702// -------------------------------------------------------------------
703
704void CarlaPipeCommon::lockPipe() const noexcept
705{
706 pData->writeLock.lock();
707}
708
709bool CarlaPipeCommon::tryLockPipe() const noexcept
710{
711 return pData->writeLock.tryLock();
712}
713
714void CarlaPipeCommon::unlockPipe() const noexcept
715{
716 pData->writeLock.unlock();
717}
718
719CarlaMutex& CarlaPipeCommon::getPipeLock() const noexcept
720{
721 return pData->writeLock;
722}
723
724// -------------------------------------------------------------------
725
726bool CarlaPipeCommon::readNextLineAsBool(bool& value) const noexcept
727{
728 CARLA_SAFE_ASSERT_RETURN(pData->isReading, false);
729
730 if (const char* const msg = _readlineblock(false))
731 {
732 value = (std::strcmp(msg, "true") == 0);
733 return true;
734 }
735
736 return false;
737}
738
739bool CarlaPipeCommon::readNextLineAsByte(uint8_t& value) const noexcept
740{
741 CARLA_SAFE_ASSERT_RETURN(pData->isReading, false);
742
743 if (const char* const msg = _readlineblock(false))
744 {
745 const int asint = std::atoi(msg);
746
747 if (asint >= 0 && asint <= 0xFF)
748 {
749 value = static_cast<uint8_t>(asint);
750 return true;
751 }
752 }
753
754 return false;
755}
756
757bool CarlaPipeCommon::readNextLineAsInt(int32_t& value) const noexcept
758{
759 CARLA_SAFE_ASSERT_RETURN(pData->isReading, false);
760
761 if (const char* const msg = _readlineblock(false))
762 {
763 value = std::atoi(msg);
764 return true;
765 }
766
767 return false;
768}
769
770bool CarlaPipeCommon::readNextLineAsUInt(uint32_t& value) const noexcept
771{
772 CARLA_SAFE_ASSERT_RETURN(pData->isReading, false);
773
774 if (const char* const msg = _readlineblock(false))
775 {
776#if (defined(__WORDSIZE) && __WORDSIZE < 64) || (defined(__SIZE_WIDTH__) && __SIZE_WIDTH__ < 64) || \
777 defined(CARLA_OS_WIN) || defined(CARLA_OS_MAC)
778 const long long aslong = std::atoll(msg);
779#else
780 const long aslong = std::atol(msg);
781#endif
782
783 if (aslong >= 0)
784 {
785 value = static_cast<uint32_t>(aslong);
786 return true;
787 }
788 }
789
790 return false;
791}
792
793bool CarlaPipeCommon::readNextLineAsLong(int64_t& value) const noexcept
794{
795 CARLA_SAFE_ASSERT_RETURN(pData->isReading, false);
796
797 if (const char* const msg = _readlineblock(false))
798 {
799 value = std::atol(msg);
800 return true;
801 }
802
803 return false;
804}
805
806bool CarlaPipeCommon::readNextLineAsULong(uint64_t& value) const noexcept
807{
808 CARLA_SAFE_ASSERT_RETURN(pData->isReading, false);
809
810 if (const char* const msg = _readlineblock(false))
811 {
812 const int64_t asint64 = std::atol(msg);
813
814 if (asint64 >= 0)
815 {
816 value = static_cast<uint64_t>(asint64);
817 return true;
818 }
819 }
820
821 return false;
822}
823
824bool CarlaPipeCommon::readNextLineAsFloat(float& value) const noexcept
825{
826 CARLA_SAFE_ASSERT_RETURN(pData->isReading, false);
827
828 if (const char* const msg = _readlineblock(false))
829 {
830 {
831 const CarlaScopedLocale csl;
832 value = static_cast<float>(std::atof(msg));
833 }
834 return true;
835 }
836
837 return false;
838}
839
840bool CarlaPipeCommon::readNextLineAsDouble(double& value) const noexcept
841{
842 CARLA_SAFE_ASSERT_RETURN(pData->isReading, false);
843
844 if (const char* const msg = _readlineblock(false))
845 {
846 {
847 const CarlaScopedLocale csl;
848 value = std::atof(msg);
849 }
850 return true;
851 }
852
853 return false;
854}
855
856bool CarlaPipeCommon::readNextLineAsString(const char*& value, const bool allocateString, uint32_t size) const noexcept
857{
858 CARLA_SAFE_ASSERT_RETURN(pData->isReading, false);
859
860 if (size >= 0xffff)
861 size = 0;
862
863 if (const char* const msg = _readlineblock(allocateString, static_cast<uint16_t>(size)))
864 {
865 value = msg;
866 return true;
867 }
868
869 return false;
870}
871
872char* CarlaPipeCommon::readNextLineAsString() const noexcept
873{
874 CARLA_SAFE_ASSERT_RETURN(pData->isReading, nullptr);
875
876 return const_cast<char*>(_readlineblock(true, 0));
877}
878
879// -------------------------------------------------------------------
880// must be locked before calling
881
882bool CarlaPipeCommon::writeMessage(const char* const msg) const noexcept
883{
884 CARLA_SAFE_ASSERT_RETURN(msg != nullptr && msg[0] != '\0', false);
885
886 if (pData->pipeClosed)
887 return false;
888
889 const std::size_t size(std::strlen(msg));
890 CARLA_SAFE_ASSERT_RETURN(size > 0, false);
891 CARLA_SAFE_ASSERT_RETURN(msg[size-1] == '\n', false);
892
893 return _writeMsgBuffer(msg, size);
894}
895
896bool CarlaPipeCommon::writeMessage(const char* const msg, std::size_t size) const noexcept
897{
898 CARLA_SAFE_ASSERT_RETURN(msg != nullptr && msg[0] != '\0', false);
899 CARLA_SAFE_ASSERT_RETURN(size > 0, false);
900 CARLA_SAFE_ASSERT_RETURN(msg[size-1] == '\n', false);
901
902 if (pData->pipeClosed)
903 return false;
904
905 return _writeMsgBuffer(msg, size);
906}
907
908bool CarlaPipeCommon::writeAndFixMessage(const char* const msg) const noexcept
909{
910 CARLA_SAFE_ASSERT_RETURN(msg != nullptr, false);
911
912 if (pData->pipeClosed)
913 return false;
914
915 const std::size_t size(std::strlen(msg));
916
917 char* const fixedMsg = static_cast<char*>(std::malloc(size+2));
918 CARLA_SAFE_ASSERT_RETURN(fixedMsg != nullptr, false);
919
920 if (size > 0)
921 {
922 std::strcpy(fixedMsg, msg);
923
924 for (std::size_t i=0; i<size; ++i)
925 {
926 if (fixedMsg[i] == '\n')
927 fixedMsg[i] = '\r';
928 }
929
930 if (fixedMsg[size-1] == '\r')
931 {
932 fixedMsg[size-1] = '\n';
933 fixedMsg[size ] = '\0';
934 fixedMsg[size+1] = '\0';
935 }
936 else
937 {
938 fixedMsg[size ] = '\n';
939 fixedMsg[size+1] = '\0';
940 }
941 }
942 else
943 {
944 fixedMsg[0] = '\n';
945 fixedMsg[1] = '\0';
946 }
947
948 const bool ret = _writeMsgBuffer(fixedMsg, size+1);
949 std::free(fixedMsg);
950 return ret;
951}
952
953bool CarlaPipeCommon::writeEmptyMessage() const noexcept
954{
955 if (pData->pipeClosed)
956 return false;
957
958 return _writeMsgBuffer("\n", 1);
959}
960
961bool CarlaPipeCommon::syncMessages() const noexcept
962{
963 CARLA_SAFE_ASSERT_RETURN(pData->pipeSend != INVALID_PIPE_VALUE, false);
964
965#if defined(CARLA_OS_LINUX) || defined(CARLA_OS_GNU_HURD)
966# if defined(__GLIBC__) && (__GLIBC__ * 1000 + __GLIBC_MINOR__) >= 2014
967 // the only call that seems to do something
968 return ::syncfs(pData->pipeSend) == 0;
969# endif
970#elif 0 // defined(CARLA_OS_WIN)
971 // FIXME causes issues
972 try {
973 return (::FlushFileBuffers(pData->pipeSend) != FALSE);
974 } CARLA_SAFE_EXCEPTION_RETURN("CarlaPipeCommon::writeMsgBuffer", false);
975#endif
976
977 return true;
978}
979
980// -------------------------------------------------------------------
981
982bool CarlaPipeCommon::writeErrorMessage(const char* const error) const noexcept
983{
984 CARLA_SAFE_ASSERT_RETURN(error != nullptr && error[0] != '\0', false);
985
986 const CarlaMutexLocker cml(pData->writeLock);
987
988 if (! _writeMsgBuffer("error\n", 6))
989 return false;
990 if (! writeAndFixMessage(error))
991 return false;
992
993 syncMessages();
994 return true;
995}
996
997bool CarlaPipeCommon::writeControlMessage(const uint32_t index, const float value, const bool withWriteLock) const noexcept
998{
999 if (withWriteLock)
1000 {
1001 const CarlaMutexLocker cml(pData->writeLock);
1002 return writeControlMessage(index, value, false);
1003 }
1004
1005 char tmpBuf[0xff];
1006 tmpBuf[0xfe] = '\0';
1007
1008 if (! _writeMsgBuffer("control\n", 8))
1009 return false;
1010
1011 std::snprintf(tmpBuf, 0xfe, "%i\n", index);
1012 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1013 return false;
1014
1015 {
1016 const CarlaScopedLocale csl;
1017 std::snprintf(tmpBuf, 0xfe, "%.12g\n", static_cast<double>(value));
1018 }
1019
1020 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1021 return false;
1022
1023 syncMessages();
1024 return true;
1025}
1026
1027bool CarlaPipeCommon::writeConfigureMessage(const char* const key, const char* const value) const noexcept
1028{
1029 CARLA_SAFE_ASSERT_RETURN(key != nullptr && key[0] != '\0', false);
1030 CARLA_SAFE_ASSERT_RETURN(value != nullptr, false);
1031
1032 const CarlaMutexLocker cml(pData->writeLock);
1033
1034 if (! _writeMsgBuffer("configure\n", 10))
1035 return false;
1036 if (! writeAndFixMessage(key))
1037 return false;
1038 if (! writeAndFixMessage(value))
1039 return false;
1040
1041 syncMessages();
1042 return true;
1043}
1044
1045bool CarlaPipeCommon::writeProgramMessage(const uint32_t index) const noexcept
1046{
1047 char tmpBuf[0xff];
1048 tmpBuf[0xfe] = '\0';
1049
1050 const CarlaMutexLocker cml(pData->writeLock);
1051
1052 if (! _writeMsgBuffer("program\n", 8))
1053 return false;
1054
1055 std::snprintf(tmpBuf, 0xfe, "%i\n", index);
1056 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1057 return false;
1058
1059 syncMessages();
1060 return true;
1061}
1062
1063bool CarlaPipeCommon::writeProgramMessage(const uint8_t channel, const uint32_t bank, const uint32_t program) const noexcept
1064{
1065 char tmpBuf[0xff];
1066 tmpBuf[0xfe] = '\0';
1067
1068 const CarlaMutexLocker cml(pData->writeLock);
1069
1070 if (! _writeMsgBuffer("program\n", 8))
1071 return false;
1072
1073 std::snprintf(tmpBuf, 0xfe, "%i\n", channel);
1074 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1075 return false;
1076
1077 std::snprintf(tmpBuf, 0xfe, "%i\n", bank);
1078 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1079 return false;
1080
1081 std::snprintf(tmpBuf, 0xfe, "%i\n", program);
1082 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1083 return false;
1084
1085 syncMessages();
1086 return true;
1087}
1088
1089bool CarlaPipeCommon::writeMidiProgramMessage(const uint32_t bank, const uint32_t program) const noexcept
1090{
1091 char tmpBuf[0xff];
1092 tmpBuf[0xfe] = '\0';
1093
1094 const CarlaMutexLocker cml(pData->writeLock);
1095
1096 if (! _writeMsgBuffer("midiprogram\n", 12))
1097 return false;
1098
1099 std::snprintf(tmpBuf, 0xfe, "%i\n", bank);
1100 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1101 return false;
1102
1103 std::snprintf(tmpBuf, 0xfe, "%i\n", program);
1104 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1105 return false;
1106
1107 syncMessages();
1108 return true;
1109}
1110
1111bool CarlaPipeCommon::writeReloadProgramsMessage(const int32_t index) const noexcept
1112{
1113 char tmpBuf[0xff];
1114 tmpBuf[0xfe] = '\0';
1115
1116 const CarlaMutexLocker cml(pData->writeLock);
1117
1118 if (! _writeMsgBuffer("reloadprograms\n", 15))
1119 return false;
1120
1121 std::snprintf(tmpBuf, 0xfe, "%i\n", index);
1122 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1123 return false;
1124
1125 syncMessages();
1126 return true;
1127}
1128
1129bool CarlaPipeCommon::writeMidiNoteMessage(const bool onOff, const uint8_t channel, const uint8_t note, const uint8_t velocity) const noexcept
1130{
1133 CARLA_SAFE_ASSERT_RETURN(velocity < MAX_MIDI_VALUE, false);
1134
1135 char tmpBuf[0xff];
1136 tmpBuf[0xfe] = '\0';
1137
1138 const CarlaMutexLocker cml(pData->writeLock);
1139
1140 if (! _writeMsgBuffer("note\n", 5))
1141 return false;
1142
1143 std::snprintf(tmpBuf, 0xfe, "%s\n", bool2str(onOff));
1144 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1145 return false;
1146
1147 std::snprintf(tmpBuf, 0xfe, "%i\n", channel);
1148 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1149 return false;
1150
1151 std::snprintf(tmpBuf, 0xfe, "%i\n", note);
1152 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1153 return false;
1154
1155 std::snprintf(tmpBuf, 0xfe, "%i\n", velocity);
1156 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1157 return false;
1158
1159 syncMessages();
1160 return true;
1161}
1162
1163bool CarlaPipeCommon::writeLv2AtomMessage(const uint32_t index, const LV2_Atom* const atom) const noexcept
1164{
1165 CARLA_SAFE_ASSERT_RETURN(atom != nullptr, false);
1166
1167 char tmpBuf[0xff];
1168 tmpBuf[0xfe] = '\0';
1169
1170 const uint32_t atomTotalSize(lv2_atom_total_size(atom));
1171 CarlaString base64atom(CarlaString::asBase64(atom, atomTotalSize));
1172
1173 const CarlaMutexLocker cml(pData->writeLock);
1174
1175 if (! _writeMsgBuffer("atom\n", 5))
1176 return false;
1177
1178 std::snprintf(tmpBuf, 0xfe, "%i\n", index);
1179 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1180 return false;
1181
1182 std::snprintf(tmpBuf, 0xfe, "%i\n", atomTotalSize);
1183 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1184 return false;
1185
1186 std::snprintf(tmpBuf, 0xfe, "%lu\n", static_cast<long unsigned>(base64atom.length()));
1187 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1188 return false;
1189
1190 if (! writeAndFixMessage(base64atom.buffer()))
1191 return false;
1192
1193 syncMessages();
1194 return true;
1195}
1196
1197bool CarlaPipeCommon::writeLv2ParameterMessage(const char* const uri, const float value, const bool withWriteLock) const noexcept
1198{
1199 if (withWriteLock)
1200 {
1201 const CarlaMutexLocker cml(pData->writeLock);
1202 return writeLv2ParameterMessage(uri, value, false);
1203 }
1204
1205 char tmpBuf[0xff];
1206 tmpBuf[0xfe] = '\0';
1207
1208 if (! _writeMsgBuffer("parameter\n", 10))
1209 return false;
1210
1211 if (! writeAndFixMessage(uri))
1212 return false;
1213
1214 {
1215 const CarlaScopedLocale csl;
1216 std::snprintf(tmpBuf, 0xfe, "%.12g\n", static_cast<double>(value));
1217 }
1218
1219 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1220 return false;
1221
1222 syncMessages();
1223 return true;
1224}
1225
1226bool CarlaPipeCommon::writeLv2UridMessage(const uint32_t urid, const char* const uri) const noexcept
1227{
1228 CARLA_SAFE_ASSERT_RETURN(urid != 0, false);
1229 CARLA_SAFE_ASSERT_RETURN(uri != nullptr && uri[0] != '\0', false);
1230
1231 char tmpBuf[0xff];
1232 tmpBuf[0xfe] = '\0';
1233
1234 const CarlaMutexLocker cml(pData->writeLock);
1235
1236 if (! _writeMsgBuffer("urid\n", 5))
1237 return false;
1238
1239 std::snprintf(tmpBuf, 0xfe, "%i\n", urid);
1240 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1241 return false;
1242
1243 std::snprintf(tmpBuf, 0xfe, "%lu\n", static_cast<long unsigned>(std::strlen(uri)));
1244 if (! _writeMsgBuffer(tmpBuf, std::strlen(tmpBuf)))
1245 return false;
1246
1247 if (! writeAndFixMessage(uri))
1248 return false;
1249
1250 syncMessages();
1251 return true;
1252}
1253
1254// -------------------------------------------------------------------
1255
1256// internal
1257const char* CarlaPipeCommon::_readline(const bool allocReturn, const uint16_t size, bool& readSucess) const noexcept
1258{
1259 CARLA_SAFE_ASSERT_RETURN(pData->pipeRecv != INVALID_PIPE_VALUE, nullptr);
1260
1261 char c;
1262 char* ptr = pData->tmpBuf;
1263 ssize_t ret = -1;
1264 bool tooBig = false;
1265
1266 pData->tmpStr.clear();
1267
1268 if (size == 0 || size == 1)
1269 {
1270 for (int i=0; i<0xfffe; ++i)
1271 {
1272 try {
1273 #ifdef CARLA_OS_WIN
1274 ret = ReadFileWin32(pData->pipeRecv, pData->ovRecv, &c, 1);
1275 #else
1276 ret = ::read(pData->pipeRecv, &c, 1);
1277 #endif
1278 } CARLA_SAFE_EXCEPTION_BREAK("CarlaPipeCommon::readline() - read");
1279
1280 if (ret != 1)
1281 break;
1282
1283 if (c == '\n')
1284 {
1285 *ptr = '\0';
1286 break;
1287 }
1288
1289 if (c == '\r')
1290 c = '\n';
1291
1292 *ptr++ = c;
1293
1294 if (i+1 == 0xfffe)
1295 {
1296 i = 0;
1297 *ptr = '\0';
1298 tooBig = true;
1299 pData->tmpStr += pData->tmpBuf;
1300 ptr = pData->tmpBuf;
1301 }
1302 }
1303 }
1304 else
1305 {
1306 uint16_t remaining = size;
1307 readSucess = false;
1308
1309 for (;;)
1310 {
1311 try {
1312 #ifdef CARLA_OS_WIN
1313 ret = ReadFileWin32(pData->pipeRecv, pData->ovRecv, ptr, remaining);
1314 #else
1315 ret = ::read(pData->pipeRecv, ptr, remaining);
1316 #endif
1317 } CARLA_SAFE_EXCEPTION_RETURN("CarlaPipeCommon::readline() - read", nullptr);
1318
1319 if (ret == -1 && errno == EAGAIN)
1320 continue;
1321
1322 CARLA_SAFE_ASSERT_INT2_RETURN(ret > 0, ret, remaining, nullptr);
1323 CARLA_SAFE_ASSERT_INT2_RETURN(ret <= (ssize_t)remaining, ret, remaining, nullptr);
1324
1325 for (ssize_t i=0; i<ret; ++i)
1326 {
1327 if (ptr[i] == '\r')
1328 ptr[i] = '\n';
1329 }
1330
1331 ptr += ret;
1332 *ptr = '\0';
1333 remaining = static_cast<uint16_t>(remaining - ret);
1334
1335 if (remaining != 0)
1336 continue;
1337
1338 readSucess = true;
1339
1340 if (allocReturn)
1341 {
1342 pData->tmpStr = pData->tmpBuf;
1343 return pData->tmpStr.releaseBufferPointer();
1344 }
1345
1346 return pData->tmpBuf;
1347 }
1348 }
1349
1350 if (ptr != pData->tmpBuf)
1351 {
1352 *ptr = '\0';
1353
1354 if (! allocReturn && ! tooBig)
1355 {
1356 readSucess = true;
1357 return pData->tmpBuf;
1358 }
1359
1360 pData->tmpStr += pData->tmpBuf;
1361 }
1362 else if (pData->tmpStr.isEmpty() && ret != 1)
1363 {
1364 // some error
1365 return nullptr;
1366 }
1367
1368 readSucess = true;
1369
1370 if (! allocReturn && ! tooBig)
1371 return pData->tmpBuf;
1372
1373 return allocReturn ? pData->tmpStr.releaseBufferPointer() : pData->tmpStr.buffer();
1374}
1375
1376const char* CarlaPipeCommon::_readlineblock(const bool allocReturn,
1377 const uint16_t size,
1378 const uint32_t timeOutMilliseconds) const noexcept
1379{
1380 const uint32_t timeoutEnd = carla_gettime_ms() + timeOutMilliseconds;
1381 bool readSucess;
1382
1383 for (;;)
1384 {
1385 readSucess = false;
1386 const char* const msg = _readline(allocReturn, size, readSucess);
1387
1388 if (readSucess)
1389 return msg;
1390
1391 if (carla_gettime_ms() >= timeoutEnd)
1392 break;
1393
1394 carla_msleep(5);
1395 }
1396
1397 static const bool testingForValgrind = std::getenv("CARLA_VALGRIND_TEST") != nullptr;
1398
1399 if (testingForValgrind)
1400 {
1401 const uint32_t timeoutEnd2 = carla_gettime_ms() + 1000;
1402
1403 for (;;)
1404 {
1405 readSucess = false;
1406 const char* const msg = _readline(allocReturn, size, readSucess);
1407
1408 if (readSucess)
1409 return msg;
1410
1411 if (carla_gettime_ms() >= timeoutEnd2)
1412 break;
1413
1414 carla_msleep(100);
1415 }
1416 }
1417
1418 carla_stderr("readlineblock timed out");
1419 return nullptr;
1420}
1421
1422bool CarlaPipeCommon::_writeMsgBuffer(const char* const msg, const std::size_t size) const noexcept
1423{
1424 if (pData->pipeClosed)
1425 return false;
1426
1427 if (pData->pipeSend == INVALID_PIPE_VALUE)
1428 {
1429 carla_stderr2("CarlaPipe write error, isServer:%s, message was:\n%s", bool2str(pData->isServer), msg);
1430 return false;
1431 }
1432
1433 ssize_t ret;
1434
1435 try {
1436 #ifdef CARLA_OS_WIN
1437 ret = WriteFileWin32(pData->pipeSend, pData->ovSend, msg, static_cast<DWORD>(size));
1438 #else
1439 ret = ::write(pData->pipeSend, msg, size);
1440 #endif
1441 } CARLA_SAFE_EXCEPTION_RETURN("CarlaPipeCommon::writeMsgBuffer", false);
1442
1443 #ifdef CARLA_OS_WIN
1444 if (ret == -2)
1445 {
1446 pData->pipeClosed = true;
1447 return false;
1448 }
1449 #endif
1450
1451 if (ret == static_cast<ssize_t>(size))
1452 {
1453 if (pData->lastMessageFailed)
1454 pData->lastMessageFailed = false;
1455 return true;
1456 }
1457
1458 if (! pData->lastMessageFailed)
1459 {
1460 pData->lastMessageFailed = true;
1461 fprintf(stderr,
1462 "CarlaPipeCommon::_writeMsgBuffer(..., " P_SIZE ") - failed with " P_SSIZE " (%s), message was:\n%s",
1463 size, ret, bool2str(pData->isServer), msg);
1464 }
1465
1466 return false;
1467}
1468
1469// -----------------------------------------------------------------------
1470
1471CarlaPipeServer::CarlaPipeServer() noexcept
1472 : CarlaPipeCommon()
1473{
1474 carla_debug("CarlaPipeServer::CarlaPipeServer()");
1475 pData->isServer = true;
1476}
1477
1478CarlaPipeServer::~CarlaPipeServer() /*noexcept*/
1479{
1480 carla_debug("CarlaPipeServer::~CarlaPipeServer()");
1481
1482 stopPipeServer(5*1000);
1483}
1484
1485uintptr_t CarlaPipeServer::getPID() const noexcept
1486{
1487#ifndef CARLA_OS_WIN
1488 return static_cast<uintptr_t>(pData->pid);
1489#else
1490 return 0;
1491#endif
1492}
1493
1494// --------------------------------------------------------------------------------------------------------------------
1495
1496bool CarlaPipeServer::startPipeServer(const char* const helperTool,
1497 const char* const filename,
1498 const char* const arg1,
1499 const char* const arg2,
1500 const int size,
1501 int timeOutMilliseconds) noexcept
1502{
1503 CARLA_SAFE_ASSERT_RETURN(pData->pipeRecv == INVALID_PIPE_VALUE, false);
1504 CARLA_SAFE_ASSERT_RETURN(pData->pipeSend == INVALID_PIPE_VALUE, false);
1505#ifdef CARLA_OS_WIN
1506 CARLA_SAFE_ASSERT_RETURN(pData->processInfo.hThread == INVALID_HANDLE_VALUE, false);
1507 CARLA_SAFE_ASSERT_RETURN(pData->processInfo.hProcess == INVALID_HANDLE_VALUE, false);
1508#else
1509 CARLA_SAFE_ASSERT_RETURN(pData->pid == -1, false);
1510#endif
1511 CARLA_SAFE_ASSERT_RETURN(filename != nullptr && filename[0] != '\0', false);
1512 CARLA_SAFE_ASSERT_RETURN(arg1 != nullptr, false);
1513 CARLA_SAFE_ASSERT_RETURN(arg2 != nullptr, false);
1514 carla_debug("CarlaPipeServer::startPipeServer(\"%s\", \"%s\", \"%s\")", filename, arg1, arg2);
1515
1516 if (timeOutMilliseconds < 0)
1517 timeOutMilliseconds = 10 * 1000;
1518
1519 char pipeRecvServerStr[100+1];
1520 char pipeSendServerStr[100+1];
1521 char pipeRecvClientStr[100+1];
1522 char pipeSendClientStr[100+1];
1523
1524 pipeRecvServerStr[100] = '\0';
1525 pipeSendServerStr[100] = '\0';
1526 pipeRecvClientStr[100] = '\0';
1527 pipeSendClientStr[100] = '\0';
1528
1529 const CarlaMutexLocker cml(pData->writeLock);
1530
1531 //-----------------------------------------------------------------------------------------------------------------
1532 // create pipes
1533
1534#ifdef CARLA_OS_WIN
1535 HANDLE pipe1, pipe2;
1536
1537 std::srand(static_cast<uint>(std::time(nullptr)));
1538
1539 static ulong sCounter = 0;
1540 ++sCounter;
1541
1542 const int randint = std::rand();
1543
1544 std::snprintf(pipeRecvServerStr, 100, "\\\\.\\pipe\\carla-pipe1-%i-%li", randint, sCounter);
1545 std::snprintf(pipeSendServerStr, 100, "\\\\.\\pipe\\carla-pipe2-%i-%li", randint, sCounter);
1546 std::snprintf(pipeRecvClientStr, 100, "ignored");
1547 std::snprintf(pipeSendClientStr, 100, "ignored");
1548
1549 SECURITY_ATTRIBUTES sa;
1550 carla_zeroStruct(sa);
1551 sa.nLength = sizeof(sa);
1552 sa.bInheritHandle = TRUE;
1553
1554 pipe1 = ::CreateNamedPipeA(pipeRecvServerStr, PIPE_ACCESS_DUPLEX|FILE_FLAG_FIRST_PIPE_INSTANCE|FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE|PIPE_READMODE_BYTE, 1, size, size, 0, &sa);
1555
1556 if (pipe1 == INVALID_HANDLE_VALUE)
1557 {
1558 fail("pipe creation failed");
1559 return false;
1560 }
1561
1562 pipe2 = ::CreateNamedPipeA(pipeSendServerStr, PIPE_ACCESS_DUPLEX|FILE_FLAG_FIRST_PIPE_INSTANCE|FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE|PIPE_READMODE_BYTE, 1, size, size, 0, &sa);
1563
1564 if (pipe2 == INVALID_HANDLE_VALUE)
1565 {
1566 try { ::CloseHandle(pipe1); } CARLA_SAFE_EXCEPTION("CloseHandle(pipe1)");
1567 fail("pipe creation failed");
1568 return false;
1569 }
1570
1571 const HANDLE pipeRecvClient = pipe2;
1572 const HANDLE pipeSendClient = pipe1;
1573#else
1574 int pipe1[2]; // read by server, written by client
1575 int pipe2[2]; // read by client, written by server
1576
1577 if (::pipe(pipe1) != 0)
1578 {
1579 fail("pipe1 creation failed");
1580 return false;
1581 }
1582
1583 if (::pipe(pipe2) != 0)
1584 {
1585 try { ::close(pipe1[0]); } CARLA_SAFE_EXCEPTION("close(pipe1[0])");
1586 try { ::close(pipe1[1]); } CARLA_SAFE_EXCEPTION("close(pipe1[1])");
1587 fail("pipe2 creation failed");
1588 return false;
1589 }
1590
1591 /* */ int pipeRecvServer = pipe1[0];
1592 /* */ int pipeSendServer = pipe2[1];
1593 const int pipeRecvClient = pipe2[0];
1594 const int pipeSendClient = pipe1[1];
1595
1596 std::snprintf(pipeRecvServerStr, 100, "%i", pipeRecvServer);
1597 std::snprintf(pipeSendServerStr, 100, "%i", pipeSendServer);
1598 std::snprintf(pipeRecvClientStr, 100, "%i", pipeRecvClient);
1599 std::snprintf(pipeSendClientStr, 100, "%i", pipeSendClient);
1600
1601 //-----------------------------------------------------------------------------------------------------------------
1602 // set size, non-fatal
1603
1604# ifdef CARLA_OS_LINUX
1605 try {
1606 ::fcntl(pipeRecvClient, F_SETPIPE_SZ, size);
1607 } CARLA_SAFE_EXCEPTION("Set pipe size");
1608
1609 try {
1610 ::fcntl(pipeRecvServer, F_SETPIPE_SZ, size);
1611 } CARLA_SAFE_EXCEPTION("Set pipe size");
1612# endif
1613
1614 //-----------------------------------------------------------------------------------------------------------------
1615 // set non-block
1616
1617 int ret;
1618
1619 try {
1620 ret = ::fcntl(pipeRecvClient, F_SETFL, ::fcntl(pipeRecvClient, F_GETFL) | O_NONBLOCK);
1621 } catch (...) {
1622 ret = -1;
1623 fail("failed to set pipe as non-block");
1624 }
1625
1626 if (ret == 0)
1627 {
1628 try {
1629 ret = ::fcntl(pipeRecvServer, F_SETFL, ::fcntl(pipeRecvServer, F_GETFL) | O_NONBLOCK);
1630 } catch (...) {
1631 ret = -1;
1632 fail("failed to set pipe as non-block");
1633 }
1634 }
1635
1636 if (ret < 0)
1637 {
1638 try { ::close(pipe1[0]); } CARLA_SAFE_EXCEPTION("close(pipe1[0])");
1639 try { ::close(pipe1[1]); } CARLA_SAFE_EXCEPTION("close(pipe1[1])");
1640 try { ::close(pipe2[0]); } CARLA_SAFE_EXCEPTION("close(pipe2[0])");
1641 try { ::close(pipe2[1]); } CARLA_SAFE_EXCEPTION("close(pipe2[1])");
1642 return false;
1643 }
1644#endif
1645
1646 //-----------------------------------------------------------------------------------------------------------------
1647 // set arguments
1648
1649 const char* argv[9] = {};
1650 int i = 0;
1651
1652 if (helperTool != nullptr)
1653 argv[i++] = helperTool;
1654
1655 //-----------------------------------------------------------------------------------------------------------------
1656 // argv[0] => filename
1657
1658 argv[i++] = filename;
1659
1660 //-----------------------------------------------------------------------------------------------------------------
1661 // argv[1-2] => args
1662
1663 argv[i++] = arg1;
1664 argv[i++] = arg2;
1665
1666 //-----------------------------------------------------------------------------------------------------------------
1667 // argv[3-6] => pipes
1668
1669 argv[i++] = pipeRecvServerStr;
1670 argv[i++] = pipeSendServerStr;
1671 argv[i++] = pipeRecvClientStr;
1672 argv[i++] = pipeSendClientStr;
1673
1674 //-----------------------------------------------------------------------------------------------------------------
1675 // start process
1676
1677#ifdef CARLA_OS_WIN
1678 if (! startProcess(argv, &pData->processInfo))
1679 {
1680 carla_zeroStruct(pData->processInfo);
1681 pData->processInfo.hProcess = INVALID_HANDLE_VALUE;
1682 pData->processInfo.hThread = INVALID_HANDLE_VALUE;
1683 try { ::CloseHandle(pipe1); } CARLA_SAFE_EXCEPTION("CloseHandle(pipe1)");
1684 try { ::CloseHandle(pipe2); } CARLA_SAFE_EXCEPTION("CloseHandle(pipe2)");
1685 return false;
1686 }
1687
1688 // just to make sure
1689 CARLA_SAFE_ASSERT(pData->processInfo.hThread != INVALID_HANDLE_VALUE);
1690 CARLA_SAFE_ASSERT(pData->processInfo.hProcess != INVALID_HANDLE_VALUE);
1691#else
1692 if (! startProcess(argv, pData->pid))
1693 {
1694 pData->pid = -1;
1695 try { ::close(pipe1[0]); } CARLA_SAFE_EXCEPTION("close(pipe1[0])");
1696 try { ::close(pipe1[1]); } CARLA_SAFE_EXCEPTION("close(pipe1[1])");
1697 try { ::close(pipe2[0]); } CARLA_SAFE_EXCEPTION("close(pipe2[0])");
1698 try { ::close(pipe2[1]); } CARLA_SAFE_EXCEPTION("close(pipe2[1])");
1699 fail("startProcess() failed");
1700 return false;
1701 }
1702
1703 //-----------------------------------------------------------------------------------------------------------------
1704 // close duplicated handles used by the client
1705
1706 try { ::close(pipeRecvServer); } CARLA_SAFE_EXCEPTION("close(pipeRecvServer)");
1707 try { ::close(pipeSendServer); } CARLA_SAFE_EXCEPTION("close(pipeSendServer)");
1708#endif
1709
1710 //-----------------------------------------------------------------------------------------------------------------
1711 // wait for client to say something
1712
1713#ifdef CARLA_OS_WIN
1714 void* const ovRecv = pData->ovRecv;
1715 void* const process = pData->processInfo.hProcess;
1716#else
1717 void* const ovRecv = nullptr;
1718 void* const process = nullptr;
1719#endif
1720
1721 if (waitForClientFirstMessage(pipeRecvClient, ovRecv, process, timeOutMilliseconds))
1722 {
1723 pData->pipeRecv = pipeRecvClient;
1724 pData->pipeSend = pipeSendClient;
1725 pData->pipeClosed = false;
1726 carla_debug("ALL OK!");
1727 return true;
1728 }
1729
1730 //-----------------------------------------------------------------------------------------------------------------
1731 // failed to set non-block or get first child message, cannot continue
1732
1733#ifdef CARLA_OS_WIN
1734 if (::TerminateProcess(pData->processInfo.hProcess, 9) != FALSE)
1735 {
1736 // wait for process to stop
1737 waitForProcessToStop(pData->processInfo.hProcess, 2*1000, false);
1738 }
1739
1740 // clear pData->processInfo
1741 try { ::CloseHandle(pData->processInfo.hThread); } CARLA_SAFE_EXCEPTION("CloseHandle(pData->processInfo.hThread)");
1742 try { ::CloseHandle(pData->processInfo.hProcess); } CARLA_SAFE_EXCEPTION("CloseHandle(pData->processInfo.hProcess)");
1743 carla_zeroStruct(pData->processInfo);
1744 pData->processInfo.hProcess = INVALID_HANDLE_VALUE;
1745 pData->processInfo.hThread = INVALID_HANDLE_VALUE;
1746#else
1747 if (::kill(pData->pid, SIGKILL) != -1)
1748 {
1749 // wait for killing to take place
1750 waitForChildToStop(pData->pid, 2*1000, false);
1751 }
1752 pData->pid = -1;
1753#endif
1754
1755 //-----------------------------------------------------------------------------------------------------------------
1756 // close pipes
1757
1758#ifdef CARLA_OS_WIN
1759 try { ::CloseHandle(pipeRecvClient); } CARLA_SAFE_EXCEPTION("CloseHandle(pipeRecvClient)");
1760 try { ::CloseHandle(pipeSendClient); } CARLA_SAFE_EXCEPTION("CloseHandle(pipeSendClient)");
1761#else
1762 try { ::close (pipeRecvClient); } CARLA_SAFE_EXCEPTION("close(pipeRecvClient)");
1763 try { ::close (pipeSendClient); } CARLA_SAFE_EXCEPTION("close(pipeSendClient)");
1764#endif
1765
1766 return false;
1767
1768 // maybe unused
1769 (void)size; (void)ovRecv; (void)process;
1770}
1771
1772bool CarlaPipeServer::startPipeServer(const char* const filename,
1773 const char* const arg1,
1774 const char* const arg2,
1775 const int size,
1776 const int timeOutMilliseconds) noexcept
1777{
1778 return startPipeServer(nullptr, filename, arg1, arg2, size, timeOutMilliseconds);
1779}
1780
1781void CarlaPipeServer::stopPipeServer(const uint32_t timeOutMilliseconds) noexcept
1782{
1783 carla_debug("CarlaPipeServer::stopPipeServer(%i)", timeOutMilliseconds);
1784
1785#ifdef CARLA_OS_WIN
1786 if (pData->processInfo.hThread != INVALID_HANDLE_VALUE || pData->processInfo.hProcess != INVALID_HANDLE_VALUE)
1787 {
1788 const CarlaMutexLocker cml(pData->writeLock);
1789
1790 if (pData->pipeSend != INVALID_PIPE_VALUE && ! pData->pipeClosed)
1791 {
1792 if (_writeMsgBuffer("__carla-quit__\n", 15))
1793 syncMessages();
1794 }
1795
1796 waitForProcessToStopOrKillIt(pData->processInfo.hProcess, timeOutMilliseconds);
1797 try { ::CloseHandle(pData->processInfo.hThread); } CARLA_SAFE_EXCEPTION("CloseHandle(pData->processInfo.hThread)");
1798 try { ::CloseHandle(pData->processInfo.hProcess); } CARLA_SAFE_EXCEPTION("CloseHandle(pData->processInfo.hProcess)");
1799 carla_zeroStruct(pData->processInfo);
1800 pData->processInfo.hProcess = INVALID_HANDLE_VALUE;
1801 pData->processInfo.hThread = INVALID_HANDLE_VALUE;
1802 }
1803#else
1804 if (pData->pid != -1)
1805 {
1806 const CarlaMutexLocker cml(pData->writeLock);
1807
1808 if (pData->pipeSend != INVALID_PIPE_VALUE && ! pData->pipeClosed)
1809 {
1810 if (_writeMsgBuffer("__carla-quit__\n", 15))
1811 syncMessages();
1812 }
1813
1814 waitForChildToStopOrKillIt(pData->pid, timeOutMilliseconds);
1815 pData->pid = -1;
1816 }
1817#endif
1818
1819 closePipeServer();
1820}
1821
1822void CarlaPipeServer::closePipeServer() noexcept
1823{
1824 carla_debug("CarlaPipeServer::closePipeServer()");
1825
1826 pData->pipeClosed = true;
1827
1828 const CarlaMutexLocker cml(pData->writeLock);
1829
1830 if (pData->pipeRecv != INVALID_PIPE_VALUE)
1831 {
1832#ifdef CARLA_OS_WIN
1833 DisconnectNamedPipe(pData->pipeRecv);
1834
1835 try { ::CloseHandle(pData->pipeRecv); } CARLA_SAFE_EXCEPTION("CloseHandle(pData->pipeRecv)");
1836#else
1837 try { ::close (pData->pipeRecv); } CARLA_SAFE_EXCEPTION("close(pData->pipeRecv)");
1838#endif
1839 pData->pipeRecv = INVALID_PIPE_VALUE;
1840 }
1841
1842 if (pData->pipeSend != INVALID_PIPE_VALUE)
1843 {
1844#ifdef CARLA_OS_WIN
1845 DisconnectNamedPipe(pData->pipeSend);
1846
1847 try { ::CloseHandle(pData->pipeSend); } CARLA_SAFE_EXCEPTION("CloseHandle(pData->pipeSend)");
1848#else
1849 try { ::close (pData->pipeSend); } CARLA_SAFE_EXCEPTION("close(pData->pipeSend)");
1850#endif
1851 pData->pipeSend = INVALID_PIPE_VALUE;
1852 }
1853}
1854
1855void CarlaPipeServer::writeShowMessage() const noexcept
1856{
1857 const CarlaMutexLocker cml(pData->writeLock);
1858
1859 if (! _writeMsgBuffer("show\n", 5))
1860 return;
1861
1862 syncMessages();
1863}
1864
1865void CarlaPipeServer::writeFocusMessage() const noexcept
1866{
1867 const CarlaMutexLocker cml(pData->writeLock);
1868
1869 if (! _writeMsgBuffer("focus\n", 6))
1870 return;
1871
1872 syncMessages();
1873}
1874
1875void CarlaPipeServer::writeHideMessage() const noexcept
1876{
1877 const CarlaMutexLocker cml(pData->writeLock);
1878
1879 if (! _writeMsgBuffer("show\n", 5))
1880 return;
1881
1882 syncMessages();
1883}
1884
1885// -----------------------------------------------------------------------
1886
1887CarlaPipeClient::CarlaPipeClient() noexcept
1888 : CarlaPipeCommon()
1889{
1890 carla_debug("CarlaPipeClient::CarlaPipeClient()");
1891}
1892
1893CarlaPipeClient::~CarlaPipeClient() /*noexcept*/
1894{
1895 carla_debug("CarlaPipeClient::~CarlaPipeClient()");
1896
1897 closePipeClient();
1898}
1899
1900bool CarlaPipeClient::initPipeClient(const char* argv[]) noexcept
1901{
1902 CARLA_SAFE_ASSERT_RETURN(pData->pipeRecv == INVALID_PIPE_VALUE, false);
1903 CARLA_SAFE_ASSERT_RETURN(pData->pipeSend == INVALID_PIPE_VALUE, false);
1904 carla_debug("CarlaPipeClient::initPipeClient(%p)", argv);
1905
1906 const CarlaMutexLocker cml(pData->writeLock);
1907
1908 //----------------------------------------------------------------
1909 // read arguments
1910
1911#ifdef CARLA_OS_WIN
1912 const char* const pipeRecvServerStr = argv[3];
1913 const char* const pipeSendServerStr = argv[4];
1914
1915 HANDLE pipeRecvServer = ::CreateFileA(pipeRecvServerStr, GENERIC_READ, 0x0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
1916 HANDLE pipeSendServer = ::CreateFileA(pipeSendServerStr, GENERIC_WRITE, 0x0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
1917
1918 CARLA_SAFE_ASSERT_RETURN(pipeRecvServer != INVALID_HANDLE_VALUE, false);
1919 CARLA_SAFE_ASSERT_RETURN(pipeSendServer != INVALID_HANDLE_VALUE, false);
1920#else
1921 const int pipeRecvServer = std::atoi(argv[3]);
1922 const int pipeSendServer = std::atoi(argv[4]);
1923 /* */ int pipeRecvClient = std::atoi(argv[5]);
1924 /* */ int pipeSendClient = std::atoi(argv[6]);
1925
1926 CARLA_SAFE_ASSERT_RETURN(pipeRecvServer > 0, false);
1927 CARLA_SAFE_ASSERT_RETURN(pipeSendServer > 0, false);
1928 CARLA_SAFE_ASSERT_RETURN(pipeRecvClient > 0, false);
1929 CARLA_SAFE_ASSERT_RETURN(pipeSendClient > 0, false);
1930
1931 //----------------------------------------------------------------
1932 // close duplicated handles used by the client
1933
1934 try { ::close(pipeRecvClient); } CARLA_SAFE_EXCEPTION("close(pipeRecvClient)");
1935 try { ::close(pipeSendClient); } CARLA_SAFE_EXCEPTION("close(pipeSendClient)");
1936
1937 //----------------------------------------------------------------
1938 // kill ourselves if parent dies
1939
1940 carla_terminateProcessOnParentExit(false);
1941#endif
1942
1943 //----------------------------------------------------------------
1944 // done
1945
1946 pData->pipeRecv = pipeRecvServer;
1947 pData->pipeSend = pipeSendServer;
1948 pData->pipeClosed = false;
1949 pData->clientClosingDown = false;
1950
1951 if (writeMessage("\n", 1))
1952 syncMessages();
1953
1954 return true;
1955}
1956
1957void CarlaPipeClient::closePipeClient() noexcept
1958{
1959 carla_debug("CarlaPipeClient::closePipeClient()");
1960
1961 pData->pipeClosed = true;
1962
1963 const CarlaMutexLocker cml(pData->writeLock);
1964
1965 if (pData->pipeRecv != INVALID_PIPE_VALUE)
1966 {
1967#ifdef CARLA_OS_WIN
1968 try { ::CloseHandle(pData->pipeRecv); } CARLA_SAFE_EXCEPTION("CloseHandle(pData->pipeRecv)");
1969#else
1970 try { ::close (pData->pipeRecv); } CARLA_SAFE_EXCEPTION("close(pData->pipeRecv)");
1971#endif
1972 pData->pipeRecv = INVALID_PIPE_VALUE;
1973 }
1974
1975 if (pData->pipeSend != INVALID_PIPE_VALUE)
1976 {
1977#ifdef CARLA_OS_WIN
1978 try { ::CloseHandle(pData->pipeSend); } CARLA_SAFE_EXCEPTION("CloseHandle(pData->pipeSend)");
1979#else
1980 try { ::close (pData->pipeSend); } CARLA_SAFE_EXCEPTION("close(pData->pipeSend)");
1981#endif
1982 pData->pipeSend = INVALID_PIPE_VALUE;
1983 }
1984}
1985
1986void CarlaPipeClient::writeExitingMessageAndWait() noexcept
1987{
1988 {
1989 const CarlaMutexLocker cml(pData->writeLock);
1990
1991 if (_writeMsgBuffer("exiting\n", 8))
1992 syncMessages();
1993 }
1994
1995 // NOTE: no more messages are handled after this point
1996 pData->clientClosingDown = true;
1997
1998 for (int i=0; i < 100 && ! pData->pipeClosed; ++i)
1999 {
2000 carla_msleep(50);
2001 idlePipe(true);
2002 }
2003
2004 if (! pData->pipeClosed)
2005 carla_stderr2("writeExitingMessageAndWait pipe is still running!");
2006}
2007
2008// -----------------------------------------------------------------------
2009
2010#undef INVALID_PIPE_VALUE
#define P_SSIZE
Definition CarlaDefines.h:141
#define CARLA_SAFE_EXCEPTION(msg)
Definition CarlaDefines.h:228
#define CARLA_SAFE_EXCEPTION_RETURN(msg, ret)
Definition CarlaDefines.h:231
#define CARLA_SAFE_ASSERT_RETURN(cond, ret)
Definition CarlaDefines.h:190
unsigned int uint
Definition CarlaDefines.h:327
unsigned long int ulong
Definition CarlaDefines.h:328
#define CARLA_SAFE_EXCEPTION_BREAK(msg)
Definition CarlaDefines.h:229
#define P_SIZE
Definition CarlaDefines.h:140
#define CARLA_SAFE_ASSERT_INT2_RETURN(cond, v1, v2, ret)
Definition CarlaDefines.h:207
#define CARLA_SAFE_ASSERT(cond)
Definition CarlaDefines.h:182
#define CARLA_DECLARE_NON_COPYABLE(ClassName)
Definition CarlaDefines.h:242
#define MAX_MIDI_CHANNELS
Definition CarlaMIDI.h:21
#define MAX_MIDI_NOTE
Definition CarlaMIDI.h:22
#define MAX_MIDI_VALUE
Definition CarlaMIDI.h:23
#define noexcept
Definition DistrhoDefines.h:72
float arg(const fft_t *freqs, off_t x)
Definition OscilGen.cpp:58
void process(Alg_seq_ptr seq, bool tempo_flag, double tempo, bool flatten_flag)
Definition allegroconvert.cpp:42
Definition CarlaMutex.cpp:8
Definition String.h:48
String trim() const
Definition String.cpp:1540
const char * toRawUTF8() const
Definition String.cpp:1925
Definition String.h:48
register unsigned i
Definition inflate.c:1575
static char filename[]
Definition features.c:5
static PuglViewHint int value
Definition pugl.h:1708
char * argv[]
Definition unzip.c:738
static uint32_t lv2_atom_total_size(const LV2_Atom *atom)
Definition atom-util.h:55
static SordNode * uri(SordWorld *world, int num)
Definition sord_test.c:47
unsigned short uint16_t
Definition mid.cpp:99
int int32_t
Definition mid.cpp:97
unsigned int uint32_t
Definition mid.cpp:100
unsigned char uint8_t
Definition mid.cpp:98
const char * msg
Definition missing_descriptor.c:20
jack_client_t client jack_client_t client jack_client_t client jack_client_t JackInfoShutdownCallback void arg jack_client_t jack_port_t port void func jack_client_t const char const char unsigned long flags const jack_port_t port jack_client_t jack_port_id_t port_id const jack_port_t const char port_name const jack_port_t port void * ptr
Definition juce_linux_JackAudio.cpp:79
#define P(protos)
Definition proto.h:37
Definition CarlaPipeUtils.cpp:576
CarlaString tmpStr
Definition CarlaPipeUtils.cpp:610
pid_t pid
Definition CarlaPipeUtils.cpp:585
int pipeSend
Definition CarlaPipeUtils.cpp:587
char tmpBuf[0xffff]
Definition CarlaPipeUtils.cpp:609
bool isReading
Definition CarlaPipeUtils.cpp:591
int pipeRecv
Definition CarlaPipeUtils.cpp:586
PrivateData() noexcept
Definition CarlaPipeUtils.cpp:612
bool clientClosingDown
Definition CarlaPipeUtils.cpp:594
bool lastMessageFailed
Definition CarlaPipeUtils.cpp:600
CarlaMutex writeLock
Definition CarlaPipeUtils.cpp:606
bool isServer
Definition CarlaPipeUtils.cpp:603
bool pipeClosed
Definition CarlaPipeUtils.cpp:597
Definition atom.h:106
Definition swell-types.h:254
#define INFINITE
#define WAIT_OBJECT_0
#define WAIT_FAILED
char * LPSTR
Definition swell-types.h:189
unsigned int DWORD
Definition swell-types.h:164
void * HANDLE
Definition swell-types.h:212
DWORD WaitForSingleObject(HANDLE hand, DWORD msTO)
Definition swell.cpp:297
HANDLE CreateEvent(void *SA, BOOL manualReset, BOOL initialSig, const char *ignored)
Definition swell.cpp:476
BOOL CloseHandle(HANDLE hand)
Definition swell.cpp:157
return c
Definition crypt.c:175
ZCONST char * key
Definition crypt.c:587
int error
Definition extract.c:1038
ulg size
Definition extract.c:2350
read(f, &c, 1)
#define void
Definition unzip.h:396
#define TRUE
Definition unzpriv.h:1295
#define FALSE
Definition unzpriv.h:1298
static bool waitForClientFirstMessage(const P &pipe, void *const ovRecv, void *const process, const uint32_t timeOutMilliseconds) noexcept
Definition CarlaPipeUtils.cpp:364
static void waitForChildToStopOrKillIt(pid_t &pid, const uint32_t timeOutMilliseconds) noexcept
Definition CarlaPipeUtils.cpp:551
static bool startProcess(const char *const argv[], pid_t &pidinst) noexcept
Definition CarlaPipeUtils.cpp:324
#define INVALID_PIPE_VALUE
Definition CarlaPipeUtils.cpp:56
static bool waitForChildToStop(const pid_t pid, const uint32_t timeOutMilliseconds, bool sendTerminate) noexcept
Definition CarlaPipeUtils.cpp:487
#define const
Definition zconf.h:137