Jack2 1.9.6
|
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* 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, &refnum, shared_engine, shared_client, shared_graph); 00110 if (*result == 0) { 00111 fSocketTable[fd].first = refnum; 00112 fRebuild = true; 00113 } else { 00114 jack_error("Cannot create new client"); 00115 } 00116 } 00117 00118 void JackSocketServerChannel::ClientRemove(int fd, int refnum) 00119 { 00120 pair<int, JackClientSocket*> elem = fSocketTable[fd]; 00121 JackClientSocket* socket = elem.second; 00122 assert(socket); 00123 jack_log("JackSocketServerChannel::ClientRemove ref = %d", refnum); 00124 fSocketTable.erase(fd); 00125 socket->Close(); 00126 delete socket; 00127 fRebuild = true; 00128 } 00129 00130 void JackSocketServerChannel::ClientKill(int fd) 00131 { 00132 pair<int, JackClientSocket*> elem = fSocketTable[fd]; 00133 JackClientSocket* socket = elem.second; 00134 int refnum = elem.first; 00135 00136 assert(socket); 00137 jack_log("JackSocketServerChannel::ClientKill ref = %d", refnum); 00138 00139 if (refnum == -1) { // Should never happen... correspond to a client that started the socket but never opened... 00140 jack_log("Client was not opened : probably correspond to server_check"); 00141 } else { 00142 fServer->ClientKill(refnum); 00143 } 00144 00145 fSocketTable.erase(fd); 00146 socket->Close(); 00147 delete socket; 00148 fRebuild = true; 00149 } 00150 00151 bool JackSocketServerChannel::HandleRequest(int fd) 00152 { 00153 pair<int, JackClientSocket*> elem = fSocketTable[fd]; 00154 JackClientSocket* socket = elem.second; 00155 assert(socket); 00156 00157 // Read header 00158 JackRequest header; 00159 if (header.Read(socket) < 0) { 00160 jack_log("HandleRequest: cannot read header"); 00161 ClientKill(fd); // TO CHECK SOLARIS 00162 return false; 00163 } 00164 00165 // Read data 00166 switch (header.fType) { 00167 00168 case JackRequest::kClientCheck: { 00169 jack_log("JackRequest::ClientCheck"); 00170 JackClientCheckRequest req; 00171 JackClientCheckResult res; 00172 if (req.Read(socket) == 0) 00173 res.fResult = fServer->GetEngine()->ClientCheck(req.fName, res.fName, req.fProtocol, req.fOptions, &res.fStatus); 00174 if (res.Write(socket) < 0) 00175 jack_error("JackRequest::ClientCheck write error name = %s", req.fName); 00176 break; 00177 } 00178 00179 case JackRequest::kClientOpen: { 00180 jack_log("JackRequest::ClientOpen"); 00181 JackClientOpenRequest req; 00182 JackClientOpenResult res; 00183 if (req.Read(socket) == 0) 00184 ClientAdd(fd, req.fName, req.fPID, &res.fSharedEngine, &res.fSharedClient, &res.fSharedGraph, &res.fResult); 00185 if (res.Write(socket) < 0) 00186 jack_error("JackRequest::ClientOpen write error name = %s", req.fName); 00187 break; 00188 } 00189 00190 case JackRequest::kClientClose: { 00191 jack_log("JackRequest::ClientClose"); 00192 JackClientCloseRequest req; 00193 JackResult res; 00194 if (req.Read(socket) == 0) 00195 res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum); 00196 if (res.Write(socket) < 0) 00197 jack_error("JackRequest::ClientClose write error ref = %d", req.fRefNum); 00198 ClientRemove(fd, req.fRefNum); 00199 break; 00200 } 00201 00202 case JackRequest::kActivateClient: { 00203 JackActivateRequest req; 00204 JackResult res; 00205 jack_log("JackRequest::ActivateClient"); 00206 if (req.Read(socket) == 0) 00207 res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime); 00208 if (res.Write(socket) < 0) 00209 jack_error("JackRequest::ActivateClient write error ref = %d", req.fRefNum); 00210 break; 00211 } 00212 00213 case JackRequest::kDeactivateClient: { 00214 jack_log("JackRequest::DeactivateClient"); 00215 JackDeactivateRequest req; 00216 JackResult res; 00217 if (req.Read(socket) == 0) 00218 res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum); 00219 if (res.Write(socket) < 0) 00220 jack_error("JackRequest::DeactivateClient write error ref = %d", req.fRefNum); 00221 break; 00222 } 00223 00224 case JackRequest::kRegisterPort: { 00225 jack_log("JackRequest::RegisterPort"); 00226 JackPortRegisterRequest req; 00227 JackPortRegisterResult res; 00228 if (req.Read(socket) == 0) 00229 res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fPortType, req.fFlags, req.fBufferSize, &res.fPortIndex); 00230 if (res.Write(socket) < 0) 00231 jack_error("JackRequest::RegisterPort write error ref = %d", req.fRefNum); 00232 break; 00233 } 00234 00235 case JackRequest::kUnRegisterPort: { 00236 jack_log("JackRequest::UnRegisterPort"); 00237 JackPortUnRegisterRequest req; 00238 JackResult res; 00239 if (req.Read(socket) == 0) 00240 res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex); 00241 if (res.Write(socket) < 0) 00242 jack_error("JackRequest::UnRegisterPort write error ref = %d", req.fRefNum); 00243 break; 00244 } 00245 00246 case JackRequest::kConnectNamePorts: { 00247 jack_log("JackRequest::ConnectNamePorts"); 00248 JackPortConnectNameRequest req; 00249 JackResult res; 00250 if (req.Read(socket) == 0) 00251 res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst); 00252 if (res.Write(socket) < 0) 00253 jack_error("JackRequest::ConnectNamePorts write error ref = %d", req.fRefNum); 00254 break; 00255 } 00256 00257 case JackRequest::kDisconnectNamePorts: { 00258 jack_log("JackRequest::DisconnectNamePorts"); 00259 JackPortDisconnectNameRequest req; 00260 JackResult res; 00261 if (req.Read(socket) == 0) 00262 res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst); 00263 if (res.Write(socket) < 0) 00264 jack_error("JackRequest::DisconnectNamePorts write error ref = %d", req.fRefNum); 00265 break; 00266 } 00267 00268 case JackRequest::kConnectPorts: { 00269 jack_log("JackRequest::ConnectPorts"); 00270 JackPortConnectRequest req; 00271 JackResult res; 00272 if (req.Read(socket) == 0) 00273 res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst); 00274 if (res.Write(socket) < 0) 00275 jack_error("JackRequest::ConnectPorts write error ref = %d", req.fRefNum); 00276 break; 00277 } 00278 00279 case JackRequest::kDisconnectPorts: { 00280 jack_log("JackRequest::DisconnectPorts"); 00281 JackPortDisconnectRequest req; 00282 JackResult res; 00283 if (req.Read(socket) == 0) 00284 res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst); 00285 if (res.Write(socket) < 0) 00286 jack_error("JackRequest::DisconnectPorts write error ref = %d", req.fRefNum); 00287 break; 00288 } 00289 00290 case JackRequest::kPortRename: { 00291 jack_log("JackRequest::PortRename"); 00292 JackPortRenameRequest req; 00293 JackResult res; 00294 if (req.Read(socket) == 0) 00295 res.fResult = fServer->GetEngine()->PortRename(req.fRefNum, req.fPort, req.fName); 00296 if (res.Write(socket) < 0) 00297 jack_error("JackRequest::PortRename write error ref = %d", req.fRefNum); 00298 break; 00299 } 00300 00301 case JackRequest::kSetBufferSize: { 00302 jack_log("JackRequest::SetBufferSize"); 00303 JackSetBufferSizeRequest req; 00304 JackResult res; 00305 if (req.Read(socket) == 0) 00306 res.fResult = fServer->SetBufferSize(req.fBufferSize); 00307 if (res.Write(socket) < 0) 00308 jack_error("JackRequest::SetBufferSize write error"); 00309 break; 00310 } 00311 00312 case JackRequest::kSetFreeWheel: { 00313 jack_log("JackRequest::SetFreeWheel"); 00314 JackSetFreeWheelRequest req; 00315 JackResult res; 00316 if (req.Read(socket) == 0) 00317 res.fResult = fServer->SetFreewheel(req.fOnOff); 00318 if (res.Write(socket) < 0) 00319 jack_error("JackRequest::SetFreeWheel write error"); 00320 break; 00321 } 00322 00323 case JackRequest::kReleaseTimebase: { 00324 jack_log("JackRequest::ReleaseTimebase"); 00325 JackReleaseTimebaseRequest req; 00326 JackResult res; 00327 if (req.Read(socket) == 0) 00328 res.fResult = fServer->ReleaseTimebase(req.fRefNum); 00329 if (res.Write(socket) < 0) 00330 jack_error("JackRequest::ReleaseTimebase write error ref = %d", req.fRefNum); 00331 break; 00332 } 00333 00334 case JackRequest::kSetTimebaseCallback: { 00335 jack_log("JackRequest::SetTimebaseCallback"); 00336 JackSetTimebaseCallbackRequest req; 00337 JackResult res; 00338 if (req.Read(socket) == 0) 00339 res.fResult = fServer->SetTimebaseCallback(req.fRefNum, req.fConditionnal); 00340 if (res.Write(socket) < 0) 00341 jack_error("JackRequest::SetTimebaseCallback write error ref = %d", req.fRefNum); 00342 break; 00343 } 00344 00345 case JackRequest::kGetInternalClientName: { 00346 jack_log("JackRequest::GetInternalClientName"); 00347 JackGetInternalClientNameRequest req; 00348 JackGetInternalClientNameResult res; 00349 if (req.Read(socket) == 0) 00350 res.fResult = fServer->GetEngine()->GetInternalClientName(req.fIntRefNum, res.fName); 00351 if (res.Write(socket) < 0) 00352 jack_error("JackRequest::GetInternalClientName write error ref = %d", req.fRefNum); 00353 break; 00354 } 00355 00356 case JackRequest::kInternalClientHandle: { 00357 jack_log("JackRequest::InternalClientHandle"); 00358 JackInternalClientHandleRequest req; 00359 JackInternalClientHandleResult res; 00360 if (req.Read(socket) == 0) 00361 res.fResult = fServer->GetEngine()->InternalClientHandle(req.fName, &res.fStatus, &res.fIntRefNum); 00362 if (res.Write(socket) < 0) 00363 jack_error("JackRequest::InternalClientHandle write error ref = %d", req.fRefNum); 00364 break; 00365 } 00366 00367 case JackRequest::kInternalClientLoad: { 00368 jack_log("JackRequest::InternalClientLoad"); 00369 JackInternalClientLoadRequest req; 00370 JackInternalClientLoadResult res; 00371 if (req.Read(socket) == 0) 00372 res.fResult = fServer->InternalClientLoad(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, &res.fStatus); 00373 if (res.Write(socket) < 0) 00374 jack_error("JackRequest::InternalClientLoad write error name = %s", req.fName); 00375 break; 00376 } 00377 00378 case JackRequest::kInternalClientUnload: { 00379 jack_log("JackRequest::InternalClientUnload"); 00380 JackInternalClientUnloadRequest req; 00381 JackInternalClientUnloadResult res; 00382 if (req.Read(socket) == 0) 00383 res.fResult = fServer->GetEngine()->InternalClientUnload(req.fIntRefNum, &res.fStatus); 00384 if (res.Write(socket) < 0) 00385 jack_error("JackRequest::InternalClientUnload write error ref = %d", req.fRefNum); 00386 break; 00387 } 00388 00389 case JackRequest::kNotification: { 00390 jack_log("JackRequest::Notification"); 00391 JackClientNotificationRequest req; 00392 if (req.Read(socket) == 0) { 00393 if (req.fNotify == kQUIT) { 00394 jack_log("JackRequest::Notification kQUIT"); 00395 throw JackQuitException(); 00396 } else { 00397 fServer->Notify(req.fRefNum, req.fNotify, req.fValue); 00398 } 00399 } 00400 break; 00401 } 00402 00403 default: 00404 jack_error("Unknown request %ld", header.fType); 00405 break; 00406 } 00407 00408 return true; 00409 } 00410 00411 void JackSocketServerChannel::BuildPoolTable() 00412 { 00413 if (fRebuild) { 00414 fRebuild = false; 00415 delete[] fPollTable; 00416 fPollTable = new pollfd[fSocketTable.size() + 1]; 00417 00418 jack_log("JackSocketServerChannel::BuildPoolTable size = %d", fSocketTable.size() + 1); 00419 00420 // First fd is the server request socket 00421 fPollTable[0].fd = fRequestListenSocket.GetFd(); 00422 fPollTable[0].events = POLLIN | POLLERR; 00423 00424 // Next fd for clients 00425 map<int, pair<int, JackClientSocket*> >::iterator it; 00426 int i; 00427 00428 for (i = 1, it = fSocketTable.begin(); it != fSocketTable.end(); it++, i++) { 00429 jack_log("fSocketTable i = %ld fd = %ld", i, it->first); 00430 fPollTable[i].fd = it->first; 00431 fPollTable[i].events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL; 00432 } 00433 } 00434 } 00435 00436 bool JackSocketServerChannel::Init() 00437 { 00438 sigset_t set; 00439 sigemptyset(&set); 00440 sigaddset(&set, SIGPIPE); 00441 pthread_sigmask(SIG_BLOCK, &set, 0); 00442 return true; 00443 } 00444 00445 bool JackSocketServerChannel::Execute() 00446 { 00447 try { 00448 00449 // Global poll 00450 if ((poll(fPollTable, fSocketTable.size() + 1, 10000) < 0) && (errno != EINTR)) { 00451 jack_error("Engine poll failed err = %s request thread quits...", strerror(errno)); 00452 return false; 00453 } else { 00454 00455 // Poll all clients 00456 for (unsigned int i = 1; i < fSocketTable.size() + 1; i++) { 00457 int fd = fPollTable[i].fd; 00458 jack_log("fPollTable i = %ld fd = %ld", i, fd); 00459 if (fPollTable[i].revents & ~POLLIN) { 00460 jack_log("Poll client error err = %s", strerror(errno)); 00461 ClientKill(fd); 00462 } else if (fPollTable[i].revents & POLLIN) { 00463 if (!HandleRequest(fd)) 00464 jack_log("Could not handle external client request"); 00465 } 00466 } 00467 00468 // Check the server request socket */ 00469 if (fPollTable[0].revents & POLLERR) 00470 jack_error("Error on server request socket err = %s", strerror(errno)); 00471 00472 if (fPollTable[0].revents & POLLIN) 00473 ClientCreate(); 00474 } 00475 00476 BuildPoolTable(); 00477 return true; 00478 00479 } catch (JackQuitException& e) { 00480 jack_log("JackMachServerChannel::Execute JackQuitException"); 00481 return false; 00482 } 00483 } 00484 00485 } // end of namespace 00486 00487