Jack2
1.9.7
|
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 fThread.Stop(); 00070 fRequestListenSocket.Close(); 00071 00072 // Close remaining client sockets 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) { // Should never happen... correspond to a client that started the socket but never opened... 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 // Read header 00164 JackRequest header; 00165 if (header.Read(socket) < 0) { 00166 jack_log("HandleRequest: cannot read header"); 00167 ClientKill(fd); // TO CHECK SOLARIS 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 // Read data 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 // First fd is the server request socket 00515 fPollTable[0].fd = fRequestListenSocket.GetFd(); 00516 fPollTable[0].events = POLLIN | POLLERR; 00517 00518 // Next fd for clients 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 // Global poll 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 // Poll all clients 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 // Check the server request socket */ 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 } // end of namespace 00580 00581