Jack2 1.9.10

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), fDecoder(NULL)
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     
00064     fDecoder = new JackRequestDecoder(server, this);
00065     fServer = server;
00066     return 0;
00067 }
00068 
00069 void JackSocketServerChannel::Close()
00070 {
00071    fRequestListenSocket.Close();
00072 
00073     // Close remaining client sockets
00074     std::map<int, std::pair<int, JackClientSocket*> >::iterator it;
00075 
00076     for (it = fSocketTable.begin(); it != fSocketTable.end(); it++) {
00077         pair<int, JackClientSocket*> elem = (*it).second;
00078         JackClientSocket* socket = elem.second;
00079         assert(socket);
00080         socket->Close();
00081         delete socket;
00082     }
00083 
00084     delete fDecoder;
00085     fDecoder = NULL;
00086 }
00087 
00088 int JackSocketServerChannel::Start()
00089 {
00090     if (fThread.Start() != 0) {
00091         jack_error("Cannot start Jack server listener");
00092         return -1;
00093     } else {
00094         return 0;
00095     }
00096 }
00097 
00098 void JackSocketServerChannel::Stop()
00099 {
00100     fThread.Stop();
00101 }
00102 
00103 void JackSocketServerChannel::ClientCreate()
00104 {
00105     jack_log("JackSocketServerChannel::ClientCreate socket");
00106     JackClientSocket* socket = fRequestListenSocket.Accept();
00107     if (socket) {
00108         fSocketTable[socket->GetFd()] = make_pair(-1, socket);
00109         fRebuild = true;
00110     } else {
00111         jack_error("Client socket cannot be created");
00112     }
00113 }
00114 
00115 int JackSocketServerChannel::GetFd(JackClientSocket* socket_aux)
00116 {
00117     std::map<int, std::pair<int, JackClientSocket*> >::iterator it;
00118 
00119     for (it = fSocketTable.begin(); it != fSocketTable.end(); it++) {
00120         pair<int, JackClientSocket*> elem = (*it).second;
00121         JackClientSocket* socket = elem.second;
00122         if (socket_aux == socket) {
00123             return (*it).first;
00124         }
00125     }
00126     return -1;
00127 }
00128 
00129 void JackSocketServerChannel::ClientAdd(detail::JackChannelTransactionInterface* socket_aux, JackClientOpenRequest* req, JackClientOpenResult *res)
00130 {
00131     int refnum = -1;
00132     res->fResult = fServer->GetEngine()->ClientExternalOpen(req->fName, req->fPID, req->fUUID, &refnum, &res->fSharedEngine, &res->fSharedClient, &res->fSharedGraph);
00133     if (res->fResult == 0) {
00134         JackClientSocket* socket = dynamic_cast<JackClientSocket*>(socket_aux);
00135         assert(socket);
00136         int fd = GetFd(socket);
00137         assert(fd >= 0);
00138         fSocketTable[fd].first = refnum;
00139         fRebuild = true;
00140         jack_log("JackSocketServerChannel::ClientAdd ref = %d fd = %d", refnum, fd);
00141     #ifdef __APPLE__
00142         int on = 1;
00143         if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) {
00144             jack_log("JackSocketServerChannel::ClientAdd : setsockopt SO_NOSIGPIPE fd = %ld err = %s", fd, strerror(errno));
00145         }
00146     #endif
00147     } else {
00148         jack_error("Cannot create new client");
00149     }
00150 }
00151 
00152 void JackSocketServerChannel::ClientRemove(detail::JackChannelTransactionInterface* socket_aux, int refnum)
00153 {
00154     JackClientSocket* socket = dynamic_cast<JackClientSocket*>(socket_aux);
00155     assert(socket);
00156     int fd = GetFd(socket);
00157     assert(fd >= 0);
00158 
00159     jack_log("JackSocketServerChannel::ClientRemove ref = %d fd = %d", refnum, fd);
00160     fSocketTable.erase(fd);
00161     socket->Close();
00162     delete socket;
00163     fRebuild = true;
00164 }
00165 
00166 void JackSocketServerChannel::ClientKill(int fd)
00167 {
00168     pair<int, JackClientSocket*> elem = fSocketTable[fd];
00169     JackClientSocket* socket = elem.second;
00170     int refnum = elem.first;
00171     assert(socket);
00172     
00173     jack_log("JackSocketServerChannel::ClientKill ref = %d fd = %d", refnum, fd);
00174     if (refnum == -1) {  // Should never happen... correspond to a client that started the socket but never opened...
00175         jack_log("Client was not opened : probably correspond to server_check");
00176     } else {
00177         fServer->GetEngine()->ClientKill(refnum);
00178     }
00179    
00180     fSocketTable.erase(fd);
00181     socket->Close();
00182     delete socket;
00183     fRebuild = true;
00184 }
00185 
00186 void JackSocketServerChannel::BuildPoolTable()
00187 {
00188     if (fRebuild) {
00189         fRebuild = false;
00190         delete[] fPollTable;
00191         fPollTable = new pollfd[fSocketTable.size() + 1];
00192 
00193         jack_log("JackSocketServerChannel::BuildPoolTable size = %d", fSocketTable.size() + 1);
00194 
00195         // First fd is the server request socket
00196         fPollTable[0].fd = fRequestListenSocket.GetFd();
00197         fPollTable[0].events = POLLIN | POLLERR;
00198 
00199         // Next fd for clients
00200         map<int, pair<int, JackClientSocket*> >::iterator it;
00201         int i;
00202 
00203         for (i = 1, it = fSocketTable.begin(); it != fSocketTable.end(); it++, i++) {
00204             jack_log("JackSocketServerChannel::BuildPoolTable fSocketTable i = %ld fd = %ld", i, it->first);
00205             fPollTable[i].fd = it->first;
00206             fPollTable[i].events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
00207         }
00208     }
00209 }
00210 
00211 bool JackSocketServerChannel::Init()
00212 {
00213     sigset_t set;
00214     sigemptyset(&set);
00215     sigaddset(&set, SIGPIPE);
00216     pthread_sigmask(SIG_BLOCK, &set, 0);
00217     return true;
00218 }
00219 
00220 bool JackSocketServerChannel::Execute()
00221 {
00222     try {
00223 
00224         // Global poll
00225         if ((poll(fPollTable, fSocketTable.size() + 1, 10000) < 0) && (errno != EINTR)) {
00226             jack_error("JackSocketServerChannel::Execute : engine poll failed err = %s request thread quits...", strerror(errno));
00227             return false;
00228         } else {
00229 
00230             // Poll all clients
00231             for (unsigned int i = 1; i < fSocketTable.size() + 1; i++) {
00232                 int fd = fPollTable[i].fd;
00233                 jack_log("JackSocketServerChannel::Execute : fPollTable i = %ld fd = %ld", i, fd);
00234                 if (fPollTable[i].revents & ~POLLIN) {
00235                     jack_log("JackSocketServerChannel::Execute : poll client error err = %s", strerror(errno));
00236                     ClientKill(fd);
00237                 } else if (fPollTable[i].revents & POLLIN) {
00238                     JackClientSocket* socket = fSocketTable[fd].second;
00239                     // Decode header
00240                     JackRequest header;
00241                     if (header.Read(socket) < 0) {
00242                         jack_log("JackSocketServerChannel::Execute : cannot decode header");
00243                         ClientKill(fd);
00244                     // Decode request
00245                     } else {
00246                         // Result is not needed here
00247                         fDecoder->HandleRequest(socket, header.fType);
00248                     }
00249                 }
00250             }
00251 
00252             // Check the server request socket */
00253             if (fPollTable[0].revents & POLLERR) {
00254                 jack_error("Error on server request socket err = %s", strerror(errno));
00255             }
00256 
00257             if (fPollTable[0].revents & POLLIN) {
00258                 ClientCreate();
00259             }
00260         }
00261 
00262         BuildPoolTable();
00263         return true;
00264 
00265     } catch (JackQuitException& e) {
00266         jack_log("JackSocketServerChannel::Execute : JackQuitException");
00267         return false;
00268     }
00269 }
00270 
00271 } // end of namespace
00272 
00273