Jack2
1.9.8
|
00001 /* 00002 Copyright (C) 2004-2008 Grame 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as published by 00006 the Free Software Foundation; either version 2.1 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 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 // Prepare request socket 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 // Prepare for poll 00062 BuildPoolTable(); 00063 fServer = server; 00064 return 0; 00065 } 00066 00067 void JackSocketServerChannel::Close() 00068 { 00069 fRequestListenSocket.Close(); 00070 00071 // Close remaining client sockets 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) { // Should never happen... correspond to a client that started the socket but never opened... 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 // Read header 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 // Read data 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 // Atomic ClientCheck followed by ClientOpen on same socket 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 // First fd is the server request socket 00521 fPollTable[0].fd = fRequestListenSocket.GetFd(); 00522 fPollTable[0].events = POLLIN | POLLERR; 00523 00524 // Next fd for clients 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 // Global poll 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 // Poll all clients 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 // Check the server request socket */ 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 } // end of namespace 00586 00587