Jack2 1.9.6

JackSocketServerChannel.cpp

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