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.

174 lines
4.3KB

  1. /*
  2. * Carla Log Thread
  3. * Copyright (C) 2013-2016 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. #ifndef CARLA_LOG_THREAD_HPP_INCLUDED
  18. #define CARLA_LOG_THREAD_HPP_INCLUDED
  19. #include "CarlaBackend.h"
  20. #include "CarlaString.hpp"
  21. #include "CarlaThread.hpp"
  22. #include <fcntl.h>
  23. using CarlaBackend::EngineCallbackFunc;
  24. // -----------------------------------------------------------------------
  25. // Log thread
  26. class CarlaLogThread : private CarlaThread
  27. {
  28. public:
  29. CarlaLogThread()
  30. : CarlaThread("CarlaLogThread"),
  31. fStdOut(-1),
  32. fStdErr(-1),
  33. fCallback(nullptr),
  34. fCallbackPtr(nullptr) {}
  35. ~CarlaLogThread()
  36. {
  37. stop();
  38. }
  39. void init()
  40. {
  41. CARLA_SAFE_ASSERT_RETURN(pipe(fPipe) == 0,);
  42. CARLA_SAFE_ASSERT_RETURN(fcntl(fPipe[0], F_SETFL, O_NONBLOCK) == 0,);
  43. std::fflush(stdout);
  44. std::fflush(stderr);
  45. fStdOut = dup(STDOUT_FILENO);
  46. fStdErr = dup(STDERR_FILENO);
  47. dup2(fPipe[1], STDOUT_FILENO);
  48. dup2(fPipe[1], STDERR_FILENO);
  49. startThread();
  50. }
  51. void stop()
  52. {
  53. if (fStdOut != -1)
  54. return;
  55. stopThread(5000);
  56. std::fflush(stdout);
  57. std::fflush(stderr);
  58. close(fPipe[0]);
  59. close(fPipe[1]);
  60. dup2(fStdOut, STDOUT_FILENO);
  61. dup2(fStdErr, STDERR_FILENO);
  62. close(fStdOut);
  63. close(fStdErr);
  64. fStdOut = -1;
  65. fStdErr = -1;
  66. }
  67. void setCallback(EngineCallbackFunc callback, void* callbackPtr)
  68. {
  69. CARLA_SAFE_ASSERT_RETURN(callback != nullptr,);
  70. fCallback = callback;
  71. fCallbackPtr = callbackPtr;
  72. }
  73. protected:
  74. void run()
  75. {
  76. CARLA_SAFE_ASSERT_RETURN(fCallback != nullptr,);
  77. size_t k, bufTempPos;
  78. ssize_t r, lastRead;
  79. char bufTemp[1024+1];
  80. char bufRead[1024+1];
  81. char bufSend[2048+1];
  82. bufTemp[0] = '\0';
  83. bufTempPos = 0;
  84. while (! shouldThreadExit())
  85. {
  86. bufRead[0] = '\0';
  87. while ((r = read(fPipe[0], bufRead, 1024)) > 0)
  88. {
  89. CARLA_SAFE_ASSERT_CONTINUE(r <= 1024);
  90. bufRead[r] = '\0';
  91. lastRead = 0;
  92. for (ssize_t i=0; i<r; ++i)
  93. {
  94. CARLA_SAFE_ASSERT_BREAK(bufRead[i] != '\0');
  95. if (bufRead[i] != '\n')
  96. continue;
  97. k = static_cast<size_t>(i-lastRead);
  98. if (bufTempPos != 0)
  99. {
  100. std::memcpy(bufSend, bufTemp, bufTempPos);
  101. std::memcpy(bufSend+bufTempPos, bufRead+lastRead, k);
  102. k += bufTempPos;
  103. }
  104. else
  105. {
  106. std::memcpy(bufSend, bufRead+lastRead, k);
  107. }
  108. lastRead = i+1;
  109. bufSend[k] = '\0';
  110. bufTemp[0] = '\0';
  111. bufTempPos = 0;
  112. fCallback(fCallbackPtr, CarlaBackend::ENGINE_CALLBACK_DEBUG, 0, 0, 0, 0.0f, bufSend);
  113. }
  114. if (lastRead > 0 && lastRead != r)
  115. {
  116. k = static_cast<size_t>(r-lastRead);
  117. std::memcpy(bufTemp, bufRead+lastRead, k);
  118. bufTemp[k] = '\0';
  119. bufTempPos = k;
  120. }
  121. }
  122. carla_msleep(20);
  123. }
  124. }
  125. private:
  126. int fPipe[2];
  127. int fStdOut;
  128. int fStdErr;
  129. EngineCallbackFunc fCallback;
  130. void* fCallbackPtr;
  131. //CARLA_PREVENT_HEAP_ALLOCATION
  132. CARLA_DECLARE_NON_COPY_CLASS(CarlaLogThread)
  133. };
  134. // -----------------------------------------------------------------------
  135. #endif // CARLA_LOG_THREAD_HPP_INCLUDED