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.

CarlaShmUtils.hpp 4.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. /*
  2. * Carla shared memory utils
  3. * Copyright (C) 2013 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 GPL.txt file
  16. */
  17. #ifndef __CARLA_SHM_UTILS_HPP__
  18. #define __CARLA_SHM_UTILS_HPP__
  19. #include "CarlaUtils.hpp"
  20. #ifdef CARLA_OS_WIN
  21. struct shm_t { HANDLE shm; HANDLE map; };
  22. #else
  23. # include <fcntl.h>
  24. # include <sys/mman.h>
  25. typedef int shm_t;
  26. #endif
  27. // -------------------------------------------------
  28. // shared memory calls
  29. static inline
  30. bool carla_is_shm_valid(const shm_t& shm)
  31. {
  32. #ifdef CARLA_OS_WIN
  33. return (shm.shm != nullptr && shm.shm != INVALID_HANDLE_VALUE);
  34. #else
  35. return (shm >= 0);
  36. #endif
  37. }
  38. static inline
  39. void carla_shm_init(shm_t& shm)
  40. {
  41. #ifdef CARLA_OS_WIN
  42. shm.shm = nullptr;
  43. shm.map = nullptr;
  44. #else
  45. shm = -1;
  46. #endif
  47. }
  48. #ifdef CARLA_OS_WIN
  49. static inline
  50. shm_t carla_shm_create(const char* const name)
  51. {
  52. CARLA_ASSERT(name != nullptr);
  53. shm_t ret;
  54. ret.shm = nullptr; // TODO
  55. ret.map = nullptr;
  56. return ret;
  57. }
  58. static inline
  59. shm_t carla_shm_attach(const char* const name)
  60. {
  61. CARLA_ASSERT(name != nullptr);
  62. shm_t ret;
  63. ret.shm = CreateFileA(name, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
  64. ret.map = nullptr;
  65. return ret;
  66. }
  67. static inline
  68. shm_t carla_shm_attach_linux(const char* const name)
  69. {
  70. CARLA_ASSERT(name != nullptr);
  71. char shmName[std::strlen(name)+10];
  72. std::strcpy(shmName, "/dev/shm/");
  73. std::strcat(shmName, name);
  74. shm_t ret;
  75. ret.shm = CreateFileA(shmName, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
  76. ret.map = nullptr;
  77. return ret;
  78. }
  79. #else
  80. static inline
  81. shm_t carla_shm_create(const char* const name)
  82. {
  83. CARLA_ASSERT(name != nullptr);
  84. return shm_open(name, O_RDWR | O_CREAT | O_EXCL, 0600);
  85. }
  86. static inline
  87. shm_t carla_shm_attach(const char* const name)
  88. {
  89. CARLA_ASSERT(name != nullptr);
  90. return shm_open(name, O_RDWR, 0);
  91. }
  92. #endif
  93. static inline
  94. void carla_shm_close(shm_t& shm)
  95. {
  96. CARLA_ASSERT(carla_is_shm_valid(shm));
  97. #ifdef CARLA_OS_WIN
  98. CARLA_ASSERT(shm.map == nullptr);
  99. CloseHandle(shm.shm);
  100. shm.shm = nullptr;
  101. #else
  102. close(shm);
  103. shm = -1;
  104. #endif
  105. }
  106. static inline
  107. void* carla_shm_map(shm_t& shm, const size_t size)
  108. {
  109. CARLA_ASSERT(carla_is_shm_valid(shm));
  110. CARLA_ASSERT(size > 0);
  111. #ifdef CARLA_OS_WIN
  112. CARLA_ASSERT(shm.map == nullptr);
  113. HANDLE map = CreateFileMapping(shm.shm, NULL, PAGE_READWRITE, size, size, NULL);
  114. if (map == nullptr)
  115. return nullptr;
  116. HANDLE ptr = MapViewOfFile(map, FILE_MAP_COPY, 0, 0, size);
  117. if (ptr == nullptr)
  118. {
  119. CloseHandle(map);
  120. return nullptr;
  121. }
  122. shm.map = map;
  123. return ptr;
  124. #else
  125. if (ftruncate(shm, size) != 0)
  126. return nullptr;
  127. return mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, shm, 0);
  128. #endif
  129. }
  130. static inline
  131. void carla_shm_unmap(shm_t& shm, void* const ptr, const size_t size)
  132. {
  133. CARLA_ASSERT(carla_is_shm_valid(shm));
  134. CARLA_ASSERT(ptr != nullptr);
  135. CARLA_ASSERT(size > 0);
  136. #ifdef CARLA_OS_WIN
  137. CARLA_ASSERT(shm.map != nullptr);
  138. UnmapViewOfFile(ptr);
  139. CloseHandle(shm.map);
  140. shm.map = nullptr;
  141. return;
  142. // unused
  143. (void)size;
  144. #else
  145. munmap(ptr, size);
  146. return;
  147. // unused
  148. (void)shm;
  149. #endif
  150. }
  151. // -------------------------------------------------
  152. // shared memory, templated calls
  153. template<typename T>
  154. static inline
  155. bool carla_shm_map(shm_t& shm, T*& value)
  156. {
  157. value = (T*)carla_shm_map(shm, sizeof(T));
  158. return (value != nullptr);
  159. }
  160. template<typename T>
  161. static inline
  162. void carla_shm_unmap(shm_t& shm, T*& value)
  163. {
  164. carla_shm_unmap(shm, value, sizeof(T));
  165. value = nullptr;
  166. }
  167. // -------------------------------------------------
  168. #endif // __CARLA_SHM_UTILS_HPP__