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.4KB

11 years ago
11 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. /*
  2. * Carla shared memory utils
  3. * Copyright (C) 2013-2014 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_SHM_UTILS_HPP_INCLUDED
  18. #define CARLA_SHM_UTILS_HPP_INCLUDED
  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. #ifdef CARLA_OS_WIN
  28. static shm_t gNullCarlaShm = { nullptr, nullptr };
  29. #else
  30. static shm_t gNullCarlaShm = -1;
  31. #endif
  32. // -----------------------------------------------------------------------
  33. // shared memory calls
  34. static inline
  35. bool carla_is_shm_valid(const shm_t& shm) noexcept
  36. {
  37. #ifdef CARLA_OS_WIN
  38. return (shm.shm != nullptr && shm.shm != INVALID_HANDLE_VALUE);
  39. #else
  40. return (shm >= 0);
  41. #endif
  42. }
  43. static inline
  44. void carla_shm_init(shm_t& shm) noexcept
  45. {
  46. #ifdef CARLA_OS_WIN
  47. shm.shm = nullptr;
  48. shm.map = nullptr;
  49. #else
  50. shm = -1;
  51. #endif
  52. }
  53. #ifdef CARLA_OS_WIN
  54. static inline
  55. shm_t carla_shm_create(const char* const name)
  56. {
  57. CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', gNullCarlaShm);
  58. shm_t ret;
  59. ret.shm = nullptr; // TODO
  60. ret.map = nullptr;
  61. return ret;
  62. }
  63. static inline
  64. shm_t carla_shm_attach(const char* const name)
  65. {
  66. CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', gNullCarlaShm);
  67. shm_t ret;
  68. ret.shm = CreateFileA(name, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
  69. ret.map = nullptr;
  70. return ret;
  71. }
  72. #else
  73. static inline
  74. shm_t carla_shm_create(const char* const name)
  75. {
  76. CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', gNullCarlaShm);
  77. return shm_open(name, O_RDWR|O_CREAT|O_EXCL, 0600);
  78. }
  79. static inline
  80. shm_t carla_shm_attach(const char* const name)
  81. {
  82. CARLA_SAFE_ASSERT_RETURN(name != nullptr && name[0] != '\0', gNullCarlaShm);
  83. return shm_open(name, O_RDWR, 0);
  84. }
  85. #endif
  86. static inline
  87. void carla_shm_close(shm_t& shm)
  88. {
  89. CARLA_SAFE_ASSERT_RETURN(carla_is_shm_valid(shm),);
  90. #ifdef CARLA_OS_WIN
  91. CARLA_SAFE_ASSERT(shm.map == nullptr);
  92. CloseHandle(shm.shm);
  93. shm.shm = nullptr;
  94. #else
  95. close(shm);
  96. shm = -1;
  97. #endif
  98. }
  99. static inline
  100. void* carla_shm_map(shm_t& shm, const size_t size)
  101. {
  102. CARLA_SAFE_ASSERT_RETURN(carla_is_shm_valid(shm), nullptr);
  103. CARLA_SAFE_ASSERT_RETURN(size > 0, nullptr);
  104. #ifdef CARLA_OS_WIN
  105. CARLA_SAFE_ASSERT_RETURN(shm.map == nullptr, nullptr);
  106. HANDLE map = CreateFileMapping(shm.shm, NULL, PAGE_READWRITE, size, size, NULL);
  107. CARLA_SAFE_ASSERT_RETURN(map != nullptr, nullptr);
  108. HANDLE ptr = MapViewOfFile(map, FILE_MAP_COPY, 0, 0, size);
  109. if (ptr == nullptr)
  110. {
  111. CloseHandle(map);
  112. return nullptr;
  113. }
  114. shm.map = map;
  115. return ptr;
  116. #else
  117. if (ftruncate(shm, static_cast<off_t>(size)) != 0)
  118. return nullptr;
  119. return mmap(nullptr, size, PROT_READ|PROT_WRITE, MAP_SHARED, shm, 0);
  120. #endif
  121. }
  122. static inline
  123. void carla_shm_unmap(shm_t& shm, void* const ptr, const size_t size)
  124. {
  125. CARLA_SAFE_ASSERT_RETURN(carla_is_shm_valid(shm),);
  126. CARLA_SAFE_ASSERT_RETURN(ptr != nullptr,);
  127. CARLA_SAFE_ASSERT_RETURN(size > 0,);
  128. #ifdef CARLA_OS_WIN
  129. CARLA_SAFE_ASSERT_RETURN(shm.map != nullptr,);
  130. UnmapViewOfFile(ptr);
  131. CloseHandle(shm.map);
  132. shm.map = nullptr;
  133. return;
  134. // unused
  135. (void)size;
  136. #else
  137. munmap(ptr, size);
  138. return;
  139. // unused
  140. (void)shm;
  141. #endif
  142. }
  143. // -----------------------------------------------------------------------
  144. // shared memory, templated calls
  145. template<typename T>
  146. static inline
  147. bool carla_shm_map(shm_t& shm, T*& value)
  148. {
  149. value = (T*)carla_shm_map(shm, sizeof(T));
  150. return (value != nullptr);
  151. }
  152. template<typename T>
  153. static inline
  154. void carla_shm_unmap(shm_t& shm, T*& value)
  155. {
  156. carla_shm_unmap(shm, value, sizeof(T));
  157. value = nullptr;
  158. }
  159. // -----------------------------------------------------------------------
  160. #endif // CARLA_SHM_UTILS_HPP_INCLUDED