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