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.

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