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 "JackEngine.h"
00024 #include "JackGlobals.h"
00025 #include "JackClient.h"
00026 #include "JackNotification.h"
00027 #include <assert.h>
00028 
00029 using namespace std;
00030 
00031 namespace Jack
00032 {
00033 
00034 JackSocketServerChannel::JackSocketServerChannel()
00035 {
00036     fThread = JackGlobals::MakeThread(this);
00037     fPollTable = NULL;
00038     fRebuild = true;
00039 }
00040 
00041 JackSocketServerChannel::~JackSocketServerChannel()
00042 {
00043     delete fThread;
00044     delete[] fPollTable;
00045 }
00046 
00047 int JackSocketServerChannel::Open(const char* server_name, JackServer* server)
00048 {
00049     JackLog("JackSocketServerChannel::Open \n");
00050         fServer = server;
00051 
00052     // Prepare request socket
00053     if (fRequestListenSocket.Bind(jack_server_dir, server_name, 0) < 0) {
00054         JackLog("JackSocketServerChannel::Open : cannot create result listen socket\n");
00055         return -1;
00056     }
00057 
00058     // Prepare for poll
00059     BuildPoolTable();
00060 
00061     // Start listening
00062     if (fThread->Start() != 0) {
00063         jack_error("Cannot start Jack server listener");
00064         goto error;
00065     }
00066 
00067     return 0;
00068 
00069 error:
00070     fRequestListenSocket.Close();
00071     return -1;
00072 }
00073 
00074 void JackSocketServerChannel::Close()
00075 {
00076     fThread->Kill();
00077     fRequestListenSocket.Close();
00078 }
00079 
00080 void JackSocketServerChannel::ClientCreate()
00081 {
00082     JackLog("JackSocketServerChannel::ClientCreate socket\n");
00083     JackClientSocket* socket = fRequestListenSocket.Accept();
00084     if (socket) {
00085         fSocketTable[socket->GetFd()] = make_pair( -1, socket);
00086         fRebuild = true;
00087     } else {
00088         jack_error("Client socket cannot be created");
00089     }
00090 }
00091 
00092 void JackSocketServerChannel::ClientAdd(int fd, char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result)
00093 {
00094     JackLog("JackSocketServerChannel::ClientAdd\n");
00095     int refnum = -1;
00096         *result = fServer->GetEngine()->ClientExternalOpen(name, &refnum, shared_engine, shared_client, shared_graph);
00097     if (*result == 0) {
00098         fSocketTable[fd].first = refnum;
00099         fRebuild = true;
00100     } else {
00101         jack_error("Cannot create new client");
00102     }
00103 }
00104 
00105 void JackSocketServerChannel::ClientRemove(int fd, int refnum)
00106 {
00107     pair<int, JackClientSocket*> elem = fSocketTable[fd];
00108     JackClientSocket* socket = elem.second;
00109     assert(socket);
00110     JackLog("JackSocketServerChannel::ClientRemove ref = %d\n", refnum);
00111     fSocketTable.erase(fd);
00112     socket->Close();
00113     delete socket;
00114     fRebuild = true;
00115 }
00116 
00117 void JackSocketServerChannel::ClientKill(int fd)
00118 {
00119     pair<int, JackClientSocket*> elem = fSocketTable[fd];
00120     JackClientSocket* socket = elem.second;
00121     int refnum = elem.first;
00122 
00123     assert(socket);
00124     JackLog("JackSocketServerChannel::ClientKill ref = %d\n", refnum);
00125 
00126     if (refnum == -1) {  // Should never happen... correspond to a client that started the socket but never opened...
00127         JackLog("Client was not opened : probably correspond to server_check\n");
00128     } else {
00129         fServer->Notify(refnum, kDeadClient, 0);
00130     }
00131 
00132     fSocketTable.erase(fd);
00133     socket->Close();
00134     delete socket;
00135     fRebuild = true;
00136 }
00137 
00138 int JackSocketServerChannel::HandleRequest(int fd)
00139 {
00140     pair<int, JackClientSocket*> elem = fSocketTable[fd];
00141     JackClientSocket* socket = elem.second;
00142     assert(socket);
00143 
00144     // Read header
00145     JackRequest header;
00146     if (header.Read(socket) < 0) {
00147         jack_error("HandleRequest: cannot read header");
00148         return -1;
00149     }
00150 
00151     // Read data
00152     switch (header.fType) {
00153         
00154                 case JackRequest::kClientCheck: {
00155                 JackLog("JackRequest::kClientCheck\n");
00156                 JackClientCheckRequest req;
00157                 JackClientCheckResult res;
00158                 if (req.Read(socket) == 0)
00159                                         res.fResult = fServer->GetEngine()->ClientCheck(req.fName, res.fName, req.fProtocol, req.fOptions, &res.fStatus);
00160                 if (res.Write(socket) < 0)
00161                                         jack_error("JackRequest::kClientCheck write error name = %s", req.fName);
00162                 break;
00163             }
00164 
00165         case JackRequest::kClientOpen: {
00166                 JackLog("JackRequest::ClientOpen\n");
00167                 JackClientOpenRequest req;
00168                 JackClientOpenResult res;
00169                 if (req.Read(socket) == 0)
00170                                         ClientAdd(fd, req.fName, &res.fSharedEngine, &res.fSharedClient, &res.fSharedGraph, &res.fResult);
00171                                 if (res.Write(socket) < 0)
00172                                         jack_error("JackRequest::kClientOpen write error name = %s", req.fName);
00173                 break;
00174             }
00175 
00176         case JackRequest::kClientClose: {
00177                 JackLog("JackRequest::ClientClose\n");
00178                 JackClientCloseRequest req;
00179                 JackResult res;
00180                 if (req.Read(socket) == 0)
00181                                         res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum);
00182                                 if (res.Write(socket) < 0)
00183                                         jack_error("JackRequest::kClientClose write error ref = %d", req.fRefNum);
00184                 ClientRemove(fd, req.fRefNum);
00185                 break;
00186             }
00187 
00188         case JackRequest::kActivateClient: {
00189                 JackActivateRequest req;
00190                 JackResult res;
00191                 JackLog("JackRequest::ActivateClient\n");
00192                 if (req.Read(socket) == 0)
00193                                         res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum);
00194                                 if (res.Write(socket) < 0)
00195                                         jack_error("JackRequest::kActivateClient write error ref = %d", req.fRefNum);
00196                 break;
00197             }
00198 
00199         case JackRequest::kDeactivateClient: {
00200                 JackLog("JackRequest::DeactivateClient\n");
00201                 JackDeactivateRequest req;
00202                 JackResult res;
00203                 if (req.Read(socket) == 0)
00204                                         res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum);
00205                 if (res.Write(socket) < 0)
00206                                         jack_error("JackRequest::kDeactivateClient write error ref = %d", req.fRefNum);
00207                 break;
00208             }
00209 
00210         case JackRequest::kRegisterPort: {
00211                 JackLog("JackRequest::RegisterPort\n");
00212                 JackPortRegisterRequest req;
00213                 JackPortRegisterResult res;
00214                 if (req.Read(socket) == 0)
00215                                         res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fPortType, req.fFlags, req.fBufferSize, &res.fPortIndex);
00216                 if (res.Write(socket) < 0)
00217                                         jack_error("JackRequest::kRegisterPort write error ref = %d", req.fRefNum);
00218                 break;
00219             }
00220 
00221         case JackRequest::kUnRegisterPort: {
00222                 JackLog("JackRequest::UnRegisterPort\n");
00223                 JackPortUnRegisterRequest req;
00224                 JackResult res;
00225                 if (req.Read(socket) == 0)
00226                                         res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex);
00227                 if (res.Write(socket) < 0)
00228                                         jack_error("JackRequest::kUnRegisterPort write error ref = %d", req.fRefNum);
00229                 break;
00230             }
00231 
00232         case JackRequest::kConnectNamePorts: {
00233                 JackLog("JackRequest::ConnectPorts\n");
00234                 JackPortConnectNameRequest req;
00235                 JackResult res;
00236                 if (req.Read(socket) == 0)
00237                                         res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
00238                 if (res.Write(socket) < 0)
00239                                         jack_error("JackRequest::kConnectNamePorts write error ref = %d", req.fRefNum);
00240                 break;
00241             }
00242 
00243         case JackRequest::kDisconnectNamePorts: {
00244                 JackLog("JackRequest::DisconnectPorts\n");
00245                 JackPortDisconnectNameRequest req;
00246                 JackResult res;
00247                 if (req.Read(socket) == 0)
00248                                         res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
00249                 if (res.Write(socket) < 0)
00250                                         jack_error("JackRequest::kDisconnectNamePorts write error ref = %d", req.fRefNum);
00251                 break;
00252             }
00253 
00254         case JackRequest::kConnectPorts: {
00255                 JackLog("JackRequest::ConnectPorts\n");
00256                 JackPortConnectRequest req;
00257                 JackResult res;
00258                 if (req.Read(socket) == 0)
00259                                         res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
00260                 if (res.Write(socket) < 0)
00261                                         jack_error("JackRequest::kConnectPorts write error ref = %d", req.fRefNum);
00262                 break;
00263             }
00264 
00265         case JackRequest::kDisconnectPorts: {
00266                 JackLog("JackRequest::DisconnectPorts\n");
00267                 JackPortDisconnectRequest req;
00268                 JackResult res;
00269                 if (req.Read(socket) == 0)
00270                                         res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
00271                 if (res.Write(socket) < 0)
00272                                         jack_error("JackRequest::kDisconnectPorts write error ref = %d", req.fRefNum);
00273                 break;
00274             }
00275 
00276         case JackRequest::kSetBufferSize: {
00277                 JackLog("JackRequest::SetBufferSize\n");
00278                 JackSetBufferSizeRequest req;
00279                 JackResult res;
00280                 if (req.Read(socket) == 0)
00281                                         res.fResult = fServer->SetBufferSize(req.fBufferSize);
00282                 if (res.Write(socket) < 0)
00283                                         jack_error("JackRequest::kSetBufferSize write error");
00284                 break;
00285             }
00286 
00287         case JackRequest::kSetFreeWheel: {
00288                 JackLog("JackRequest::SetFreeWheel\n");
00289                 JackSetFreeWheelRequest req;
00290                 JackResult res;
00291                 if (req.Read(socket) == 0)
00292                                         res.fResult = fServer->SetFreewheel(req.fOnOff);
00293                 if (res.Write(socket) < 0)
00294                                         jack_error("JackRequest::kSetFreeWheel write error");
00295                 break;
00296             }
00297 
00298         case JackRequest::kReleaseTimebase: {
00299                 JackLog("JackRequest::kReleaseTimebase\n");
00300                 JackReleaseTimebaseRequest req;
00301                 JackResult res;
00302                 if (req.Read(socket) == 0)
00303                                         res.fResult = fServer->ReleaseTimebase(req.fRefNum);
00304                 if (res.Write(socket) < 0)
00305                                         jack_error("JackRequest::kReleaseTimebase write error ref = %d", req.fRefNum);
00306                 break;
00307             }
00308 
00309         case JackRequest::kSetTimebaseCallback: {
00310                 JackLog("JackRequest::kSetTimebaseCallback\n");
00311                 JackSetTimebaseCallbackRequest req;
00312                 JackResult res;
00313                 if (req.Read(socket) == 0)
00314                                         res.fResult = fServer->SetTimebaseCallback(req.fRefNum, req.fConditionnal);
00315                 if (res.Write(socket) < 0)
00316                                         jack_error("JackRequest::kSetTimebaseCallback write error ref = %d", req.fRefNum);
00317                 break;
00318             }
00319                         
00320                 case JackRequest::kGetInternalClientName: {
00321                 JackLog("JackRequest::kGetInternalClientName\n");
00322                 JackGetInternalClientNameRequest req;
00323                 JackGetInternalClientNameResult res;
00324                 if (req.Read(socket) == 0)
00325                                         res.fResult = fServer->GetEngine()->GetInternalClientName(req.fIntRefNum, res.fName);
00326                if (res.Write(socket) < 0)
00327                                         jack_error("JackRequest::kGetInternalClientName write error ref = %d", req.fRefNum);
00328                 break;
00329             }
00330                         
00331                 case JackRequest::kInternalClientHandle: {
00332                 JackLog("JackRequest::kInternalClientHandle\n");
00333                 JackInternalClientHandleRequest req;
00334                 JackInternalClientHandleResult res;
00335                 if (req.Read(socket) == 0)
00336                                         res.fResult = fServer->GetEngine()->InternalClientHandle(req.fName, &res.fStatus, &res.fIntRefNum);
00337                 if (res.Write(socket) < 0)
00338                                         jack_error("JackRequest::kInternalClientHandle write error ref = %d", req.fRefNum);
00339                 break;
00340             }
00341                         
00342                 case JackRequest::kInternalClientLoad: {
00343                 JackLog("JackRequest::kInternalClientLoad\n");
00344                 JackInternalClientLoadRequest req;
00345                 JackInternalClientLoadResult res;
00346                 if (req.Read(socket) == 0)
00347                                         res.fResult = fServer->InternalClientLoad(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, &res.fStatus);
00348                                 if (res.Write(socket) < 0)
00349                                         jack_error("JackRequest::kInternalClientLoad write error name = %s", req.fName);
00350                 break;
00351             }
00352                         
00353                 case JackRequest::kInternalClientUnload: {
00354                 JackLog("JackRequest::kInternalClientUnload\n");
00355                 JackInternalClientUnloadRequest req;
00356                 JackInternalClientUnloadResult res;
00357                 if (req.Read(socket) == 0)
00358                                         res.fResult = fServer->GetEngine()->InternalClientUnload(req.fIntRefNum, &res.fStatus);
00359                 if (res.Write(socket) < 0)
00360                                         jack_error("JackRequest::kInternalClientUnload write error ref = %d", req.fRefNum);
00361                 break;
00362             }
00363 
00364         case JackRequest::kNotification: {
00365                 JackLog("JackRequest::Notification\n");
00366                 JackClientNotificationRequest req;
00367                                 if (req.Read(socket) == 0)
00368                                         fServer->Notify(req.fRefNum, req.fNotify, req.fValue);
00369                 break;
00370             }
00371 
00372         default:
00373             JackLog("Unknown request %ld\n", header.fType);
00374             break;
00375     }
00376 
00377     return 0;
00378 }
00379 
00380 void JackSocketServerChannel::BuildPoolTable()
00381 {
00382     if (fRebuild) {
00383         fRebuild = false;
00384         delete[] fPollTable;
00385         fPollTable = new pollfd[fSocketTable.size() + 1];
00386 
00387         JackLog("JackSocketServerChannel::BuildPoolTable size = %d\n", fSocketTable.size() + 1);
00388 
00389         // First fd is the server request socket
00390         fPollTable[0].fd = fRequestListenSocket.GetFd();
00391         fPollTable[0].events = POLLIN | POLLERR;
00392 
00393         // Next fd for clients
00394         map<int, pair<int, JackClientSocket*> >::iterator it;
00395         int i;
00396 
00397         for (i = 1, it = fSocketTable.begin(); it != fSocketTable.end(); it++, i++) {
00398             JackLog("fSocketTable i = %ld fd = %ld\n", i, it->first);
00399             fPollTable[i].fd = it->first;
00400             fPollTable[i].events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
00401         }
00402     }
00403 }
00404 
00405 bool JackSocketServerChannel::Execute()
00406 {
00407     // Global poll
00408     if ((poll(fPollTable, fSocketTable.size() + 1, 10000) < 0) && (errno != EINTR)) {
00409         jack_error("Engine poll failed err = %s request thread quits...", strerror(errno));
00410         return false;
00411     } else {
00412 
00413         // Poll all clients
00414         for (unsigned int i = 1; i < fSocketTable.size() + 1; i++) {
00415             int fd = fPollTable[i].fd;
00416             JackLog("fPollTable i = %ld fd = %ld\n", i, fd);
00417             if (fPollTable[i].revents & ~POLLIN) {
00418                 jack_error("Poll client error err = %s", strerror(errno));
00419                 ClientKill(fd);
00420             } else if (fPollTable[i].revents & POLLIN) {
00421                 if (HandleRequest(fd) < 0) {
00422                     jack_error("Could not handle external client request");
00423                     //ClientRemove(fd); TO CHECK
00424                 }
00425             }
00426         }
00427 
00428         // Check the server request socket */
00429         if (fPollTable[0].revents & POLLERR) {
00430             jack_error("Error on server request socket err = %s", strerror(errno));
00431             //return false; TO CHECK
00432         }
00433 
00434         if (fPollTable[0].revents & POLLIN) {
00435             ClientCreate();
00436         }
00437     }
00438 
00439     BuildPoolTable();
00440     return true;
00441 }
00442 
00443 } // end of namespace
00444 
00445 

Generated on Thu Feb 14 11:16:02 2008 for Jackdmp by  doxygen 1.5.1