Add innosetup files
[jack2.git] / posix / JackSocketServerChannel.cpp
blobaba7bf230ee3d091bbf42d78e8e09dee005f1366
1 /*
2 Copyright (C) 2004-2008 Grame
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 #include "JackSocketServerChannel.h"
21 #include "JackRequest.h"
22 #include "JackServer.h"
23 #include "JackLockedEngine.h"
24 #include "JackGlobals.h"
25 #include "JackClient.h"
26 #include "JackTools.h"
27 #include "JackNotification.h"
28 #include "JackException.h"
30 #include <assert.h>
31 #include <signal.h>
33 using namespace std;
35 namespace Jack
38 JackSocketServerChannel::JackSocketServerChannel():
39 fThread(this), fDecoder(NULL)
41 fPollTable = NULL;
42 fRebuild = true;
45 JackSocketServerChannel::~JackSocketServerChannel()
47 delete[] fPollTable;
50 int JackSocketServerChannel::Open(const char* server_name, JackServer* server)
52 jack_log("JackSocketServerChannel::Open");
54 // Prepare request socket
55 if (fRequestListenSocket.Bind(jack_server_dir, server_name, 0) < 0) {
56 jack_log("JackSocketServerChannel::Open : cannot create result listen socket");
57 return -1;
60 // Prepare for poll
61 BuildPoolTable();
63 fDecoder = new JackRequestDecoder(server, this);
64 fServer = server;
65 return 0;
68 void JackSocketServerChannel::Close()
70 fRequestListenSocket.Close();
72 // Close remaining client sockets
73 std::map<int, std::pair<int, JackClientSocket*> >::iterator it;
75 for (it = fSocketTable.begin(); it != fSocketTable.end(); it++) {
76 pair<int, JackClientSocket*> elem = (*it).second;
77 JackClientSocket* socket = elem.second;
78 assert(socket);
79 socket->Close();
80 delete socket;
83 delete fDecoder;
84 fDecoder = NULL;
87 int JackSocketServerChannel::Start()
89 if (fThread.Start() != 0) {
90 jack_error("Cannot start Jack server listener");
91 return -1;
92 } else {
93 return 0;
97 void JackSocketServerChannel::Stop()
99 fThread.Stop();
102 void JackSocketServerChannel::ClientCreate()
104 jack_log("JackSocketServerChannel::ClientCreate socket");
105 JackClientSocket* socket = fRequestListenSocket.Accept();
106 if (socket) {
107 fSocketTable[socket->GetFd()] = make_pair(-1, socket);
108 fRebuild = true;
109 } else {
110 jack_error("Client socket cannot be created");
114 int JackSocketServerChannel::GetFd(JackClientSocket* socket_aux)
116 std::map<int, std::pair<int, JackClientSocket*> >::iterator it;
118 for (it = fSocketTable.begin(); it != fSocketTable.end(); it++) {
119 pair<int, JackClientSocket*> elem = (*it).second;
120 JackClientSocket* socket = elem.second;
121 if (socket_aux == socket) {
122 return (*it).first;
125 return -1;
128 void JackSocketServerChannel::ClientAdd(detail::JackChannelTransactionInterface* socket_aux, JackClientOpenRequest* req, JackClientOpenResult *res)
130 int refnum = -1;
131 res->fResult = fServer->GetEngine()->ClientExternalOpen(req->fName, req->fPID, req->fUUID, &refnum, &res->fSharedEngine, &res->fSharedClient, &res->fSharedGraph);
132 if (res->fResult == 0) {
133 JackClientSocket* socket = dynamic_cast<JackClientSocket*>(socket_aux);
134 assert(socket);
135 int fd = GetFd(socket);
136 assert(fd >= 0);
137 fSocketTable[fd].first = refnum;
138 fRebuild = true;
139 jack_log("JackSocketServerChannel::ClientAdd ref = %d fd = %d", refnum, fd);
140 #ifdef __APPLE__
141 int on = 1;
142 if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (const char*)&on, sizeof(on)) < 0) {
143 jack_log("JackSocketServerChannel::ClientAdd : setsockopt SO_NOSIGPIPE fd = %ld err = %s", fd, strerror(errno));
145 #endif
146 } else {
147 jack_error("Cannot create new client");
151 void JackSocketServerChannel::ClientRemove(detail::JackChannelTransactionInterface* socket_aux, int refnum)
153 JackClientSocket* socket = dynamic_cast<JackClientSocket*>(socket_aux);
154 assert(socket);
155 int fd = GetFd(socket);
156 assert(fd >= 0);
158 jack_log("JackSocketServerChannel::ClientRemove ref = %d fd = %d", refnum, fd);
159 fSocketTable.erase(fd);
160 socket->Close();
161 delete socket;
162 fRebuild = true;
165 void JackSocketServerChannel::ClientKill(int fd)
167 pair<int, JackClientSocket*> elem = fSocketTable[fd];
168 JackClientSocket* socket = elem.second;
169 int refnum = elem.first;
170 assert(socket);
172 jack_log("JackSocketServerChannel::ClientKill ref = %d fd = %d", refnum, fd);
173 if (refnum == -1) { // Should never happen... correspond to a client that started the socket but never opened...
174 jack_log("Client was not opened : probably correspond to server_check");
175 } else {
176 fServer->GetEngine()->ClientKill(refnum);
179 fSocketTable.erase(fd);
180 socket->Close();
181 delete socket;
182 fRebuild = true;
185 void JackSocketServerChannel::BuildPoolTable()
187 if (fRebuild) {
188 fRebuild = false;
189 delete[] fPollTable;
190 fPollTable = new pollfd[fSocketTable.size() + 1];
192 jack_log("JackSocketServerChannel::BuildPoolTable size = %d", fSocketTable.size() + 1);
194 // First fd is the server request socket
195 fPollTable[0].fd = fRequestListenSocket.GetFd();
196 fPollTable[0].events = POLLIN | POLLERR;
198 // Next fd for clients
199 map<int, pair<int, JackClientSocket*> >::iterator it;
200 int i;
202 for (i = 1, it = fSocketTable.begin(); it != fSocketTable.end(); it++, i++) {
203 jack_log("JackSocketServerChannel::BuildPoolTable fSocketTable i = %ld fd = %ld", i, it->first);
204 fPollTable[i].fd = it->first;
205 fPollTable[i].events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
210 bool JackSocketServerChannel::Init()
212 sigset_t set;
213 sigemptyset(&set);
214 sigaddset(&set, SIGPIPE);
215 pthread_sigmask(SIG_BLOCK, &set, 0);
216 return true;
219 bool JackSocketServerChannel::Execute()
221 try {
223 // Global poll
224 if ((poll(fPollTable, fSocketTable.size() + 1, 10000) < 0) && (errno != EINTR)) {
225 jack_error("JackSocketServerChannel::Execute : engine poll failed err = %s request thread quits...", strerror(errno));
226 return false;
227 } else {
229 // Poll all clients
230 for (unsigned int i = 1; i < fSocketTable.size() + 1; i++) {
231 int fd = fPollTable[i].fd;
232 if (fPollTable[i].revents & ~POLLIN) {
233 jack_log("JackSocketServerChannel::Execute : poll client error err = %s", strerror(errno));
234 ClientKill(fd);
235 } else if (fPollTable[i].revents & POLLIN) {
236 JackClientSocket* socket = fSocketTable[fd].second;
237 // Decode header
238 JackRequest header;
239 if (header.Read(socket) < 0) {
240 jack_log("JackSocketServerChannel::Execute : cannot decode header");
241 ClientKill(fd);
242 // Decode request
243 } else {
244 // Result is not needed here
245 fDecoder->HandleRequest(socket, header.fType);
250 // Check the server request socket */
251 if (fPollTable[0].revents & POLLERR) {
252 jack_error("Error on server request socket err = %s", strerror(errno));
255 if (fPollTable[0].revents & POLLIN) {
256 ClientCreate();
260 BuildPoolTable();
261 return true;
263 } catch (JackQuitException& e) {
264 jack_log("JackSocketServerChannel::Execute : JackQuitException");
265 return false;
269 } // end of namespace