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"
39 JackSocketServerChannel::JackSocketServerChannel():
46 JackSocketServerChannel::~JackSocketServerChannel()
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");
67 void JackSocketServerChannel::Close()
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
;
83 int JackSocketServerChannel::Start()
85 if (fThread
.Start() != 0) {
86 jack_error("Cannot start Jack server listener");
93 void JackSocketServerChannel::ClientCreate()
95 jack_log("JackSocketServerChannel::ClientCreate socket");
96 JackClientSocket
* socket
= fRequestListenSocket
.Accept();
98 fSocketTable
[socket
->GetFd()] = make_pair( -1, socket
);
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");
109 *result
= fServer
->GetEngine()->ClientExternalOpen(name
, pid
, &refnum
, shared_engine
, shared_client
, shared_graph
);
111 fSocketTable
[fd
].first
= refnum
;
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
;
123 jack_log("JackSocketServerChannel::ClientRemove ref = %d", refnum
);
124 fSocketTable
.erase(fd
);
130 void JackSocketServerChannel::ClientKill(int fd
)
132 pair
<int, JackClientSocket
*> elem
= fSocketTable
[fd
];
133 JackClientSocket
* socket
= elem
.second
;
134 int refnum
= elem
.first
;
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");
142 fServer
->ClientKill(refnum
);
145 fSocketTable
.erase(fd
);
151 bool JackSocketServerChannel::HandleRequest(int fd
)
153 pair
<int, JackClientSocket
*> elem
= fSocketTable
[fd
];
154 JackClientSocket
* socket
= elem
.second
;
159 if (header
.Read(socket
) < 0) {
160 jack_log("HandleRequest: cannot read header");
161 ClientKill(fd
); // TO CHECK SOLARIS
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
);
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
);
190 case JackRequest::kClientClose
: {
191 jack_log("JackRequest::ClientClose");
192 JackClientCloseRequest req
;
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
);
202 case JackRequest::kActivateClient
: {
203 JackActivateRequest req
;
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
);
213 case JackRequest::kDeactivateClient
: {
214 jack_log("JackRequest::DeactivateClient");
215 JackDeactivateRequest req
;
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
);
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
);
235 case JackRequest::kUnRegisterPort
: {
236 jack_log("JackRequest::UnRegisterPort");
237 JackPortUnRegisterRequest req
;
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
);
246 case JackRequest::kConnectNamePorts
: {
247 jack_log("JackRequest::ConnectNamePorts");
248 JackPortConnectNameRequest req
;
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
);
257 case JackRequest::kDisconnectNamePorts
: {
258 jack_log("JackRequest::DisconnectNamePorts");
259 JackPortDisconnectNameRequest req
;
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
);
268 case JackRequest::kConnectPorts
: {
269 jack_log("JackRequest::ConnectPorts");
270 JackPortConnectRequest req
;
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
);
279 case JackRequest::kDisconnectPorts
: {
280 jack_log("JackRequest::DisconnectPorts");
281 JackPortDisconnectRequest req
;
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
);
290 case JackRequest::kPortRename
: {
291 jack_log("JackRequest::PortRename");
292 JackPortRenameRequest req
;
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
);
301 case JackRequest::kSetBufferSize
: {
302 jack_log("JackRequest::SetBufferSize");
303 JackSetBufferSizeRequest req
;
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");
312 case JackRequest::kSetFreeWheel
: {
313 jack_log("JackRequest::SetFreeWheel");
314 JackSetFreeWheelRequest req
;
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");
323 case JackRequest::kReleaseTimebase
: {
324 jack_log("JackRequest::ReleaseTimebase");
325 JackReleaseTimebaseRequest req
;
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
);
334 case JackRequest::kSetTimebaseCallback
: {
335 jack_log("JackRequest::SetTimebaseCallback");
336 JackSetTimebaseCallbackRequest req
;
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
);
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
);
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
);
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
);
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
);
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();
397 fServer
->Notify(req
.fRefNum
, req
.fNotify
, req
.fValue
);
404 jack_error("Unknown request %ld", header
.fType
);
411 void JackSocketServerChannel::BuildPoolTable()
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
;
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()
440 sigaddset(&set
, SIGPIPE
);
441 pthread_sigmask(SIG_BLOCK
, &set
, 0);
445 bool JackSocketServerChannel::Execute()
450 if ((poll(fPollTable
, fSocketTable
.size() + 1, 10000) < 0) && (errno
!= EINTR
)) {
451 jack_error("Engine poll failed err = %s request thread quits...", strerror(errno
));
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
));
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
)
479 } catch (JackQuitException
& e
) {
480 jack_log("JackMachServerChannel::Execute JackQuitException");
485 } // end of namespace