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