00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackPthreadCond.h"
00021 #include "JackError.h"
00022
00023 namespace Jack
00024 {
00025
00026 JackPthreadCondArray* JackPthreadCondServer::fTable = NULL;
00027 long JackPthreadCondServer::fCount = 0;
00028
00029 JackShmReadWritePtr1<JackPthreadCondArray> JackPthreadCondClient::fTable;
00030 long JackPthreadCondClient::fCount = 0;
00031
00032 JackPthreadCondArray::JackPthreadCondArray()
00033 {
00034 for (int i = 0; i < MAX_ITEM; i++) {
00035 strcpy(fTable[i].fName, "");
00036 }
00037 }
00038
00039 void JackPthreadCond::BuildName(const char* name, char* res)
00040 {
00041 sprintf(res, "%s/jack_sem.%s", jack_client_dir, name);
00042 }
00043
00044 bool JackPthreadCond::Signal()
00045 {
00046
00047
00048 pthread_cond_signal(&fSynchro->fCond);
00049
00050 return true;
00051 }
00052
00053 bool JackPthreadCond::SignalAll()
00054 {
00055 pthread_cond_broadcast(&fSynchro->fCond);
00056 return true;
00057 }
00058
00059 bool JackPthreadCond::Wait()
00060 {
00061 pthread_mutex_lock(&fSynchro->fLock);
00062
00063 pthread_cond_wait(&fSynchro->fCond, &fSynchro->fLock);
00064 pthread_mutex_unlock(&fSynchro->fLock);
00065
00066 return true;
00067 }
00068
00069 bool JackPthreadCond::TimedWait(long usec)
00070 {
00071 timespec time;
00072 struct timeval now;
00073 gettimeofday(&now, 0);
00074 time.tv_sec = now.tv_sec + usec / 1000000;
00075 time.tv_nsec = (now.tv_usec + (usec % 1000000)) * 1000;
00076 pthread_mutex_lock(&fSynchro->fLock);
00077 JackLog("JackProcessSync::Wait...\n");
00078 pthread_cond_timedwait(&fSynchro->fCond, &fSynchro->fLock, &time);
00079 pthread_mutex_unlock(&fSynchro->fLock);
00080 JackLog("JackProcessSync::Wait finished\n");
00081 return true;
00082 }
00083
00084
00085 bool JackPthreadCond::ConnectInput(const char* name)
00086 {
00087 BuildName(name, fName);
00088 JackLog("JackPthreadCond::Connect %s\n", fName);
00089
00090
00091 if (fSynchro) {
00092 JackLog("Already connected name = %s\n", name);
00093 return true;
00094 }
00095
00096 for (int i = 0; i < MAX_ITEM; i++) {
00097 JackPthreadCondItem* synchro = &(GetTable()->fTable[i]);
00098 if (strcmp(fName, synchro->fName) == 0) {
00099 fSynchro = synchro;
00100 return true;
00101 }
00102 }
00103
00104 return false;
00105 }
00106
00107 bool JackPthreadCond::Connect(const char* name)
00108 {
00109 return ConnectInput(name);
00110 }
00111
00112 bool JackPthreadCond::ConnectOutput(const char* name)
00113 {
00114 return ConnectInput(name);
00115 }
00116
00117 bool JackPthreadCond::Disconnect()
00118 {
00119 JackLog("JackPthreadCond::Disconnect %s\n", fName);
00120
00121 if (fSynchro) {
00122 strcpy(fSynchro->fName, "");
00123 fSynchro = NULL;
00124 return true;
00125 } else {
00126 return false;
00127 }
00128 }
00129
00130 JackPthreadCondServer::JackPthreadCondServer(): JackPthreadCond()
00131 {
00132 if (fCount++ == 0 && !fTable) {
00133 fTable = new JackPthreadCondArray();
00134 }
00135 if (fCount == MAX_ITEM)
00136 throw new std::bad_alloc;
00137 }
00138
00139 JackPthreadCondServer::~JackPthreadCondServer()
00140 {
00141 if (--fCount == 0 && fTable) {
00142 delete fTable;
00143 fTable = NULL;
00144 }
00145 }
00146
00147 bool JackPthreadCondServer::Allocate(const char* name, int value)
00148 {
00149 BuildName(name, fName);
00150 JackLog("JackPthreadCond::Allocate name = %s val = %ld\n", fName, value);
00151
00152 pthread_mutexattr_t mutex_attr;
00153 pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
00154 pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_NORMAL);
00155
00156 pthread_condattr_t cond_attr;
00157 pthread_condattr_init(&cond_attr);
00158 pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
00159
00160 for (int i = 0; i < MAX_ITEM; i++) {
00161 if (strcmp(fTable->fTable[i].fName, "") == 0) {
00162 fSynchro = &fTable->fTable[i];
00163 if (pthread_mutex_init(&fSynchro->fLock, &mutex_attr) != 0) {
00164 jack_error("Allocate: can't check in named semaphore name = %s err = %s", fName, strerror(errno));
00165 return false;
00166 }
00167 if (pthread_cond_init(&fSynchro->fCond, &cond_attr) != 0) {
00168 jack_error("Allocate: can't check in named semaphore name = %s err = %s", fName, strerror(errno));
00169 return false;
00170 }
00171 strcpy(fSynchro->fName, fName);
00172 return true;
00173 }
00174 }
00175
00176 return false;
00177 }
00178
00179 void JackPthreadCondServer::Destroy()
00180 {
00181 if (fSynchro != NULL) {
00182 pthread_mutex_destroy(&fSynchro->fLock);
00183 pthread_cond_destroy(&fSynchro->fCond);
00184 strcpy(fSynchro->fName, "");
00185 fSynchro = NULL;
00186 } else {
00187 jack_error("JackPthreadCond::Destroy semaphore == NULL");
00188 }
00189 }
00190
00191 JackPthreadCondClient::JackPthreadCondClient(int shared_index): JackPthreadCond()
00192 {
00193 if (fCount++ == 0 && !fTable) {
00194 fTable = shared_index;
00195 }
00196 if (fCount == MAX_ITEM)
00197 throw new std::bad_alloc;
00198 }
00199
00200 JackPthreadCondClient::~JackPthreadCondClient()
00201 {
00202 if (--fCount == 0 && fTable)
00203 delete fTable;
00204 }
00205
00206 }
00207