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.

209 lines
5.5KB

  1. /*
  2. Copyright (C) 2004-2005 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 "JackPthreadCond.h"
  16. #include "JackConstants.h"
  17. #include "JackError.h"
  18. namespace Jack
  19. {
  20. JackPthreadCondArray* JackPthreadCondServer::fTable = NULL;
  21. long JackPthreadCondServer::fCount = 0;
  22. JackShmReadWritePtr1<JackPthreadCondArray> JackPthreadCondClient::fTable;
  23. long JackPthreadCondClient::fCount = 0;
  24. JackPthreadCondArray::JackPthreadCondArray()
  25. {
  26. for (int i = 0; i < MAX_ITEM; i++) {
  27. strcpy(fTable[i].fName, "");
  28. }
  29. }
  30. void JackPthreadCond::BuildName(const char* name, char* res)
  31. {
  32. sprintf(res, "%s/jack_sem.%s", jack_client_dir, name);
  33. }
  34. bool JackPthreadCond::Signal()
  35. {
  36. //pthread_mutex_lock(&fSynchro->fLock);
  37. //JackLog("JackPthreadCond::Signal...\n");
  38. pthread_cond_signal(&fSynchro->fCond);
  39. //pthread_mutex_unlock(&fSynchro->fLock);
  40. return true;
  41. }
  42. bool JackPthreadCond::SignalAll()
  43. {
  44. pthread_cond_broadcast(&fSynchro->fCond);
  45. return true;
  46. }
  47. bool JackPthreadCond::Wait()
  48. {
  49. pthread_mutex_lock(&fSynchro->fLock);
  50. //JackLog("JackPthreadCond::Wait...\n");
  51. pthread_cond_wait(&fSynchro->fCond, &fSynchro->fLock);
  52. pthread_mutex_unlock(&fSynchro->fLock);
  53. //JackLog("JackProcessSync::Wait finished\n");
  54. return true;
  55. }
  56. bool JackPthreadCond::TimedWait(long usec)
  57. {
  58. timespec time;
  59. struct timeval now;
  60. gettimeofday(&now, 0);
  61. time.tv_sec = now.tv_sec + usec / 1000000;
  62. time.tv_nsec = (now.tv_usec + (usec % 1000000)) * 1000;
  63. pthread_mutex_lock(&fSynchro->fLock);
  64. JackLog("JackProcessSync::Wait...\n");
  65. pthread_cond_timedwait(&fSynchro->fCond, &fSynchro->fLock, &time);
  66. pthread_mutex_unlock(&fSynchro->fLock);
  67. JackLog("JackProcessSync::Wait finished\n");
  68. return true;
  69. }
  70. // Client side : get the published semaphore from server
  71. bool JackPthreadCond::ConnectInput(const char* name)
  72. {
  73. BuildName(name, fName);
  74. JackLog("JackPthreadCond::Connect %s\n", fName);
  75. // Temporary...
  76. if (fSynchro) {
  77. JackLog("Already connected name = %s\n", name);
  78. return true;
  79. }
  80. for (int i = 0; i < MAX_ITEM; i++) {
  81. JackPthreadCondItem* synchro = &(GetTable()->fTable[i]);
  82. if (strcmp(fName, synchro->fName) == 0) {
  83. fSynchro = synchro;
  84. return true;
  85. }
  86. }
  87. return false;
  88. }
  89. bool JackPthreadCond::Connect(const char* name)
  90. {
  91. return ConnectInput(name);
  92. }
  93. bool JackPthreadCond::ConnectOutput(const char* name)
  94. {
  95. return ConnectInput(name);
  96. }
  97. bool JackPthreadCond::Disconnect()
  98. {
  99. JackLog("JackPthreadCond::Disconnect %s\n", fName);
  100. if (fSynchro) {
  101. strcpy(fSynchro->fName, "");
  102. fSynchro = NULL;
  103. return true;
  104. } else {
  105. return false;
  106. }
  107. }
  108. JackPthreadCondServer::JackPthreadCondServer(): JackPthreadCond()
  109. {
  110. if (fCount++ == 0 && !fTable) {
  111. fTable = new JackPthreadCondArray();
  112. }
  113. if (fCount == MAX_ITEM)
  114. throw new std::bad_alloc;
  115. }
  116. JackPthreadCondServer::~JackPthreadCondServer()
  117. {
  118. if (--fCount == 0 && fTable) {
  119. delete fTable;
  120. fTable = NULL;
  121. }
  122. }
  123. bool JackPthreadCondServer::Allocate(const char* name, int value)
  124. {
  125. BuildName(name, fName);
  126. JackLog("JackPthreadCond::Allocate name = %s val = %ld\n", fName, value);
  127. pthread_mutexattr_t mutex_attr;
  128. pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
  129. pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_NORMAL);
  130. pthread_condattr_t cond_attr;
  131. pthread_condattr_init(&cond_attr);
  132. pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
  133. for (int i = 0; i < MAX_ITEM; i++) {
  134. if (strcmp(fTable->fTable[i].fName, "") == 0) { // first empty place
  135. fSynchro = &fTable->fTable[i];
  136. if (pthread_mutex_init(&fSynchro->fLock, &mutex_attr) != 0) {
  137. jack_error("Allocate: can't check in named semaphore name = %s err = %s", fName, strerror(errno));
  138. return false;
  139. }
  140. if (pthread_cond_init(&fSynchro->fCond, &cond_attr) != 0) {
  141. jack_error("Allocate: can't check in named semaphore name = %s err = %s", fName, strerror(errno));
  142. return false;
  143. }
  144. strcpy(fSynchro->fName, fName);
  145. return true;
  146. }
  147. }
  148. return false;
  149. }
  150. void JackPthreadCondServer::Destroy()
  151. {
  152. if (fSynchro != NULL) {
  153. pthread_mutex_destroy(&fSynchro->fLock);
  154. pthread_cond_destroy(&fSynchro->fCond);
  155. strcpy(fSynchro->fName, "");
  156. fSynchro = NULL;
  157. } else {
  158. jack_error("JackPthreadCond::Destroy semaphore == NULL");
  159. }
  160. }
  161. JackPthreadCondClient::JackPthreadCondClient(int shared_index): JackPthreadCond()
  162. {
  163. if (fCount++ == 0 && !fTable) {
  164. fTable = shared_index;
  165. }
  166. if (fCount == MAX_ITEM)
  167. throw new std::bad_alloc;
  168. }
  169. JackPthreadCondClient::~JackPthreadCondClient()
  170. {
  171. if (--fCount == 0 && fTable)
  172. delete fTable;
  173. }
  174. } // end of namespace