JackPthreadCond.cpp

00001 /*
00002 Copyright (C) 2004-2005 Grame  
00003 
00004 This program is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008 
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details.
00013 
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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     //pthread_mutex_lock(&fSynchro->fLock);
00047     //JackLog("JackPthreadCond::Signal...\n");
00048     pthread_cond_signal(&fSynchro->fCond);
00049     //pthread_mutex_unlock(&fSynchro->fLock);
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     //JackLog("JackPthreadCond::Wait...\n");
00063     pthread_cond_wait(&fSynchro->fCond, &fSynchro->fLock);
00064     pthread_mutex_unlock(&fSynchro->fLock);
00065     //JackLog("JackProcessSync::Wait finished\n");
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 // Client side : get the published semaphore from server
00085 bool JackPthreadCond::ConnectInput(const char* name)
00086 {
00087     BuildName(name, fName);
00088     JackLog("JackPthreadCond::Connect %s\n", fName);
00089 
00090     // Temporary...
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) { // first empty place
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 } // end of namespace
00207 

Generated on Wed Jan 10 11:42:46 2007 for Jackdmp by  doxygen 1.4.5