00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackFifo.h"
00021 #include "JackTools.h"
00022 #include "JackError.h"
00023 #include "JackPlatformPlug.h"
00024 #include <sys/types.h>
00025 #include <sys/stat.h>
00026 #include <unistd.h>
00027 #include <fcntl.h>
00028 #include <stdio.h>
00029
00030 namespace Jack
00031 {
00032
00033 void JackFifo::BuildName(const char* client_name, const char* server_name, char* res)
00034 {
00035 char ext_client_name[JACK_CLIENT_NAME_SIZE + 1];
00036 JackTools::RewriteName(client_name, ext_client_name);
00037 sprintf(res, "%s/jack_fifo.%d_%s_%s", jack_client_dir, JackTools::GetUID(), server_name, ext_client_name);
00038 }
00039
00040 bool JackFifo::Signal()
00041 {
00042 bool res;
00043 char c = 0;
00044
00045 if (fFifo < 0) {
00046 jack_error("JackFifo::Signal name = %s already desallocated!!", fName);
00047 return false;
00048 }
00049
00050 if (fFlush)
00051 return true;
00052
00053 if ((res = (write(fFifo, &c, sizeof(c)) != sizeof(c)))) {
00054 jack_error("JackFifo::Signal name = %s err = %s", fName, strerror(errno));
00055 }
00056 return !res;
00057 }
00058
00059 bool JackFifo::SignalAll()
00060 {
00061 bool res;
00062 char c = 0;
00063
00064 if (fFifo < 0) {
00065 jack_error("JackFifo::SignalAll name = %s already desallocated!!", fName);
00066 return false;
00067 }
00068
00069 if (fFlush)
00070 return true;
00071
00072 if ((res = (write(fFifo, &c, sizeof(c)) != sizeof(c)))) {
00073 jack_error("JackFifo::SignalAll name = %s err = %s", fName, strerror(errno));
00074 }
00075 return !res;
00076 }
00077
00078 bool JackFifo::Wait()
00079 {
00080 bool res;
00081 char c;
00082
00083 if (fFifo < 0) {
00084 jack_error("JackFifo::Wait name = %s already desallocated!!", fName);
00085 return false;
00086 }
00087
00088 if ((res = (read(fFifo, &c, sizeof(c)) != sizeof(c)))) {
00089 jack_error("JackFifo::Wait name = %s err = %s", fName, strerror(errno));
00090 }
00091 return !res;
00092 }
00093
00094 #ifdef __APPLE__
00095 #warning JackFifo::TimedWait not available : synchronous mode may not work correctly if FIFO are used
00096 bool JackFifo::TimedWait(long usec)
00097 {
00098 return Wait();
00099 }
00100 #else
00101
00102 bool JackFifo::TimedWait(long usec)
00103 {
00104 int res;
00105
00106 if (fFifo < 0) {
00107 jack_error("JackFifo::TimedWait name = %s already desallocated!!", fName);
00108 return false;
00109 }
00110
00111 do {
00112 res = poll(&fPoll, 1, usec / 1000);
00113 } while (res < 0 && errno == EINTR);
00114
00115 if (fPoll.revents & POLLIN) {
00116 return Wait();
00117 } else {
00118
00119 jack_log("JackFifo::TimedWait name = %s usec = %ld err = %s", fName, usec, strerror(errno));
00120 return true;
00121 }
00122 }
00123 #endif
00124
00125
00126 bool JackFifo::Allocate(const char* name, const char* server_name, int value)
00127 {
00128 struct stat statbuf;
00129 BuildName(name, server_name, fName);
00130 jack_log("JackFifo::Allocate name = %s", fName);
00131
00132 if (stat(fName, &statbuf) < 0) {
00133 if (errno == ENOENT || errno == EPERM) {
00134 if (mkfifo(fName, 0666) < 0) {
00135 jack_error("Cannot create inter-client FIFO name = %s err = %s", name, strerror(errno));
00136 return false;
00137 }
00138 } else {
00139 jack_error("Cannot check on FIFO %s", name);
00140 return false;
00141 }
00142 } else {
00143 if (!S_ISFIFO(statbuf.st_mode)) {
00144 jack_error("FIFO name = %s already exists, but is not a FIFO", name);
00145 return false;
00146 }
00147 }
00148
00149 if ((fFifo = open(fName, O_RDWR | O_CREAT, 0666)) < 0) {
00150 jack_error("Cannot open FIFO name = %s err = %s", name, strerror(errno));
00151 return false;
00152 } else {
00153 fPoll.fd = fFifo;
00154 fPoll.events = POLLERR | POLLIN | POLLHUP | POLLNVAL;
00155 return true;
00156 }
00157 }
00158
00159
00160 bool JackFifo::ConnectAux(const char* name, const char* server_name, int access)
00161 {
00162 BuildName(name, server_name, fName);
00163 jack_log("JackFifo::ConnectAux name = %s", fName);
00164
00165
00166 if (fFifo >= 0) {
00167 jack_log("Already connected name = %s", name);
00168 return true;
00169 }
00170
00171 if ((fFifo = open(fName, access)) < 0) {
00172 jack_error("Connect: can't connect named fifo name = %s err = %s", fName, strerror(errno));
00173 return false;
00174 } else {
00175 fPoll.fd = fFifo;
00176 fPoll.events = POLLERR | POLLIN | POLLHUP | POLLNVAL;
00177 return true;
00178 }
00179 }
00180
00181 bool JackFifo::Connect(const char* name, const char* server_name)
00182 {
00183 return ConnectAux(name, server_name, O_RDWR);
00184 }
00185
00186 bool JackFifo::ConnectOutput(const char* name, const char* server_name)
00187 {
00188 return ConnectAux(name, server_name, O_WRONLY | O_NONBLOCK);
00189 }
00190
00191 bool JackFifo::ConnectInput(const char* name, const char* server_name)
00192 {
00193 return ConnectAux(name, server_name, O_RDONLY);
00194 }
00195
00196 bool JackFifo::Disconnect()
00197 {
00198 if (fFifo >= 0) {
00199 jack_log("JackFifo::Disconnect %s", fName);
00200 if (close(fFifo) != 0) {
00201 jack_error("Disconnect: can't disconnect named fifo name = %s err = %s", fName, strerror(errno));
00202 return false;
00203 } else {
00204 fFifo = -1;
00205 return true;
00206 }
00207 } else {
00208 return true;
00209 }
00210 }
00211
00212
00213 void JackFifo::Destroy()
00214 {
00215 if (fFifo > 0) {
00216 jack_log("JackFifo::Destroy name = %s", fName);
00217 unlink(fName);
00218 if (close(fFifo) != 0) {
00219 jack_error("Destroy: can't destroy fifo name = %s err = %s", fName, strerror(errno));
00220 }
00221 fFifo = -1;
00222 } else {
00223 jack_error("JackFifo::Destroy fifo < 0");
00224 }
00225 }
00226
00227 }
00228