00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackSocketServerChannel.h"
00021 #include "JackRequest.h"
00022 #include "JackServer.h"
00023 #include "JackLockedEngine.h"
00024 #include "JackGlobals.h"
00025 #include "JackServerGlobals.h"
00026 #include "JackClient.h"
00027 #include "JackTools.h"
00028 #include "JackNotification.h"
00029 #include "JackException.h"
00030
00031 #include <assert.h>
00032 #include <signal.h>
00033
00034 using namespace std;
00035
00036 namespace Jack
00037 {
00038
00039 JackSocketServerChannel::JackSocketServerChannel():
00040 fThread(this)
00041 {
00042 fPollTable = NULL;
00043 fRebuild = true;
00044 }
00045
00046 JackSocketServerChannel::~JackSocketServerChannel()
00047 {
00048 delete[] fPollTable;
00049 }
00050
00051 int JackSocketServerChannel::Open(const char* server_name, JackServer* server)
00052 {
00053 jack_log("JackSocketServerChannel::Open");
00054
00055
00056 if (fRequestListenSocket.Bind(jack_server_dir, server_name, 0) < 0) {
00057 jack_log("JackSocketServerChannel::Open : cannot create result listen socket");
00058 return -1;
00059 }
00060
00061
00062 BuildPoolTable();
00063 fServer = server;
00064 return 0;
00065 }
00066
00067 void JackSocketServerChannel::Close()
00068 {
00069 fRequestListenSocket.Close();
00070
00071
00072 std::map<int, std::pair<int, JackClientSocket*> >::iterator it;
00073 for (it = fSocketTable.begin(); it != fSocketTable.end(); it++) {
00074 pair<int, JackClientSocket*> elem = (*it).second;
00075 JackClientSocket* socket = elem.second;
00076 assert(socket);
00077 socket->Close();
00078 delete socket;
00079 }
00080 }
00081
00082 int JackSocketServerChannel::Start()
00083 {
00084 if (fThread.Start() != 0) {
00085 jack_error("Cannot start Jack server listener");
00086 return -1;
00087 } else {
00088 return 0;
00089 }
00090 }
00091
00092 void JackSocketServerChannel::Stop()
00093 {
00094 fThread.Kill();
00095 }
00096
00097 void JackSocketServerChannel::ClientCreate()
00098 {
00099 jack_log("JackSocketServerChannel::ClientCreate socket");
00100 JackClientSocket* socket = fRequestListenSocket.Accept();
00101 if (socket) {
00102 fSocketTable[socket->GetFd()] = make_pair( -1, socket);
00103 fRebuild = true;
00104 } else {
00105 jack_error("Client socket cannot be created");
00106 }
00107 }
00108
00109 void JackSocketServerChannel::ClientAdd(int fd, char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result)
00110 {
00111 jack_log("JackSocketServerChannel::ClientAdd");
00112 int refnum = -1;
00113 *result = fServer->GetEngine()->ClientExternalOpen(name, pid, uuid, &refnum, shared_engine, shared_client, shared_graph);
00114 if (*result == 0) {
00115 fSocketTable[fd].first = refnum;
00116 fRebuild = true;
00117 #ifdef __APPLE__
00118 int on = 1;
00119 if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) {
00120 jack_log("setsockopt SO_NOSIGPIPE fd = %ld err = %s", fd, strerror(errno));
00121 }
00122 #endif
00123 } else {
00124 jack_error("Cannot create new client");
00125 }
00126 }
00127
00128 void JackSocketServerChannel::ClientRemove(int fd, int refnum)
00129 {
00130 pair<int, JackClientSocket*> elem = fSocketTable[fd];
00131 JackClientSocket* socket = elem.second;
00132 assert(socket);
00133 jack_log("JackSocketServerChannel::ClientRemove ref = %d", refnum);
00134 fSocketTable.erase(fd);
00135 socket->Close();
00136 delete socket;
00137 fRebuild = true;
00138 }
00139
00140 void JackSocketServerChannel::ClientKill(int fd)
00141 {
00142 pair<int, JackClientSocket*> elem = fSocketTable[fd];
00143 JackClientSocket* socket = elem.second;
00144 int refnum = elem.first;
00145
00146 assert(socket);
00147 jack_log("JackSocketServerChannel::ClientKill ref = %d", refnum);
00148
00149 if (refnum == -1) {
00150 jack_log("Client was not opened : probably correspond to server_check");
00151 } else {
00152 fServer->ClientKill(refnum);
00153 }
00154
00155 fSocketTable.erase(fd);
00156 socket->Close();
00157 delete socket;
00158 fRebuild = true;
00159 }
00160
00161 bool JackSocketServerChannel::HandleRequest(int fd)
00162 {
00163 pair<int, JackClientSocket*> elem = fSocketTable[fd];
00164 JackClientSocket* socket = elem.second;
00165 assert(socket);
00166
00167
00168 JackRequest header;
00169 if (header.Read(socket) < 0) {
00170 jack_log("HandleRequest: cannot read header");
00171 ClientKill(fd);
00172 return false;
00173 }
00174
00175 if (fd == JackServerGlobals::fRTNotificationSocket && header.fType != JackRequest::kNotification) {
00176 jack_error("fRTNotificationSocket = %d", JackServerGlobals::fRTNotificationSocket);
00177 jack_error("JackSocketServerChannel::HandleRequest : incorrect notification !!");
00178 return true;
00179 }
00180
00181
00182 switch (header.fType) {
00183
00184 case JackRequest::kClientCheck: {
00185 jack_log("JackRequest::ClientCheck");
00186 JackClientCheckRequest req;
00187 JackClientCheckResult res;
00188 if (req.Read(socket) == 0)
00189 res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus);
00190 if (res.Write(socket) < 0)
00191 jack_error("JackRequest::ClientCheck write error name = %s", req.fName);
00192
00193 if (req.fOpen)
00194 HandleRequest(fd);
00195 break;
00196 }
00197
00198 case JackRequest::kClientOpen: {
00199 jack_log("JackRequest::ClientOpen");
00200 JackClientOpenRequest req;
00201 JackClientOpenResult res;
00202 if (req.Read(socket) == 0)
00203 ClientAdd(fd, req.fName, req.fPID, req.fUUID, &res.fSharedEngine, &res.fSharedClient, &res.fSharedGraph, &res.fResult);
00204 if (res.Write(socket) < 0)
00205 jack_error("JackRequest::ClientOpen write error name = %s", req.fName);
00206 break;
00207 }
00208
00209 case JackRequest::kClientClose: {
00210 jack_log("JackRequest::ClientClose");
00211 JackClientCloseRequest req;
00212 JackResult res;
00213 if (req.Read(socket) == 0)
00214 res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum);
00215 if (res.Write(socket) < 0)
00216 jack_error("JackRequest::ClientClose write error ref = %d", req.fRefNum);
00217 ClientRemove(fd, req.fRefNum);
00218 break;
00219 }
00220
00221 case JackRequest::kActivateClient: {
00222 JackActivateRequest req;
00223 JackResult res;
00224 jack_log("JackRequest::ActivateClient");
00225 if (req.Read(socket) == 0)
00226 res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime);
00227 if (res.Write(socket) < 0)
00228 jack_error("JackRequest::ActivateClient write error ref = %d", req.fRefNum);
00229 break;
00230 }
00231
00232 case JackRequest::kDeactivateClient: {
00233 jack_log("JackRequest::DeactivateClient");
00234 JackDeactivateRequest req;
00235 JackResult res;
00236 if (req.Read(socket) == 0)
00237 res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum);
00238 if (res.Write(socket) < 0)
00239 jack_error("JackRequest::DeactivateClient write error ref = %d", req.fRefNum);
00240 break;
00241 }
00242
00243 case JackRequest::kRegisterPort: {
00244 jack_log("JackRequest::RegisterPort");
00245 JackPortRegisterRequest req;
00246 JackPortRegisterResult res;
00247 if (req.Read(socket) == 0)
00248 res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fPortType, req.fFlags, req.fBufferSize, &res.fPortIndex);
00249 if (res.Write(socket) < 0)
00250 jack_error("JackRequest::RegisterPort write error ref = %d", req.fRefNum);
00251 break;
00252 }
00253
00254 case JackRequest::kUnRegisterPort: {
00255 jack_log("JackRequest::UnRegisterPort");
00256 JackPortUnRegisterRequest req;
00257 JackResult res;
00258 if (req.Read(socket) == 0)
00259 res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex);
00260 if (res.Write(socket) < 0)
00261 jack_error("JackRequest::UnRegisterPort write error ref = %d", req.fRefNum);
00262 break;
00263 }
00264
00265 case JackRequest::kConnectNamePorts: {
00266 jack_log("JackRequest::ConnectNamePorts");
00267 JackPortConnectNameRequest req;
00268 JackResult res;
00269 if (req.Read(socket) == 0)
00270 res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
00271 if (res.Write(socket) < 0)
00272 jack_error("JackRequest::ConnectNamePorts write error ref = %d", req.fRefNum);
00273 break;
00274 }
00275
00276 case JackRequest::kDisconnectNamePorts: {
00277 jack_log("JackRequest::DisconnectNamePorts");
00278 JackPortDisconnectNameRequest req;
00279 JackResult res;
00280 if (req.Read(socket) == 0)
00281 res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
00282 if (res.Write(socket) < 0)
00283 jack_error("JackRequest::DisconnectNamePorts write error ref = %d", req.fRefNum);
00284 break;
00285 }
00286
00287 case JackRequest::kConnectPorts: {
00288 jack_log("JackRequest::ConnectPorts");
00289 JackPortConnectRequest req;
00290 JackResult res;
00291 if (req.Read(socket) == 0)
00292 res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
00293 if (res.Write(socket) < 0)
00294 jack_error("JackRequest::ConnectPorts write error ref = %d", req.fRefNum);
00295 break;
00296 }
00297
00298 case JackRequest::kDisconnectPorts: {
00299 jack_log("JackRequest::DisconnectPorts");
00300 JackPortDisconnectRequest req;
00301 JackResult res;
00302 if (req.Read(socket) == 0)
00303 res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
00304 if (res.Write(socket) < 0)
00305 jack_error("JackRequest::DisconnectPorts write error ref = %d", req.fRefNum);
00306 break;
00307 }
00308
00309 case JackRequest::kPortRename: {
00310 jack_log("JackRequest::PortRename");
00311 JackPortRenameRequest req;
00312 JackResult res;
00313 if (req.Read(socket) == 0)
00314 res.fResult = fServer->GetEngine()->PortRename(req.fRefNum, req.fPort, req.fName);
00315 if (res.Write(socket) < 0)
00316 jack_error("JackRequest::PortRename write error ref = %d", req.fRefNum);
00317 break;
00318 }
00319
00320 case JackRequest::kSetBufferSize: {
00321 jack_log("JackRequest::SetBufferSize");
00322 JackSetBufferSizeRequest req;
00323 JackResult res;
00324 if (req.Read(socket) == 0)
00325 res.fResult = fServer->SetBufferSize(req.fBufferSize);
00326 if (res.Write(socket) < 0)
00327 jack_error("JackRequest::SetBufferSize write error");
00328 break;
00329 }
00330
00331 case JackRequest::kSetFreeWheel: {
00332 jack_log("JackRequest::SetFreeWheel");
00333 JackSetFreeWheelRequest req;
00334 JackResult res;
00335 if (req.Read(socket) == 0)
00336 res.fResult = fServer->SetFreewheel(req.fOnOff);
00337 if (res.Write(socket) < 0)
00338 jack_error("JackRequest::SetFreeWheel write error");
00339 break;
00340 }
00341
00342 case JackRequest::kComputeTotalLatencies: {
00343 jack_log("JackRequest::ComputeTotalLatencies");
00344 JackComputeTotalLatenciesRequest req;
00345 JackResult res;
00346 if (req.Read(socket) == 0)
00347 res.fResult = fServer->GetEngine()->ComputeTotalLatencies();
00348 if (res.Write(socket) < 0)
00349 jack_error("JackRequest::ComputeTotalLatencies write error");
00350 break;
00351 }
00352
00353 case JackRequest::kReleaseTimebase: {
00354 jack_log("JackRequest::ReleaseTimebase");
00355 JackReleaseTimebaseRequest req;
00356 JackResult res;
00357 if (req.Read(socket) == 0)
00358 res.fResult = fServer->ReleaseTimebase(req.fRefNum);
00359 if (res.Write(socket) < 0)
00360 jack_error("JackRequest::ReleaseTimebase write error ref = %d", req.fRefNum);
00361 break;
00362 }
00363
00364 case JackRequest::kSetTimebaseCallback: {
00365 jack_log("JackRequest::SetTimebaseCallback");
00366 JackSetTimebaseCallbackRequest req;
00367 JackResult res;
00368 if (req.Read(socket) == 0)
00369 res.fResult = fServer->SetTimebaseCallback(req.fRefNum, req.fConditionnal);
00370 if (res.Write(socket) < 0)
00371 jack_error("JackRequest::SetTimebaseCallback write error ref = %d", req.fRefNum);
00372 break;
00373 }
00374
00375 case JackRequest::kGetInternalClientName: {
00376 jack_log("JackRequest::GetInternalClientName");
00377 JackGetInternalClientNameRequest req;
00378 JackGetInternalClientNameResult res;
00379 if (req.Read(socket) == 0)
00380 res.fResult = fServer->GetEngine()->GetInternalClientName(req.fIntRefNum, res.fName);
00381 if (res.Write(socket) < 0)
00382 jack_error("JackRequest::GetInternalClientName write error ref = %d", req.fRefNum);
00383 break;
00384 }
00385
00386 case JackRequest::kInternalClientHandle: {
00387 jack_log("JackRequest::InternalClientHandle");
00388 JackInternalClientHandleRequest req;
00389 JackInternalClientHandleResult res;
00390 if (req.Read(socket) == 0)
00391 res.fResult = fServer->GetEngine()->InternalClientHandle(req.fName, &res.fStatus, &res.fIntRefNum);
00392 if (res.Write(socket) < 0)
00393 jack_error("JackRequest::InternalClientHandle write error ref = %d", req.fRefNum);
00394 break;
00395 }
00396
00397 case JackRequest::kInternalClientLoad: {
00398 jack_log("JackRequest::InternalClientLoad");
00399 JackInternalClientLoadRequest req;
00400 JackInternalClientLoadResult res;
00401 if (req.Read(socket) == 0)
00402 res.fResult = fServer->InternalClientLoad1(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus);
00403 if (res.Write(socket) < 0)
00404 jack_error("JackRequest::InternalClientLoad write error name = %s", req.fName);
00405 break;
00406 }
00407
00408 case JackRequest::kInternalClientUnload: {
00409 jack_log("JackRequest::InternalClientUnload");
00410 JackInternalClientUnloadRequest req;
00411 JackInternalClientUnloadResult res;
00412 if (req.Read(socket) == 0)
00413 res.fResult = fServer->GetEngine()->InternalClientUnload(req.fIntRefNum, &res.fStatus);
00414 if (res.Write(socket) < 0)
00415 jack_error("JackRequest::InternalClientUnload write error ref = %d", req.fRefNum);
00416 break;
00417 }
00418
00419 case JackRequest::kNotification: {
00420 jack_log("JackRequest::Notification");
00421 JackClientNotificationRequest req;
00422 if (req.Read(socket) == 0) {
00423 if (req.fNotify == kQUIT) {
00424 jack_log("JackRequest::Notification kQUIT");
00425 throw JackQuitException();
00426 } else {
00427 fServer->Notify(req.fRefNum, req.fNotify, req.fValue);
00428 }
00429 }
00430 break;
00431 }
00432
00433 case JackRequest::kSessionNotify: {
00434 jack_log("JackRequest::SessionNotify");
00435 JackSessionNotifyRequest req;
00436 if (req.Read(socket) == 0) {
00437 fServer->GetEngine()->SessionNotify(req.fRefNum, req.fDst, req.fEventType, req.fPath, socket, NULL);
00438 }
00439 break;
00440 }
00441
00442 case JackRequest::kSessionReply: {
00443 jack_log("JackRequest::SessionReply");
00444 JackSessionReplyRequest req;
00445 JackResult res;
00446 if (req.Read(socket) == 0) {
00447 fServer->GetEngine()->SessionReply(req.fRefNum);
00448 res.fResult = 0;
00449 }
00450 if (res.Write(socket) < 0)
00451 jack_error("JackRequest::SessionReply write error");
00452 break;
00453 }
00454
00455 case JackRequest::kGetClientByUUID: {
00456 jack_log("JackRequest::GetClientByUUID");
00457 JackGetClientNameRequest req;
00458 JackClientNameResult res;
00459 if (req.Read(socket) == 0) {
00460 fServer->GetEngine()->GetClientNameForUUID(req.fUUID, res.fName, &res.fResult);
00461 }
00462 if (res.Write(socket) < 0)
00463 jack_error("JackRequest::GetClientByUUID write error");
00464 break;
00465 }
00466
00467 case JackRequest::kGetUUIDByClient: {
00468 jack_log("JackRequest::GetUUIDByClient");
00469 JackGetUUIDRequest req;
00470 JackUUIDResult res;
00471 if (req.Read(socket) == 0) {
00472 fServer->GetEngine()->GetUUIDForClientName(req.fName, res.fUUID, &res.fResult);
00473 }
00474 if (res.Write(socket) < 0)
00475 jack_error("JackRequest::GetUUIDByClient write error");
00476 break;
00477 }
00478
00479 case JackRequest::kReserveClientName: {
00480 jack_log("JackRequest::ReserveClientName");
00481 JackReserveNameRequest req;
00482 JackResult res;
00483 if (req.Read(socket) == 0) {
00484 fServer->GetEngine()->ReserveClientName(req.fName, req.fUUID, &res.fResult);
00485 }
00486 if (res.Write(socket) < 0)
00487 jack_error("JackRequest::ReserveClientName write error");
00488 break;
00489 }
00490
00491 case JackRequest::kClientHasSessionCallback: {
00492 jack_log("JackRequest::ClientHasSessionCallback");
00493 JackClientHasSessionCallbackRequest req;
00494 JackResult res;
00495 if (req.Read(socket) == 0) {
00496 fServer->GetEngine()->ClientHasSessionCallback(req.fName, &res.fResult);
00497 }
00498 if (res.Write(socket) < 0)
00499 jack_error("JackRequest::ClientHasSessionCallback write error");
00500 break;
00501 }
00502
00503 default:
00504 jack_error("Unknown request %ld", header.fType);
00505 break;
00506 }
00507
00508 return true;
00509 }
00510
00511 void JackSocketServerChannel::BuildPoolTable()
00512 {
00513 if (fRebuild) {
00514 fRebuild = false;
00515 delete[] fPollTable;
00516 fPollTable = new pollfd[fSocketTable.size() + 1];
00517
00518 jack_log("JackSocketServerChannel::BuildPoolTable size = %d", fSocketTable.size() + 1);
00519
00520
00521 fPollTable[0].fd = fRequestListenSocket.GetFd();
00522 fPollTable[0].events = POLLIN | POLLERR;
00523
00524
00525 map<int, pair<int, JackClientSocket*> >::iterator it;
00526 int i;
00527
00528 for (i = 1, it = fSocketTable.begin(); it != fSocketTable.end(); it++, i++) {
00529 jack_log("fSocketTable i = %ld fd = %ld", i, it->first);
00530 fPollTable[i].fd = it->first;
00531 fPollTable[i].events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
00532 }
00533 }
00534 }
00535
00536 bool JackSocketServerChannel::Init()
00537 {
00538 sigset_t set;
00539 sigemptyset(&set);
00540 sigaddset(&set, SIGPIPE);
00541 pthread_sigmask(SIG_BLOCK, &set, 0);
00542 return true;
00543 }
00544
00545 bool JackSocketServerChannel::Execute()
00546 {
00547 try {
00548
00549
00550 if ((poll(fPollTable, fSocketTable.size() + 1, 10000) < 0) && (errno != EINTR)) {
00551 jack_error("Engine poll failed err = %s request thread quits...", strerror(errno));
00552 return false;
00553 } else {
00554
00555
00556 for (unsigned int i = 1; i < fSocketTable.size() + 1; i++) {
00557 int fd = fPollTable[i].fd;
00558 jack_log("fPollTable i = %ld fd = %ld", i, fd);
00559 if (fPollTable[i].revents & ~POLLIN) {
00560 jack_log("Poll client error err = %s", strerror(errno));
00561 ClientKill(fd);
00562 } else if (fPollTable[i].revents & POLLIN) {
00563 if (!HandleRequest(fd))
00564 jack_log("Could not handle external client request");
00565 }
00566 }
00567
00568
00569 if (fPollTable[0].revents & POLLERR)
00570 jack_error("Error on server request socket err = %s", strerror(errno));
00571
00572 if (fPollTable[0].revents & POLLIN)
00573 ClientCreate();
00574 }
00575
00576 BuildPoolTable();
00577 return true;
00578
00579 } catch (JackQuitException& e) {
00580 jack_log("JackSocketServerChannel::Execute JackQuitException");
00581 return false;
00582 }
00583 }
00584
00585 }
00586
00587