JackPosixSemaphore.cpp

00001 /*
00002 Copyright (C) 2004-2006 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 "JackPosixSemaphore.h"
00021 #include "JackChannel.h"
00022 #include "JackError.h"
00023 #include <fcntl.h>
00024 #include <sys/time.h>
00025 
00026 namespace Jack
00027 {
00028 
00029 void JackPosixSemaphore::BuildName(const char* name, char* res)
00030 {
00031     sprintf(res, "%s/jack_sem.%s", jack_client_dir, name);
00032 }
00033 
00034 bool JackPosixSemaphore::Signal()
00035 {
00036     int res;
00037     assert(fSemaphore);
00038 
00039     if (fFlush)
00040         return true;
00041 
00042     if ((res = sem_post(fSemaphore)) != 0) {
00043         jack_error("JackPosixSemaphore::Signal name = %s err = %s", fName, strerror(errno));
00044     }
00045     return (res == 0);
00046 }
00047 
00048 bool JackPosixSemaphore::SignalAll()
00049 {
00050     int res;
00051     assert(fSemaphore);
00052 
00053     if (fFlush)
00054         return true;
00055 
00056     if ((res = sem_post(fSemaphore)) != 0) {
00057         jack_error("JackPosixSemaphore::SignalAll name = %s err = %s", fName, strerror(errno));
00058     }
00059     return (res == 0);
00060 }
00061 
00062 /*
00063 bool JackPosixSemaphore::Wait()
00064 {
00065     int res;
00066         assert(fSemaphore);
00067     if ((res = sem_wait(fSemaphore)) != 0) {
00068         jack_error("JackPosixSemaphore::Wait name = %s err = %s", fName, strerror(errno));
00069     }
00070     return (res == 0);
00071 }
00072 */
00073 
00074 bool JackPosixSemaphore::Wait()
00075 {
00076     int res;
00077 
00078     while ((res = sem_wait(fSemaphore) < 0)) {
00079         jack_error("JackPosixSemaphore::Wait name = %s err = %s", fName, strerror(errno));
00080         if (errno != EINTR)
00081             break;
00082     }
00083     return (res == 0);
00084 }
00085 
00086 
00087 /*
00088 #ifdef __linux__
00089  
00090 bool JackPosixSemaphore::TimedWait(long usec) // unusable semantic !!
00091 {
00092         int res;
00093         struct timeval now;
00094         timespec time;
00095         assert(fSemaphore);
00096         gettimeofday(&now, 0);
00097         time.tv_sec = now.tv_sec + usec / 1000000;
00098         time.tv_nsec = (now.tv_usec + (usec % 1000000)) * 1000;
00099         
00100     if ((res = sem_timedwait(fSemaphore, &time)) != 0) {
00101         jack_error("JackPosixSemaphore::TimedWait err = %s", strerror(errno));
00102                 JackLog("now %ld %ld \n", now.tv_sec, now.tv_usec);
00103                 JackLog("next %ld %ld \n", time.tv_sec, time.tv_nsec/1000);
00104         }
00105     return (res == 0);
00106 }
00107  
00108 #else 
00109 #warning "JackPosixSemaphore::TimedWait is not supported: Jack in SYNC mode with JackPosixSemaphore will not run properly !!"
00110  
00111 bool JackPosixSemaphore::TimedWait(long usec)
00112 {
00113         return Wait();
00114 }
00115 #endif 
00116 */
00117 
00118 #warning JackPosixSemaphore::TimedWait not available : synchronous mode may not work correctly if POSIX semaphore are used
00119 
00120 bool JackPosixSemaphore::TimedWait(long usec)
00121 {
00122     return Wait();
00123 }
00124 
00125 // Server side : publish the semaphore in the global namespace
00126 bool JackPosixSemaphore::Allocate(const char* name, int value)
00127 {
00128     BuildName(name, fName);
00129     JackLog("JackPosixSemaphore::Allocate name = %s val = %ld\n", fName, value);
00130 
00131     if ((fSemaphore = sem_open(fName, O_CREAT, 0777, value)) == (sem_t*)SEM_FAILED) {
00132         jack_error("Allocate: can't check in named semaphore name = %s err = %s", fName, strerror(errno));
00133         return false;
00134     } else {
00135         return true;
00136     }
00137 }
00138 
00139 // Client side : get the published semaphore from server
00140 bool JackPosixSemaphore::ConnectInput(const char* name)
00141 {
00142     BuildName(name, fName);
00143     JackLog("JackPosixSemaphore::Connect %s\n", fName);
00144 
00145     // Temporary...
00146     if (fSemaphore) {
00147         JackLog("Already connected name = %s\n", name);
00148         return true;
00149     }
00150 
00151     if ((fSemaphore = sem_open(fName, O_CREAT)) == (sem_t*)SEM_FAILED) {
00152         jack_error("Connect: can't connect named semaphore name = %s err = %s", fName, strerror(errno));
00153         return false;
00154     } else {
00155         int val = 0;
00156         sem_getvalue(fSemaphore, &val);
00157         JackLog("JackPosixSemaphore::Connect sem_getvalue %ld\n", val);
00158         return true;
00159     }
00160 }
00161 
00162 bool JackPosixSemaphore::Connect(const char* name)
00163 {
00164     return ConnectInput(name);
00165 }
00166 
00167 bool JackPosixSemaphore::ConnectOutput(const char* name)
00168 {
00169     return ConnectInput(name);
00170 }
00171 
00172 bool JackPosixSemaphore::Disconnect()
00173 {
00174     JackLog("JackPosixSemaphore::Disconnect %s\n", fName);
00175 
00176     if (fSemaphore) {
00177         if (sem_close(fSemaphore) != 0) {
00178             jack_error("Disconnect: can't disconnect named semaphore name = %s err = %s", fName, strerror(errno));
00179             return false;
00180         } else {
00181             fSemaphore = NULL;
00182             return true;
00183         }
00184     } else {
00185         return true;
00186     }
00187 }
00188 
00189 // Server side : destroy the semaphore
00190 void JackPosixSemaphore::Destroy()
00191 {
00192     if (fSemaphore != NULL) {
00193         JackLog("JackPosixSemaphore::Destroy\n");
00194         sem_unlink(fName);
00195         if (sem_close(fSemaphore) != 0) {
00196             jack_error("Destroy: can't destroy semaphore name = %s err = %s", fName, strerror(errno));
00197         }
00198         fSemaphore = NULL;
00199     } else {
00200         jack_error("JackPosixSemaphore::Destroy semaphore == NULL");
00201     }
00202 }
00203 
00204 } // end of namespace
00205 

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