JackSocketServerChannel.cpp

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

Generated on Wed Jan 10 11:42:46 2007 for Jackdmp by  doxygen 1.4.5