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