|
|
|
@@ -29,11 +29,7 @@ public: |
|
|
|
Pimpl (const String& pipePath, bool createPipe)
|
|
|
|
: pipeInName (pipePath + "_in"),
|
|
|
|
pipeOutName (pipePath + "_out"),
|
|
|
|
pipeIn (-1), pipeOut (-1),
|
|
|
|
createdFifoIn (false),
|
|
|
|
createdFifoOut (false),
|
|
|
|
createdPipe (createPipe),
|
|
|
|
stopReadOperation (false)
|
|
|
|
createdPipe (createPipe)
|
|
|
|
{
|
|
|
|
signal (SIGPIPE, signalHandler);
|
|
|
|
juce_siginterrupt (SIGPIPE, 1);
|
|
|
|
@@ -53,7 +49,7 @@ public: |
|
|
|
|
|
|
|
int read (char* destBuffer, int maxBytesToRead, int timeOutMilliseconds)
|
|
|
|
{
|
|
|
|
const uint32 timeoutEnd = getTimeoutEnd (timeOutMilliseconds);
|
|
|
|
auto timeoutEnd = getTimeoutEnd (timeOutMilliseconds);
|
|
|
|
|
|
|
|
if (pipeIn == -1)
|
|
|
|
{
|
|
|
|
@@ -67,12 +63,12 @@ public: |
|
|
|
|
|
|
|
while (bytesRead < maxBytesToRead)
|
|
|
|
{
|
|
|
|
const int bytesThisTime = maxBytesToRead - bytesRead;
|
|
|
|
const int numRead = (int) ::read (pipeIn, destBuffer, (size_t) bytesThisTime);
|
|
|
|
auto bytesThisTime = maxBytesToRead - bytesRead;
|
|
|
|
auto numRead = (int) ::read (pipeIn, destBuffer, (size_t) bytesThisTime);
|
|
|
|
|
|
|
|
if (numRead <= 0)
|
|
|
|
{
|
|
|
|
if (errno != EWOULDBLOCK || stopReadOperation || hasExpired (timeoutEnd))
|
|
|
|
if (errno != EWOULDBLOCK || stopReadOperation.load() || hasExpired (timeoutEnd))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
const int maxWaitingTime = 30;
|
|
|
|
@@ -91,7 +87,7 @@ public: |
|
|
|
|
|
|
|
int write (const char* sourceBuffer, int numBytesToWrite, int timeOutMilliseconds)
|
|
|
|
{
|
|
|
|
const uint32 timeoutEnd = getTimeoutEnd (timeOutMilliseconds);
|
|
|
|
auto timeoutEnd = getTimeoutEnd (timeOutMilliseconds);
|
|
|
|
|
|
|
|
if (pipeOut == -1)
|
|
|
|
{
|
|
|
|
@@ -105,8 +101,8 @@ public: |
|
|
|
|
|
|
|
while (bytesWritten < numBytesToWrite && ! hasExpired (timeoutEnd))
|
|
|
|
{
|
|
|
|
const int bytesThisTime = numBytesToWrite - bytesWritten;
|
|
|
|
const int numWritten = (int) ::write (pipeOut, sourceBuffer, (size_t) bytesThisTime);
|
|
|
|
auto bytesThisTime = numBytesToWrite - bytesWritten;
|
|
|
|
auto numWritten = (int) ::write (pipeOut, sourceBuffer, (size_t) bytesThisTime);
|
|
|
|
|
|
|
|
if (numWritten <= 0)
|
|
|
|
return -1;
|
|
|
|
@@ -132,39 +128,39 @@ public: |
|
|
|
}
|
|
|
|
|
|
|
|
const String pipeInName, pipeOutName;
|
|
|
|
int pipeIn, pipeOut;
|
|
|
|
bool createdFifoIn, createdFifoOut;
|
|
|
|
int pipeIn = -1, pipeOut = -1;
|
|
|
|
bool createdFifoIn = false, createdFifoOut = false;
|
|
|
|
|
|
|
|
const bool createdPipe;
|
|
|
|
bool stopReadOperation;
|
|
|
|
std::atomic<bool> stopReadOperation { false };
|
|
|
|
|
|
|
|
private:
|
|
|
|
static void signalHandler (int) {}
|
|
|
|
|
|
|
|
static uint32 getTimeoutEnd (const int timeOutMilliseconds)
|
|
|
|
static uint32 getTimeoutEnd (int timeOutMilliseconds)
|
|
|
|
{
|
|
|
|
return timeOutMilliseconds >= 0 ? Time::getMillisecondCounter() + (uint32) timeOutMilliseconds : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool hasExpired (const uint32 timeoutEnd)
|
|
|
|
static bool hasExpired (uint32 timeoutEnd)
|
|
|
|
{
|
|
|
|
return timeoutEnd != 0 && Time::getMillisecondCounter() >= timeoutEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
int openPipe (const String& name, int flags, const uint32 timeoutEnd)
|
|
|
|
int openPipe (const String& name, int flags, uint32 timeoutEnd)
|
|
|
|
{
|
|
|
|
for (;;)
|
|
|
|
{
|
|
|
|
const int p = ::open (name.toUTF8(), flags);
|
|
|
|
auto p = ::open (name.toUTF8(), flags);
|
|
|
|
|
|
|
|
if (p != -1 || hasExpired (timeoutEnd) || stopReadOperation)
|
|
|
|
if (p != -1 || hasExpired (timeoutEnd) || stopReadOperation.load())
|
|
|
|
return p;
|
|
|
|
|
|
|
|
Thread::sleep (2);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void waitForInput (const int handle, const int timeoutMsecs) noexcept
|
|
|
|
static void waitForInput (int handle, int timeoutMsecs) noexcept
|
|
|
|
{
|
|
|
|
struct timeval timeout;
|
|
|
|
timeout.tv_sec = timeoutMsecs / 1000;
|
|
|
|
@@ -195,13 +191,13 @@ void NamedPipe::close() |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool NamedPipe::openInternal (const String& pipeName, const bool createPipe, bool mustNotExist)
|
|
|
|
bool NamedPipe::openInternal (const String& pipeName, bool createPipe, bool mustNotExist)
|
|
|
|
{
|
|
|
|
#if JUCE_IOS
|
|
|
|
pimpl.reset (new Pimpl (File::getSpecialLocation (File::tempDirectory)
|
|
|
|
.getChildFile (File::createLegalFileName (pipeName)).getFullPathName(), createPipe));
|
|
|
|
#else
|
|
|
|
String file (pipeName);
|
|
|
|
auto file = pipeName;
|
|
|
|
|
|
|
|
if (! File::isAbsolutePath (file))
|
|
|
|
file = "/tmp/" + File::createLegalFileName (file);
|
|
|
|
|