Correct netjack2 socket init code.
[jack2.git] / posix / JackSocketServerChannel.cpp
blobd2a59b335d8c35f34102238052653ea9584211e0
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 "JackServerGlobals.h"
26 #include "JackClient.h"
27 #include "JackTools.h"
28 #include "JackNotification.h"
29 #include "JackException.h"
31 #include <assert.h>
32 #include <signal.h>
34 using namespace std;
36 namespace Jack
39 JackSocketServerChannel::JackSocketServerChannel():
40 fThread(this)
42 fPollTable = NULL;
43 fRebuild = true;
46 JackSocketServerChannel::~JackSocketServerChannel()
48 delete[] fPollTable;
51 int JackSocketServerChannel::Open(const char* server_name, JackServer* server)
53 jack_log("JackSocketServerChannel::Open");
55 // Prepare request socket
56 if (fRequestListenSocket.Bind(jack_server_dir, server_name, 0) < 0) {
57 jack_log("JackSocketServerChannel::Open : cannot create result listen socket");
58 return -1;
61 // Prepare for poll
62 BuildPoolTable();
63 fServer = server;
64 return 0;
67 void JackSocketServerChannel::Close()
69 fThread.Stop();
70 fRequestListenSocket.Close();
72 // Close remaining client sockets
73 std::map<int, std::pair<int, JackClientSocket*> >::iterator it;
74 for (it = fSocketTable.begin(); it != fSocketTable.end(); it++) {
75 pair<int, JackClientSocket*> elem = (*it).second;
76 JackClientSocket* socket = elem.second;
77 assert(socket);
78 socket->Close();
79 delete socket;
83 int JackSocketServerChannel::Start()
85 if (fThread.Start() != 0) {
86 jack_error("Cannot start Jack server listener");
87 return -1;
90 return 0;
93 void JackSocketServerChannel::ClientCreate()
95 jack_log("JackSocketServerChannel::ClientCreate socket");
96 JackClientSocket* socket = fRequestListenSocket.Accept();
97 if (socket) {
98 fSocketTable[socket->GetFd()] = make_pair( -1, socket);
99 fRebuild = true;
100 } else {
101 jack_error("Client socket cannot be created");
105 void JackSocketServerChannel::ClientAdd(int fd, char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result)
107 jack_log("JackSocketServerChannel::ClientAdd");
108 int refnum = -1;
109 *result = fServer->GetEngine()->ClientExternalOpen(name, pid, &refnum, shared_engine, shared_client, shared_graph);
110 if (*result == 0) {
111 fSocketTable[fd].first = refnum;
112 fRebuild = true;
113 } else {
114 jack_error("Cannot create new client");
118 void JackSocketServerChannel::ClientRemove(int fd, int refnum)
120 pair<int, JackClientSocket*> elem = fSocketTable[fd];
121 JackClientSocket* socket = elem.second;
122 assert(socket);
123 jack_log("JackSocketServerChannel::ClientRemove ref = %d", refnum);
124 fSocketTable.erase(fd);
125 socket->Close();
126 delete socket;
127 fRebuild = true;
130 void JackSocketServerChannel::ClientKill(int fd)
132 pair<int, JackClientSocket*> elem = fSocketTable[fd];
133 JackClientSocket* socket = elem.second;
134 int refnum = elem.first;
136 assert(socket);
137 jack_log("JackSocketServerChannel::ClientKill ref = %d", refnum);
139 if (refnum == -1) { // Should never happen... correspond to a client that started the socket but never opened...
140 jack_log("Client was not opened : probably correspond to server_check");
141 } else {
142 fServer->ClientKill(refnum);
145 fSocketTable.erase(fd);
146 socket->Close();
147 delete socket;
148 fRebuild = true;
151 bool JackSocketServerChannel::HandleRequest(int fd)
153 pair<int, JackClientSocket*> elem = fSocketTable[fd];
154 JackClientSocket* socket = elem.second;
155 assert(socket);
157 // Read header
158 JackRequest header;
159 if (header.Read(socket) < 0) {
160 jack_log("HandleRequest: cannot read header");
161 ClientKill(fd); // TO CHECK SOLARIS
162 return false;
165 // Read data
166 switch (header.fType) {
168 case JackRequest::kClientCheck: {
169 jack_log("JackRequest::ClientCheck");
170 JackClientCheckRequest req;
171 JackClientCheckResult res;
172 if (req.Read(socket) == 0)
173 res.fResult = fServer->GetEngine()->ClientCheck(req.fName, res.fName, req.fProtocol, req.fOptions, &res.fStatus);
174 if (res.Write(socket) < 0)
175 jack_error("JackRequest::ClientCheck write error name = %s", req.fName);
176 break;
179 case JackRequest::kClientOpen: {
180 jack_log("JackRequest::ClientOpen");
181 JackClientOpenRequest req;
182 JackClientOpenResult res;
183 if (req.Read(socket) == 0)
184 ClientAdd(fd, req.fName, req.fPID, &res.fSharedEngine, &res.fSharedClient, &res.fSharedGraph, &res.fResult);
185 if (res.Write(socket) < 0)
186 jack_error("JackRequest::ClientOpen write error name = %s", req.fName);
187 break;
190 case JackRequest::kClientClose: {
191 jack_log("JackRequest::ClientClose");
192 JackClientCloseRequest req;
193 JackResult res;
194 if (req.Read(socket) == 0)
195 res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum);
196 if (res.Write(socket) < 0)
197 jack_error("JackRequest::ClientClose write error ref = %d", req.fRefNum);
198 ClientRemove(fd, req.fRefNum);
199 break;
202 case JackRequest::kActivateClient: {
203 JackActivateRequest req;
204 JackResult res;
205 jack_log("JackRequest::ActivateClient");
206 if (req.Read(socket) == 0)
207 res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime);
208 if (res.Write(socket) < 0)
209 jack_error("JackRequest::ActivateClient write error ref = %d", req.fRefNum);
210 break;
213 case JackRequest::kDeactivateClient: {
214 jack_log("JackRequest::DeactivateClient");
215 JackDeactivateRequest req;
216 JackResult res;
217 if (req.Read(socket) == 0)
218 res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum);
219 if (res.Write(socket) < 0)
220 jack_error("JackRequest::DeactivateClient write error ref = %d", req.fRefNum);
221 break;
224 case JackRequest::kRegisterPort: {
225 jack_log("JackRequest::RegisterPort");
226 JackPortRegisterRequest req;
227 JackPortRegisterResult res;
228 if (req.Read(socket) == 0)
229 res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fPortType, req.fFlags, req.fBufferSize, &res.fPortIndex);
230 if (res.Write(socket) < 0)
231 jack_error("JackRequest::RegisterPort write error ref = %d", req.fRefNum);
232 break;
235 case JackRequest::kUnRegisterPort: {
236 jack_log("JackRequest::UnRegisterPort");
237 JackPortUnRegisterRequest req;
238 JackResult res;
239 if (req.Read(socket) == 0)
240 res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex);
241 if (res.Write(socket) < 0)
242 jack_error("JackRequest::UnRegisterPort write error ref = %d", req.fRefNum);
243 break;
246 case JackRequest::kConnectNamePorts: {
247 jack_log("JackRequest::ConnectNamePorts");
248 JackPortConnectNameRequest req;
249 JackResult res;
250 if (req.Read(socket) == 0)
251 res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
252 if (res.Write(socket) < 0)
253 jack_error("JackRequest::ConnectNamePorts write error ref = %d", req.fRefNum);
254 break;
257 case JackRequest::kDisconnectNamePorts: {
258 jack_log("JackRequest::DisconnectNamePorts");
259 JackPortDisconnectNameRequest req;
260 JackResult res;
261 if (req.Read(socket) == 0)
262 res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
263 if (res.Write(socket) < 0)
264 jack_error("JackRequest::DisconnectNamePorts write error ref = %d", req.fRefNum);
265 break;
268 case JackRequest::kConnectPorts: {
269 jack_log("JackRequest::ConnectPorts");
270 JackPortConnectRequest req;
271 JackResult res;
272 if (req.Read(socket) == 0)
273 res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
274 if (res.Write(socket) < 0)
275 jack_error("JackRequest::ConnectPorts write error ref = %d", req.fRefNum);
276 break;
279 case JackRequest::kDisconnectPorts: {
280 jack_log("JackRequest::DisconnectPorts");
281 JackPortDisconnectRequest req;
282 JackResult res;
283 if (req.Read(socket) == 0)
284 res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
285 if (res.Write(socket) < 0)
286 jack_error("JackRequest::DisconnectPorts write error ref = %d", req.fRefNum);
287 break;
290 case JackRequest::kPortRename: {
291 jack_log("JackRequest::PortRename");
292 JackPortRenameRequest req;
293 JackResult res;
294 if (req.Read(socket) == 0)
295 res.fResult = fServer->GetEngine()->PortRename(req.fRefNum, req.fPort, req.fName);
296 if (res.Write(socket) < 0)
297 jack_error("JackRequest::PortRename write error ref = %d", req.fRefNum);
298 break;
301 case JackRequest::kSetBufferSize: {
302 jack_log("JackRequest::SetBufferSize");
303 JackSetBufferSizeRequest req;
304 JackResult res;
305 if (req.Read(socket) == 0)
306 res.fResult = fServer->SetBufferSize(req.fBufferSize);
307 if (res.Write(socket) < 0)
308 jack_error("JackRequest::SetBufferSize write error");
309 break;
312 case JackRequest::kSetFreeWheel: {
313 jack_log("JackRequest::SetFreeWheel");
314 JackSetFreeWheelRequest req;
315 JackResult res;
316 if (req.Read(socket) == 0)
317 res.fResult = fServer->SetFreewheel(req.fOnOff);
318 if (res.Write(socket) < 0)
319 jack_error("JackRequest::SetFreeWheel write error");
320 break;
323 case JackRequest::kReleaseTimebase: {
324 jack_log("JackRequest::ReleaseTimebase");
325 JackReleaseTimebaseRequest req;
326 JackResult res;
327 if (req.Read(socket) == 0)
328 res.fResult = fServer->ReleaseTimebase(req.fRefNum);
329 if (res.Write(socket) < 0)
330 jack_error("JackRequest::ReleaseTimebase write error ref = %d", req.fRefNum);
331 break;
334 case JackRequest::kSetTimebaseCallback: {
335 jack_log("JackRequest::SetTimebaseCallback");
336 JackSetTimebaseCallbackRequest req;
337 JackResult res;
338 if (req.Read(socket) == 0)
339 res.fResult = fServer->SetTimebaseCallback(req.fRefNum, req.fConditionnal);
340 if (res.Write(socket) < 0)
341 jack_error("JackRequest::SetTimebaseCallback write error ref = %d", req.fRefNum);
342 break;
345 case JackRequest::kGetInternalClientName: {
346 jack_log("JackRequest::GetInternalClientName");
347 JackGetInternalClientNameRequest req;
348 JackGetInternalClientNameResult res;
349 if (req.Read(socket) == 0)
350 res.fResult = fServer->GetEngine()->GetInternalClientName(req.fIntRefNum, res.fName);
351 if (res.Write(socket) < 0)
352 jack_error("JackRequest::GetInternalClientName write error ref = %d", req.fRefNum);
353 break;
356 case JackRequest::kInternalClientHandle: {
357 jack_log("JackRequest::InternalClientHandle");
358 JackInternalClientHandleRequest req;
359 JackInternalClientHandleResult res;
360 if (req.Read(socket) == 0)
361 res.fResult = fServer->GetEngine()->InternalClientHandle(req.fName, &res.fStatus, &res.fIntRefNum);
362 if (res.Write(socket) < 0)
363 jack_error("JackRequest::InternalClientHandle write error ref = %d", req.fRefNum);
364 break;
367 case JackRequest::kInternalClientLoad: {
368 jack_log("JackRequest::InternalClientLoad");
369 JackInternalClientLoadRequest req;
370 JackInternalClientLoadResult res;
371 if (req.Read(socket) == 0)
372 res.fResult = fServer->InternalClientLoad(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, &res.fStatus);
373 if (res.Write(socket) < 0)
374 jack_error("JackRequest::InternalClientLoad write error name = %s", req.fName);
375 break;
378 case JackRequest::kInternalClientUnload: {
379 jack_log("JackRequest::InternalClientUnload");
380 JackInternalClientUnloadRequest req;
381 JackInternalClientUnloadResult res;
382 if (req.Read(socket) == 0)
383 res.fResult = fServer->GetEngine()->InternalClientUnload(req.fIntRefNum, &res.fStatus);
384 if (res.Write(socket) < 0)
385 jack_error("JackRequest::InternalClientUnload write error ref = %d", req.fRefNum);
386 break;
389 case JackRequest::kNotification: {
390 jack_log("JackRequest::Notification");
391 JackClientNotificationRequest req;
392 if (req.Read(socket) == 0) {
393 if (req.fNotify == kQUIT) {
394 jack_log("JackRequest::Notification kQUIT");
395 throw JackQuitException();
396 } else {
397 fServer->Notify(req.fRefNum, req.fNotify, req.fValue);
400 break;
403 default:
404 jack_error("Unknown request %ld", header.fType);
405 break;
408 return true;
411 void JackSocketServerChannel::BuildPoolTable()
413 if (fRebuild) {
414 fRebuild = false;
415 delete[] fPollTable;
416 fPollTable = new pollfd[fSocketTable.size() + 1];
418 jack_log("JackSocketServerChannel::BuildPoolTable size = %d", fSocketTable.size() + 1);
420 // First fd is the server request socket
421 fPollTable[0].fd = fRequestListenSocket.GetFd();
422 fPollTable[0].events = POLLIN | POLLERR;
424 // Next fd for clients
425 map<int, pair<int, JackClientSocket*> >::iterator it;
426 int i;
428 for (i = 1, it = fSocketTable.begin(); it != fSocketTable.end(); it++, i++) {
429 jack_log("fSocketTable i = %ld fd = %ld", i, it->first);
430 fPollTable[i].fd = it->first;
431 fPollTable[i].events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
436 bool JackSocketServerChannel::Init()
438 sigset_t set;
439 sigemptyset(&set);
440 sigaddset(&set, SIGPIPE);
441 pthread_sigmask(SIG_BLOCK, &set, 0);
442 return true;
445 bool JackSocketServerChannel::Execute()
447 try {
449 // Global poll
450 if ((poll(fPollTable, fSocketTable.size() + 1, 10000) < 0) && (errno != EINTR)) {
451 jack_error("Engine poll failed err = %s request thread quits...", strerror(errno));
452 return false;
453 } else {
455 // Poll all clients
456 for (unsigned int i = 1; i < fSocketTable.size() + 1; i++) {
457 int fd = fPollTable[i].fd;
458 jack_log("fPollTable i = %ld fd = %ld", i, fd);
459 if (fPollTable[i].revents & ~POLLIN) {
460 jack_log("Poll client error err = %s", strerror(errno));
461 ClientKill(fd);
462 } else if (fPollTable[i].revents & POLLIN) {
463 if (!HandleRequest(fd))
464 jack_log("Could not handle external client request");
468 // Check the server request socket */
469 if (fPollTable[0].revents & POLLERR)
470 jack_error("Error on server request socket err = %s", strerror(errno));
472 if (fPollTable[0].revents & POLLIN)
473 ClientCreate();
476 BuildPoolTable();
477 return true;
479 } catch (JackQuitException& e) {
480 jack_log("JackMachServerChannel::Execute JackQuitException");
481 return false;
485 } // end of namespace