| 
							- /*
 -  * Carla Log Thread
 -  * Copyright (C) 2013-2019 Filipe Coelho <falktx@falktx.com>
 -  *
 -  * This program is free software; you can redistribute it and/or
 -  * modify it under the terms of the GNU General Public License as
 -  * published by the Free Software Foundation; either version 2 of
 -  * the License, or any later version.
 -  *
 -  * This program is distributed in the hope that it will be useful,
 -  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 -  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 -  * GNU General Public License for more details.
 -  *
 -  * For a full copy of the GNU General Public License see the doc/GPL.txt file.
 -  */
 - 
 - #ifndef CARLA_LOG_THREAD_HPP_INCLUDED
 - #define CARLA_LOG_THREAD_HPP_INCLUDED
 - 
 - #include "CarlaBackend.h"
 - #include "CarlaString.hpp"
 - #include "CarlaThread.hpp"
 - 
 - #include <fcntl.h>
 - 
 - #ifdef CARLA_OS_WIN
 - # include <io.h>
 - # define _close(fd) close(fd)
 - # define _dup2(f1,f2) dup2(f1,f2)
 - #endif
 - 
 - using CarlaBackend::EngineCallbackFunc;
 - 
 - // -----------------------------------------------------------------------
 - // Log thread
 - 
 - class CarlaLogThread : private CarlaThread
 - {
 - public:
 -     CarlaLogThread()
 -         : CarlaThread("CarlaLogThread"),
 -           fStdOut(-1),
 -           fStdErr(-1),
 -           fCallback(nullptr),
 -           fCallbackPtr(nullptr) {}
 - 
 -     ~CarlaLogThread()
 -     {
 -         stop();
 -     }
 - 
 -     void init()
 -     {
 -         std::fflush(stdout);
 -         std::fflush(stderr);
 - 
 - #ifdef CARLA_OS_WIN
 -         // TODO: use process id instead
 -         const int randint = std::rand();
 - 
 -         char strBuf[0xff+1];
 -         strBuf[0xff] = '\0';
 -         std::snprintf(strBuf, 0xff, "\\\\.\\pipe\\carlalogthread-%i", randint);
 - 
 -         fPipe[0] = CreateNamedPipeA(strBuf, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_READMODE_BYTE|PIPE_NOWAIT, 2, 4096, 4096, 0, nullptr);
 -         fPipe[1] = CreateFileA(strBuf, GENERIC_WRITE, 0x0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
 - 
 -         CARLA_SAFE_ASSERT_RETURN(fPipe[0] != INVALID_HANDLE_VALUE,);
 -         CARLA_SAFE_ASSERT_RETURN(fPipe[1] != INVALID_HANDLE_VALUE,);
 - 
 -         const int pipe1 = _open_osfhandle((INT_PTR)fPipe[1], _O_WRONLY | _O_BINARY);
 - #else
 -         CARLA_SAFE_ASSERT_RETURN(pipe(fPipe) == 0,);
 - 
 -         if (fcntl(fPipe[0], F_SETFL, O_NONBLOCK) != 0)
 -         {
 -             close(fPipe[0]);
 -             close(fPipe[1]);
 -             return;
 -         }
 - 
 -         const int pipe1 = fPipe[1];
 - #endif
 - 
 -         fStdOut = dup(STDOUT_FILENO);
 -         fStdErr = dup(STDERR_FILENO);
 - 
 -         dup2(pipe1, STDOUT_FILENO);
 -         dup2(pipe1, STDERR_FILENO);
 - 
 -         startThread();
 -     }
 - 
 -     void stop()
 -     {
 -         if (fStdOut == -1)
 -             return;
 - 
 -         stopThread(5000);
 - 
 -         std::fflush(stdout);
 -         std::fflush(stderr);
 - 
 - #ifdef CARLA_OS_WIN
 -         CloseHandle(fPipe[0]);
 -         CloseHandle(fPipe[1]);
 - #else
 -         close(fPipe[0]);
 -         close(fPipe[1]);
 - #endif
 - 
 -         dup2(fStdOut, STDOUT_FILENO);
 -         dup2(fStdErr, STDERR_FILENO);
 -         close(fStdOut);
 -         close(fStdErr);
 -         fStdOut = -1;
 -         fStdErr = -1;
 -     }
 - 
 -     void setCallback(EngineCallbackFunc callback, void* callbackPtr)
 -     {
 -         CARLA_SAFE_ASSERT_RETURN(callback != nullptr,);
 - 
 -         fCallback    = callback;
 -         fCallbackPtr = callbackPtr;
 -     }
 - 
 - protected:
 -     void run()
 -     {
 -         CARLA_SAFE_ASSERT_RETURN(fCallback != nullptr,);
 - 
 -         size_t k, bufTempPos;
 -         ssize_t r, lastRead;
 -         char bufTemp[1024+1];
 -         char bufRead[1024+1];
 -         char bufSend[2048+1];
 - 
 -         bufTemp[0] = '\0';
 -         bufTempPos = 0;
 - 
 -         while (! shouldThreadExit())
 -         {
 -             bufRead[0] = '\0';
 - 
 -             while ((r = read(fPipe[0], bufRead, 1024)) > 0)
 -             {
 -                 CARLA_SAFE_ASSERT_CONTINUE(r <= 1024);
 - 
 -                 bufRead[r] = '\0';
 -                 lastRead = 0;
 - 
 -                 for (ssize_t i=0; i<r; ++i)
 -                 {
 -                     CARLA_SAFE_ASSERT_BREAK(bufRead[i] != '\0');
 - 
 -                     if (bufRead[i] != '\n')
 -                         continue;
 - 
 -                     k = static_cast<size_t>(i-lastRead);
 - 
 -                     if (bufTempPos != 0)
 -                     {
 -                         std::memcpy(bufSend, bufTemp, bufTempPos);
 -                         std::memcpy(bufSend+bufTempPos, bufRead+lastRead, k);
 -                         k += bufTempPos;
 -                     }
 -                     else
 -                     {
 -                         std::memcpy(bufSend, bufRead+lastRead, k);
 -                     }
 - 
 -                     lastRead   = i+1;
 -                     bufSend[k] = '\0';
 -                     bufTemp[0] = '\0';
 -                     bufTempPos = 0;
 - 
 -                     fCallback(fCallbackPtr, CarlaBackend::ENGINE_CALLBACK_DEBUG, 0, 0, 0, 0, 0.0f, bufSend);
 -                 }
 - 
 -                 if (lastRead > 0 && lastRead != r)
 -                 {
 -                     k = static_cast<size_t>(r-lastRead);
 -                     std::memcpy(bufTemp, bufRead+lastRead, k);
 -                     bufTemp[k] = '\0';
 -                     bufTempPos = k;
 -                 }
 -             }
 - 
 -             carla_msleep(20);
 -         }
 -     }
 - 
 - private:
 - #ifdef CARLA_OS_WIN
 -     HANDLE fPipe[2];
 - #else
 -     int fPipe[2];
 - #endif
 - 
 -     int fStdOut;
 -     int fStdErr;
 - 
 -     EngineCallbackFunc fCallback;
 -     void*              fCallbackPtr;
 - 
 - #ifdef CARLA_OS_WIN
 -     ssize_t read(const HANDLE pipeh, void* const buf, DWORD numBytes)
 -     {
 -         if (ReadFile(pipeh, buf, numBytes, &numBytes, nullptr) != FALSE)
 -             return numBytes;
 -         return -1;
 -     }
 - #endif
 - 
 -     //CARLA_PREVENT_HEAP_ALLOCATION
 -     CARLA_DECLARE_NON_COPY_CLASS(CarlaLogThread)
 - };
 - 
 - #ifdef CARLA_OS_WIN
 - # undef close
 - # undef dup2
 - #endif
 - 
 - // -----------------------------------------------------------------------
 - 
 - #endif // CARLA_LOG_THREAD_HPP_INCLUDED
 
 
  |