|
- /*
- Copyright (C) 2004-2005 Grame
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- */
-
- #include "JackPthreadCond.h"
- #include "JackError.h"
-
- namespace Jack
- {
-
- JackPthreadCondArray* JackPthreadCondServer::fTable = NULL;
- long JackPthreadCondServer::fCount = 0;
-
- JackShmReadWritePtr1<JackPthreadCondArray> JackPthreadCondClient::fTable;
- long JackPthreadCondClient::fCount = 0;
-
- JackPthreadCondArray::JackPthreadCondArray()
- {
- for (int i = 0; i < MAX_ITEM; i++) {
- strcpy(fTable[i].fName, "");
- }
- }
-
- void JackPthreadCond::BuildName(const char* name, char* res)
- {
- sprintf(res, "%s/jack_sem.%s", jack_client_dir, name);
- }
-
- bool JackPthreadCond::Signal()
- {
- //pthread_mutex_lock(&fSynchro->fLock);
- //JackLog("JackPthreadCond::Signal...\n");
- pthread_cond_signal(&fSynchro->fCond);
- //pthread_mutex_unlock(&fSynchro->fLock);
- return true;
- }
-
- bool JackPthreadCond::SignalAll()
- {
- pthread_cond_broadcast(&fSynchro->fCond);
- return true;
- }
-
- bool JackPthreadCond::Wait()
- {
- pthread_mutex_lock(&fSynchro->fLock);
- //JackLog("JackPthreadCond::Wait...\n");
- pthread_cond_wait(&fSynchro->fCond, &fSynchro->fLock);
- pthread_mutex_unlock(&fSynchro->fLock);
- //JackLog("JackProcessSync::Wait finished\n");
- return true;
- }
-
- bool JackPthreadCond::TimedWait(long usec)
- {
- timespec time;
- struct timeval now;
- gettimeofday(&now, 0);
- time.tv_sec = now.tv_sec + usec / 1000000;
- time.tv_nsec = (now.tv_usec + (usec % 1000000)) * 1000;
- pthread_mutex_lock(&fSynchro->fLock);
- JackLog("JackProcessSync::Wait...\n");
- pthread_cond_timedwait(&fSynchro->fCond, &fSynchro->fLock, &time);
- pthread_mutex_unlock(&fSynchro->fLock);
- JackLog("JackProcessSync::Wait finished\n");
- return true;
- }
-
- // Client side : get the published semaphore from server
- bool JackPthreadCond::ConnectInput(const char* name)
- {
- BuildName(name, fName);
- JackLog("JackPthreadCond::Connect %s\n", fName);
-
- // Temporary...
- if (fSynchro) {
- JackLog("Already connected name = %s\n", name);
- return true;
- }
-
- for (int i = 0; i < MAX_ITEM; i++) {
- JackPthreadCondItem* synchro = &(GetTable()->fTable[i]);
- if (strcmp(fName, synchro->fName) == 0) {
- fSynchro = synchro;
- return true;
- }
- }
-
- return false;
- }
-
- bool JackPthreadCond::Connect(const char* name)
- {
- return ConnectInput(name);
- }
-
- bool JackPthreadCond::ConnectOutput(const char* name)
- {
- return ConnectInput(name);
- }
-
- bool JackPthreadCond::Disconnect()
- {
- JackLog("JackPthreadCond::Disconnect %s\n", fName);
-
- if (fSynchro) {
- strcpy(fSynchro->fName, "");
- fSynchro = NULL;
- return true;
- } else {
- return false;
- }
- }
-
- JackPthreadCondServer::JackPthreadCondServer(): JackPthreadCond()
- {
- if (fCount++ == 0 && !fTable) {
- fTable = new JackPthreadCondArray();
- }
- if (fCount == MAX_ITEM)
- throw new std::bad_alloc;
- }
-
- JackPthreadCondServer::~JackPthreadCondServer()
- {
- if (--fCount == 0 && fTable) {
- delete fTable;
- fTable = NULL;
- }
- }
-
- bool JackPthreadCondServer::Allocate(const char* name, int value)
- {
- BuildName(name, fName);
- JackLog("JackPthreadCond::Allocate name = %s val = %ld\n", fName, value);
-
- pthread_mutexattr_t mutex_attr;
- pthread_mutexattr_setpshared(&mutex_attr, PTHREAD_PROCESS_SHARED);
- pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_NORMAL);
-
- pthread_condattr_t cond_attr;
- pthread_condattr_init(&cond_attr);
- pthread_condattr_setpshared(&cond_attr, PTHREAD_PROCESS_SHARED);
-
- for (int i = 0; i < MAX_ITEM; i++) {
- if (strcmp(fTable->fTable[i].fName, "") == 0) { // first empty place
- fSynchro = &fTable->fTable[i];
- if (pthread_mutex_init(&fSynchro->fLock, &mutex_attr) != 0) {
- jack_error("Allocate: can't check in named semaphore name = %s err = %s", fName, strerror(errno));
- return false;
- }
- if (pthread_cond_init(&fSynchro->fCond, &cond_attr) != 0) {
- jack_error("Allocate: can't check in named semaphore name = %s err = %s", fName, strerror(errno));
- return false;
- }
- strcpy(fSynchro->fName, fName);
- return true;
- }
- }
-
- return false;
- }
-
- void JackPthreadCondServer::Destroy()
- {
- if (fSynchro != NULL) {
- pthread_mutex_destroy(&fSynchro->fLock);
- pthread_cond_destroy(&fSynchro->fCond);
- strcpy(fSynchro->fName, "");
- fSynchro = NULL;
- } else {
- jack_error("JackPthreadCond::Destroy semaphore == NULL");
- }
- }
-
- JackPthreadCondClient::JackPthreadCondClient(int shared_index): JackPthreadCond()
- {
- if (fCount++ == 0 && !fTable) {
- fTable = shared_index;
- }
- if (fCount == MAX_ITEM)
- throw new std::bad_alloc;
- }
-
- JackPthreadCondClient::~JackPthreadCondClient()
- {
- if (--fCount == 0 && fTable)
- delete fTable;
- }
-
- } // end of namespace
|