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"
39 JackSocketServerChannel::JackSocketServerChannel():
46 JackSocketServerChannel::~JackSocketServerChannel()
51 int JackSocketServerChannel::Open(
const char* server_name, JackServer* server)
53 jack_log(
"JackSocketServerChannel::Open");
56 if (fRequestListenSocket.Bind(jack_server_dir, server_name, 0) < 0) {
57 jack_log(
"JackSocketServerChannel::Open : cannot create result listen socket");
67 void JackSocketServerChannel::Close()
69 fRequestListenSocket.Close();
72 std::map<int, std::pair<int, JackClientSocket*> >::iterator it;
73 for (it = fSocketTable.begin(); it != fSocketTable.end(); it++) {
74 pair<int, JackClientSocket*> elem = (*it).second;
75 JackClientSocket* socket = elem.second;
82 int JackSocketServerChannel::Start()
84 if (fThread.Start() != 0) {
85 jack_error(
"Cannot start Jack server listener");
92 void JackSocketServerChannel::Stop()
97 void JackSocketServerChannel::ClientCreate()
99 jack_log(
"JackSocketServerChannel::ClientCreate socket");
100 JackClientSocket* socket = fRequestListenSocket.Accept();
102 fSocketTable[socket->GetFd()] = make_pair( -1, socket);
105 jack_error(
"Client socket cannot be created");
109 void JackSocketServerChannel::ClientAdd(
int fd,
char* name,
int pid,
int uuid,
int* shared_engine,
int* shared_client,
int* shared_graph,
int* result)
111 jack_log(
"JackSocketServerChannel::ClientAdd");
113 *result = fServer->GetEngine()->ClientExternalOpen(name, pid, uuid, &refnum, shared_engine, shared_client, shared_graph);
115 fSocketTable[fd].first = refnum;
119 if (setsockopt(fd, SOL_SOCKET, SO_NOSIGPIPE, (
const char*)&on,
sizeof(on)) < 0) {
120 jack_log(
"setsockopt SO_NOSIGPIPE fd = %ld err = %s", fd, strerror(errno));
128 void JackSocketServerChannel::ClientRemove(
int fd,
int refnum)
130 pair<int, JackClientSocket*> elem = fSocketTable[fd];
131 JackClientSocket* socket = elem.second;
133 jack_log(
"JackSocketServerChannel::ClientRemove ref = %d", refnum);
134 fSocketTable.erase(fd);
140 void JackSocketServerChannel::ClientKill(
int fd)
142 pair<int, JackClientSocket*> elem = fSocketTable[fd];
143 JackClientSocket* socket = elem.second;
144 int refnum = elem.first;
147 jack_log(
"JackSocketServerChannel::ClientKill ref = %d", refnum);
150 jack_log(
"Client was not opened : probably correspond to server_check");
152 fServer->ClientKill(refnum);
155 fSocketTable.erase(fd);
161 bool JackSocketServerChannel::HandleRequest(
int fd)
163 pair<int, JackClientSocket*> elem = fSocketTable[fd];
164 JackClientSocket* socket = elem.second;
169 if (header.Read(socket) < 0) {
170 jack_log(
"HandleRequest: cannot read header");
175 if (fd == JackServerGlobals::fRTNotificationSocket && header.fType != JackRequest::kNotification) {
176 jack_error(
"fRTNotificationSocket = %d", JackServerGlobals::fRTNotificationSocket);
177 jack_error(
"JackSocketServerChannel::HandleRequest : incorrect notification !!");
182 switch (header.fType) {
184 case JackRequest::kClientCheck: {
185 jack_log(
"JackRequest::ClientCheck");
186 JackClientCheckRequest req;
187 JackClientCheckResult res;
188 if (req.Read(socket) == 0)
189 res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus);
190 if (res.Write(socket) < 0)
191 jack_error(
"JackRequest::ClientCheck write error name = %s", req.fName);
198 case JackRequest::kClientOpen: {
199 jack_log(
"JackRequest::ClientOpen");
200 JackClientOpenRequest req;
201 JackClientOpenResult res;
202 if (req.Read(socket) == 0)
203 ClientAdd(fd, req.fName, req.fPID, req.fUUID, &res.fSharedEngine, &res.fSharedClient, &res.fSharedGraph, &res.fResult);
204 if (res.Write(socket) < 0)
205 jack_error(
"JackRequest::ClientOpen write error name = %s", req.fName);
209 case JackRequest::kClientClose: {
210 jack_log(
"JackRequest::ClientClose");
211 JackClientCloseRequest req;
213 if (req.Read(socket) == 0)
214 res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum);
215 if (res.Write(socket) < 0)
216 jack_error(
"JackRequest::ClientClose write error ref = %d", req.fRefNum);
217 ClientRemove(fd, req.fRefNum);
221 case JackRequest::kActivateClient: {
222 JackActivateRequest req;
224 jack_log(
"JackRequest::ActivateClient");
225 if (req.Read(socket) == 0)
226 res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime);
227 if (res.Write(socket) < 0)
228 jack_error(
"JackRequest::ActivateClient write error ref = %d", req.fRefNum);
232 case JackRequest::kDeactivateClient: {
233 jack_log(
"JackRequest::DeactivateClient");
234 JackDeactivateRequest req;
236 if (req.Read(socket) == 0)
237 res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum);
238 if (res.Write(socket) < 0)
239 jack_error(
"JackRequest::DeactivateClient write error ref = %d", req.fRefNum);
243 case JackRequest::kRegisterPort: {
244 jack_log(
"JackRequest::RegisterPort");
245 JackPortRegisterRequest req;
246 JackPortRegisterResult res;
247 if (req.Read(socket) == 0)
248 res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fPortType, req.fFlags, req.fBufferSize, &res.fPortIndex);
249 if (res.Write(socket) < 0)
250 jack_error(
"JackRequest::RegisterPort write error ref = %d", req.fRefNum);
254 case JackRequest::kUnRegisterPort: {
255 jack_log(
"JackRequest::UnRegisterPort");
256 JackPortUnRegisterRequest req;
258 if (req.Read(socket) == 0)
259 res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex);
260 if (res.Write(socket) < 0)
261 jack_error(
"JackRequest::UnRegisterPort write error ref = %d", req.fRefNum);
265 case JackRequest::kConnectNamePorts: {
266 jack_log(
"JackRequest::ConnectNamePorts");
267 JackPortConnectNameRequest req;
269 if (req.Read(socket) == 0)
270 res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
271 if (res.Write(socket) < 0)
272 jack_error(
"JackRequest::ConnectNamePorts write error ref = %d", req.fRefNum);
276 case JackRequest::kDisconnectNamePorts: {
277 jack_log(
"JackRequest::DisconnectNamePorts");
278 JackPortDisconnectNameRequest req;
280 if (req.Read(socket) == 0)
281 res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
282 if (res.Write(socket) < 0)
283 jack_error(
"JackRequest::DisconnectNamePorts write error ref = %d", req.fRefNum);
287 case JackRequest::kConnectPorts: {
288 jack_log(
"JackRequest::ConnectPorts");
289 JackPortConnectRequest req;
291 if (req.Read(socket) == 0)
292 res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
293 if (res.Write(socket) < 0)
294 jack_error(
"JackRequest::ConnectPorts write error ref = %d", req.fRefNum);
298 case JackRequest::kDisconnectPorts: {
299 jack_log(
"JackRequest::DisconnectPorts");
300 JackPortDisconnectRequest req;
302 if (req.Read(socket) == 0)
303 res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
304 if (res.Write(socket) < 0)
305 jack_error(
"JackRequest::DisconnectPorts write error ref = %d", req.fRefNum);
309 case JackRequest::kPortRename: {
310 jack_log(
"JackRequest::PortRename");
311 JackPortRenameRequest req;
313 if (req.Read(socket) == 0)
314 res.fResult = fServer->GetEngine()->PortRename(req.fRefNum, req.fPort, req.fName);
315 if (res.Write(socket) < 0)
316 jack_error(
"JackRequest::PortRename write error ref = %d", req.fRefNum);
320 case JackRequest::kSetBufferSize: {
321 jack_log(
"JackRequest::SetBufferSize");
322 JackSetBufferSizeRequest req;
324 if (req.Read(socket) == 0)
325 res.fResult = fServer->SetBufferSize(req.fBufferSize);
326 if (res.Write(socket) < 0)
327 jack_error(
"JackRequest::SetBufferSize write error");
331 case JackRequest::kSetFreeWheel: {
332 jack_log(
"JackRequest::SetFreeWheel");
333 JackSetFreeWheelRequest req;
335 if (req.Read(socket) == 0)
336 res.fResult = fServer->SetFreewheel(req.fOnOff);
337 if (res.Write(socket) < 0)
338 jack_error(
"JackRequest::SetFreeWheel write error");
342 case JackRequest::kComputeTotalLatencies: {
343 jack_log(
"JackRequest::ComputeTotalLatencies");
344 JackComputeTotalLatenciesRequest req;
346 if (req.Read(socket) == 0)
347 res.fResult = fServer->GetEngine()->ComputeTotalLatencies();
348 if (res.Write(socket) < 0)
349 jack_error(
"JackRequest::ComputeTotalLatencies write error");
353 case JackRequest::kReleaseTimebase: {
354 jack_log(
"JackRequest::ReleaseTimebase");
355 JackReleaseTimebaseRequest req;
357 if (req.Read(socket) == 0)
358 res.fResult = fServer->ReleaseTimebase(req.fRefNum);
359 if (res.Write(socket) < 0)
360 jack_error(
"JackRequest::ReleaseTimebase write error ref = %d", req.fRefNum);
364 case JackRequest::kSetTimebaseCallback: {
365 jack_log(
"JackRequest::SetTimebaseCallback");
366 JackSetTimebaseCallbackRequest req;
368 if (req.Read(socket) == 0)
369 res.fResult = fServer->SetTimebaseCallback(req.fRefNum, req.fConditionnal);
370 if (res.Write(socket) < 0)
371 jack_error(
"JackRequest::SetTimebaseCallback write error ref = %d", req.fRefNum);
375 case JackRequest::kGetInternalClientName: {
376 jack_log(
"JackRequest::GetInternalClientName");
377 JackGetInternalClientNameRequest req;
378 JackGetInternalClientNameResult res;
379 if (req.Read(socket) == 0)
380 res.fResult = fServer->GetEngine()->GetInternalClientName(req.fIntRefNum, res.fName);
381 if (res.Write(socket) < 0)
382 jack_error(
"JackRequest::GetInternalClientName write error ref = %d", req.fRefNum);
386 case JackRequest::kInternalClientHandle: {
387 jack_log(
"JackRequest::InternalClientHandle");
388 JackInternalClientHandleRequest req;
389 JackInternalClientHandleResult res;
390 if (req.Read(socket) == 0)
391 res.fResult = fServer->GetEngine()->InternalClientHandle(req.fName, &res.fStatus, &res.fIntRefNum);
392 if (res.Write(socket) < 0)
393 jack_error(
"JackRequest::InternalClientHandle write error ref = %d", req.fRefNum);
397 case JackRequest::kInternalClientLoad: {
398 jack_log(
"JackRequest::InternalClientLoad");
399 JackInternalClientLoadRequest req;
400 JackInternalClientLoadResult res;
401 if (req.Read(socket) == 0)
402 res.fResult = fServer->InternalClientLoad1(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus);
403 if (res.Write(socket) < 0)
404 jack_error(
"JackRequest::InternalClientLoad write error name = %s", req.fName);
408 case JackRequest::kInternalClientUnload: {
409 jack_log(
"JackRequest::InternalClientUnload");
410 JackInternalClientUnloadRequest req;
411 JackInternalClientUnloadResult res;
412 if (req.Read(socket) == 0)
413 res.fResult = fServer->GetEngine()->InternalClientUnload(req.fIntRefNum, &res.fStatus);
414 if (res.Write(socket) < 0)
415 jack_error(
"JackRequest::InternalClientUnload write error ref = %d", req.fRefNum);
419 case JackRequest::kNotification: {
420 jack_log(
"JackRequest::Notification");
421 JackClientNotificationRequest req;
422 if (req.Read(socket) == 0) {
423 if (req.fNotify == kQUIT) {
424 jack_log(
"JackRequest::Notification kQUIT");
425 throw JackQuitException();
427 fServer->Notify(req.fRefNum, req.fNotify, req.fValue);
433 case JackRequest::kSessionNotify: {
434 jack_log(
"JackRequest::SessionNotify");
435 JackSessionNotifyRequest req;
436 if (req.Read(socket) == 0) {
437 fServer->GetEngine()->SessionNotify(req.fRefNum, req.fDst, req.fEventType, req.fPath, socket, NULL);
442 case JackRequest::kSessionReply: {
443 jack_log(
"JackRequest::SessionReply");
444 JackSessionReplyRequest req;
446 if (req.Read(socket) == 0) {
447 fServer->GetEngine()->SessionReply(req.fRefNum);
450 if (res.Write(socket) < 0)
451 jack_error(
"JackRequest::SessionReply write error");
455 case JackRequest::kGetClientByUUID: {
456 jack_log(
"JackRequest::GetClientByUUID");
457 JackGetClientNameRequest req;
458 JackClientNameResult res;
459 if (req.Read(socket) == 0) {
460 fServer->GetEngine()->GetClientNameForUUID(req.fUUID, res.fName, &res.fResult);
462 if (res.Write(socket) < 0)
463 jack_error(
"JackRequest::GetClientByUUID write error");
467 case JackRequest::kGetUUIDByClient: {
468 jack_log(
"JackRequest::GetUUIDByClient");
469 JackGetUUIDRequest req;
471 if (req.Read(socket) == 0) {
472 fServer->GetEngine()->GetUUIDForClientName(req.fName, res.fUUID, &res.fResult);
474 if (res.Write(socket) < 0)
475 jack_error(
"JackRequest::GetUUIDByClient write error");
479 case JackRequest::kReserveClientName: {
480 jack_log(
"JackRequest::ReserveClientName");
481 JackReserveNameRequest req;
483 if (req.Read(socket) == 0) {
484 fServer->GetEngine()->ReserveClientName(req.fName, req.fUUID, &res.fResult);
486 if (res.Write(socket) < 0)
487 jack_error(
"JackRequest::ReserveClientName write error");
491 case JackRequest::kClientHasSessionCallback: {
492 jack_log(
"JackRequest::ClientHasSessionCallback");
493 JackClientHasSessionCallbackRequest req;
495 if (req.Read(socket) == 0) {
496 fServer->GetEngine()->ClientHasSessionCallback(req.fName, &res.fResult);
498 if (res.Write(socket) < 0)
499 jack_error(
"JackRequest::ClientHasSessionCallback write error");
504 jack_error(
"Unknown request %ld", header.fType);
511 void JackSocketServerChannel::BuildPoolTable()
516 fPollTable =
new pollfd[fSocketTable.size() + 1];
518 jack_log(
"JackSocketServerChannel::BuildPoolTable size = %d", fSocketTable.size() + 1);
521 fPollTable[0].fd = fRequestListenSocket.GetFd();
522 fPollTable[0].events = POLLIN | POLLERR;
525 map<int, pair<int, JackClientSocket*> >::iterator it;
528 for (i = 1, it = fSocketTable.begin(); it != fSocketTable.end(); it++, i++) {
529 jack_log(
"fSocketTable i = %ld fd = %ld", i, it->first);
530 fPollTable[i].fd = it->first;
531 fPollTable[i].events = POLLIN | POLLPRI | POLLERR | POLLHUP | POLLNVAL;
540 sigaddset(&
set, SIGPIPE);
541 pthread_sigmask(SIG_BLOCK, &
set, 0);
545 bool JackSocketServerChannel::Execute()
550 if ((poll(fPollTable, fSocketTable.size() + 1, 10000) < 0) && (errno != EINTR)) {
551 jack_error(
"Engine poll failed err = %s request thread quits...", strerror(errno));
556 for (
unsigned int i = 1; i < fSocketTable.size() + 1; i++) {
557 int fd = fPollTable[i].fd;
558 jack_log(
"fPollTable i = %ld fd = %ld", i, fd);
559 if (fPollTable[i].revents & ~POLLIN) {
560 jack_log(
"Poll client error err = %s", strerror(errno));
562 }
else if (fPollTable[i].revents & POLLIN) {
563 if (!HandleRequest(fd))
564 jack_log(
"Could not handle external client request");
569 if (fPollTable[0].revents & POLLERR)
570 jack_error(
"Error on server request socket err = %s", strerror(errno));
572 if (fPollTable[0].revents & POLLIN)
579 }
catch (JackQuitException& e) {
580 jack_log(
"JackSocketServerChannel::Execute JackQuitException");