jack2 codebase
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.

223 lines
5.8KB

  1. /*
  2. Copyright (C) 2004-2008 Grame
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 2 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  14. */
  15. #include "JackPosixSemaphore.h"
  16. #include "JackConstants.h"
  17. #include "JackError.h"
  18. #include <fcntl.h>
  19. #include <sys/time.h>
  20. namespace Jack
  21. {
  22. void JackPosixSemaphore::BuildName(const char* name, const char* server_name, char* res)
  23. {
  24. sprintf(res, "%s/jack_sem.%s_%s", jack_client_dir, server_name, name);
  25. }
  26. bool JackPosixSemaphore::Signal()
  27. {
  28. int res;
  29. if (!fSemaphore) {
  30. jack_error("JackPosixSemaphore::Signal name = %s already desallocated!!", fName);
  31. return false;
  32. }
  33. if (fFlush)
  34. return true;
  35. if ((res = sem_post(fSemaphore)) != 0) {
  36. jack_error("JackPosixSemaphore::Signal name = %s err = %s", fName, strerror(errno));
  37. }
  38. return (res == 0);
  39. }
  40. bool JackPosixSemaphore::SignalAll()
  41. {
  42. int res;
  43. if (!fSemaphore) {
  44. jack_error("JackPosixSemaphore::SignalAll name = %s already desallocated!!", fName);
  45. return false;
  46. }
  47. if (fFlush)
  48. return true;
  49. if ((res = sem_post(fSemaphore)) != 0) {
  50. jack_error("JackPosixSemaphore::SignalAll name = %s err = %s", fName, strerror(errno));
  51. }
  52. return (res == 0);
  53. }
  54. /*
  55. bool JackPosixSemaphore::Wait()
  56. {
  57. int res;
  58. if (!fSemaphore) {
  59. jack_error("JackPosixSemaphore::Wait name = %s already desallocated!!", fName);
  60. return false;
  61. }
  62. if ((res = sem_wait(fSemaphore)) != 0) {
  63. jack_error("JackPosixSemaphore::Wait name = %s err = %s", fName, strerror(errno));
  64. }
  65. return (res == 0);
  66. }
  67. */
  68. bool JackPosixSemaphore::Wait()
  69. {
  70. int res;
  71. while ((res = sem_wait(fSemaphore) < 0)) {
  72. jack_error("JackPosixSemaphore::Wait name = %s err = %s", fName, strerror(errno));
  73. if (errno != EINTR)
  74. break;
  75. }
  76. return (res == 0);
  77. }
  78. /*
  79. #ifdef __linux__
  80. bool JackPosixSemaphore::TimedWait(long usec) // unusable semantic !!
  81. {
  82. int res;
  83. struct timeval now;
  84. timespec time;
  85. if (!fSemaphore) {
  86. jack_error("JackPosixSemaphore::TimedWait name = %s already desallocated!!", fName);
  87. return false;
  88. }
  89. gettimeofday(&now, 0);
  90. time.tv_sec = now.tv_sec + usec / 1000000;
  91. time.tv_nsec = (now.tv_usec + (usec % 1000000)) * 1000;
  92. if ((res = sem_timedwait(fSemaphore, &time)) != 0) {
  93. jack_error("JackPosixSemaphore::TimedWait err = %s", strerror(errno));
  94. JackLog("now %ld %ld \n", now.tv_sec, now.tv_usec);
  95. JackLog("next %ld %ld \n", time.tv_sec, time.tv_nsec/1000);
  96. }
  97. return (res == 0);
  98. }
  99. #else
  100. #warning "JackPosixSemaphore::TimedWait is not supported: Jack in SYNC mode with JackPosixSemaphore will not run properly !!"
  101. bool JackPosixSemaphore::TimedWait(long usec)
  102. {
  103. return Wait();
  104. }
  105. #endif
  106. */
  107. #warning JackPosixSemaphore::TimedWait not available : synchronous mode may not work correctly if POSIX semaphore are used
  108. bool JackPosixSemaphore::TimedWait(long usec)
  109. {
  110. return Wait();
  111. }
  112. // Server side : publish the semaphore in the global namespace
  113. bool JackPosixSemaphore::Allocate(const char* name, const char* server_name, int value)
  114. {
  115. BuildName(name, server_name, fName);
  116. JackLog("JackPosixSemaphore::Allocate name = %s val = %ld\n", fName, value);
  117. if ((fSemaphore = sem_open(fName, O_CREAT, 0777, value)) == (sem_t*)SEM_FAILED) {
  118. jack_error("Allocate: can't check in named semaphore name = %s err = %s", fName, strerror(errno));
  119. return false;
  120. } else {
  121. return true;
  122. }
  123. }
  124. // Client side : get the published semaphore from server
  125. bool JackPosixSemaphore::ConnectInput(const char* name, const char* server_name)
  126. {
  127. BuildName(name, server_name, fName);
  128. JackLog("JackPosixSemaphore::Connect %s\n", fName);
  129. // Temporary...
  130. if (fSemaphore) {
  131. JackLog("Already connected name = %s\n", name);
  132. return true;
  133. }
  134. if ((fSemaphore = sem_open(fName, O_CREAT)) == (sem_t*)SEM_FAILED) {
  135. jack_error("Connect: can't connect named semaphore name = %s err = %s", fName, strerror(errno));
  136. return false;
  137. } else {
  138. int val = 0;
  139. sem_getvalue(fSemaphore, &val);
  140. JackLog("JackPosixSemaphore::Connect sem_getvalue %ld\n", val);
  141. return true;
  142. }
  143. }
  144. bool JackPosixSemaphore::Connect(const char* name, const char* server_name)
  145. {
  146. return ConnectInput(name, server_name);
  147. }
  148. bool JackPosixSemaphore::ConnectOutput(const char* name, const char* server_name)
  149. {
  150. return ConnectInput(name, server_name);
  151. }
  152. bool JackPosixSemaphore::Disconnect()
  153. {
  154. JackLog("JackPosixSemaphore::Disconnect %s\n", fName);
  155. if (fSemaphore) {
  156. if (sem_close(fSemaphore) != 0) {
  157. jack_error("Disconnect: can't disconnect named semaphore name = %s err = %s", fName, strerror(errno));
  158. return false;
  159. } else {
  160. fSemaphore = NULL;
  161. return true;
  162. }
  163. } else {
  164. return true;
  165. }
  166. }
  167. // Server side : destroy the semaphore
  168. void JackPosixSemaphore::Destroy()
  169. {
  170. if (fSemaphore != NULL) {
  171. JackLog("JackPosixSemaphore::Destroy\n");
  172. sem_unlink(fName);
  173. if (sem_close(fSemaphore) != 0) {
  174. jack_error("Destroy: can't destroy semaphore name = %s err = %s", fName, strerror(errno));
  175. }
  176. fSemaphore = NULL;
  177. } else {
  178. jack_error("JackPosixSemaphore::Destroy semaphore == NULL");
  179. }
  180. }
  181. } // end of namespace