00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackPosixSemaphore.h"
00021 #include "JackTools.h"
00022 #include "JackConstants.h"
00023 #include "JackError.h"
00024 #include <fcntl.h>
00025 #include <stdio.h>
00026 #include <sys/time.h>
00027
00028 namespace Jack
00029 {
00030
00031 void JackPosixSemaphore::BuildName(const char* name, const char* server_name, char* res)
00032 {
00033 sprintf(res, "jack_sem.%d_%s_%s", JackTools::GetUID(), server_name, name);
00034 }
00035
00036 bool JackPosixSemaphore::Signal()
00037 {
00038 int res;
00039
00040 if (!fSemaphore) {
00041 jack_error("JackPosixSemaphore::Signal name = %s already desallocated!!", fName);
00042 return false;
00043 }
00044
00045 if (fFlush)
00046 return true;
00047
00048 if ((res = sem_post(fSemaphore)) != 0) {
00049 jack_error("JackPosixSemaphore::Signal name = %s err = %s", fName, strerror(errno));
00050 }
00051 return (res == 0);
00052 }
00053
00054 bool JackPosixSemaphore::SignalAll()
00055 {
00056 int res;
00057
00058 if (!fSemaphore) {
00059 jack_error("JackPosixSemaphore::SignalAll name = %s already desallocated!!", fName);
00060 return false;
00061 }
00062
00063 if (fFlush)
00064 return true;
00065
00066 if ((res = sem_post(fSemaphore)) != 0) {
00067 jack_error("JackPosixSemaphore::SignalAll name = %s err = %s", fName, strerror(errno));
00068 }
00069 return (res == 0);
00070 }
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089 bool JackPosixSemaphore::Wait()
00090 {
00091 int res;
00092
00093 while ((res = sem_wait(fSemaphore) < 0)) {
00094 jack_error("JackPosixSemaphore::Wait name = %s err = %s", fName, strerror(errno));
00095 if (errno != EINTR)
00096 break;
00097 }
00098 return (res == 0);
00099 }
00100
00101 #if (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) // glibc feature test
00102
00103 bool JackPosixSemaphore::TimedWait(long usec)
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 long tv_usec = (now.tv_usec + (usec % 1000000));
00116 time.tv_sec += tv_usec / 1000000;
00117 time.tv_nsec = (tv_usec % 1000000) * 1000;
00118
00119 if ((res = sem_timedwait(fSemaphore, &time)) != 0) {
00120 jack_error("JackPosixSemaphore::TimedWait err = %s", strerror(errno));
00121 jack_log("now %ld %ld ", now.tv_sec, now.tv_usec);
00122 jack_log("next %ld %ld ", time.tv_sec, time.tv_nsec/1000);
00123 }
00124 return (res == 0);
00125 }
00126
00127 #else
00128 #warning "JackPosixSemaphore::TimedWait is not supported: Jack in SYNC mode with JackPosixSemaphore will not run properly !!"
00129
00130 bool JackPosixSemaphore::TimedWait(long usec)
00131 {
00132 return Wait();
00133 }
00134 #endif
00135
00136
00137 bool JackPosixSemaphore::Allocate(const char* name, const char* server_name, int value)
00138 {
00139 BuildName(name, server_name, fName);
00140 jack_log("JackPosixSemaphore::Allocate name = %s val = %ld", fName, value);
00141
00142 if ((fSemaphore = sem_open(fName, O_CREAT, 0777, value)) == (sem_t*)SEM_FAILED) {
00143 jack_error("Allocate: can't check in named semaphore name = %s err = %s", fName, strerror(errno));
00144 return false;
00145 } else {
00146 return true;
00147 }
00148 }
00149
00150
00151 bool JackPosixSemaphore::ConnectInput(const char* name, const char* server_name)
00152 {
00153 BuildName(name, server_name, fName);
00154 jack_log("JackPosixSemaphore::Connect %s", fName);
00155
00156
00157 if (fSemaphore) {
00158 jack_log("Already connected name = %s", name);
00159 return true;
00160 }
00161
00162 if ((fSemaphore = sem_open(fName, O_CREAT)) == (sem_t*)SEM_FAILED) {
00163 jack_error("Connect: can't connect named semaphore name = %s err = %s", fName, strerror(errno));
00164 return false;
00165 } else {
00166 int val = 0;
00167 sem_getvalue(fSemaphore, &val);
00168 jack_log("JackPosixSemaphore::Connect sem_getvalue %ld", val);
00169 return true;
00170 }
00171 }
00172
00173 bool JackPosixSemaphore::Connect(const char* name, const char* server_name)
00174 {
00175 return ConnectInput(name, server_name);
00176 }
00177
00178 bool JackPosixSemaphore::ConnectOutput(const char* name, const char* server_name)
00179 {
00180 return ConnectInput(name, server_name);
00181 }
00182
00183 bool JackPosixSemaphore::Disconnect()
00184 {
00185 jack_log("JackPosixSemaphore::Disconnect %s", fName);
00186
00187 if (fSemaphore) {
00188 if (sem_close(fSemaphore) != 0) {
00189 jack_error("Disconnect: can't disconnect named semaphore name = %s err = %s", fName, strerror(errno));
00190 return false;
00191 } else {
00192 fSemaphore = NULL;
00193 return true;
00194 }
00195 } else {
00196 return true;
00197 }
00198 }
00199
00200
00201 void JackPosixSemaphore::Destroy()
00202 {
00203 if (fSemaphore != NULL) {
00204 jack_log("JackPosixSemaphore::Destroy");
00205 sem_unlink(fName);
00206 if (sem_close(fSemaphore) != 0) {
00207 jack_error("Destroy: can't destroy semaphore name = %s err = %s", fName, strerror(errno));
00208 }
00209 fSemaphore = NULL;
00210 } else {
00211 jack_error("JackPosixSemaphore::Destroy semaphore == NULL");
00212 }
00213 }
00214
00215 }
00216