JackPosixSemaphore.cpp

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

Generated on Thu Feb 14 11:16:02 2008 for Jackdmp by  doxygen 1.5.1