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"
37 JackSocketServerChannel::JackSocketServerChannel():
44 JackSocketServerChannel::~JackSocketServerChannel()
49 int JackSocketServerChannel::Open(const char* server_name
, JackServer
* server
)
51 jack_log("JackSocketServerChannel::Open");
53 // Prepare request socket
54 if (fRequestListenSocket
.Bind(jack_server_dir
, server_name
, 0) < 0) {
55 jack_log("JackSocketServerChannel::Open : cannot create result listen socket");
65 void JackSocketServerChannel::Close()
68 fRequestListenSocket
.Close();
70 // Close remaining client sockets
71 std::map
<int, std::pair
<int, JackClientSocket
*> >::iterator it
;
72 for (it
= fSocketTable
.begin(); it
!= fSocketTable
.end(); it
++) {
73 pair
<int, JackClientSocket
*> elem
= (*it
).second
;
74 JackClientSocket
* socket
= elem
.second
;
81 int JackSocketServerChannel::Start()
83 if (fThread
.Start() != 0) {
84 jack_error("Cannot start Jack server listener");
91 void JackSocketServerChannel::ClientCreate()
93 jack_log("JackSocketServerChannel::ClientCreate socket");
94 JackClientSocket
* socket
= fRequestListenSocket
.Accept();
96 fSocketTable
[socket
->GetFd()] = make_pair( -1, socket
);
99 jack_error("Client socket cannot be created");
103 void JackSocketServerChannel::ClientAdd(int fd
, char* name
, int pid
, int* shared_engine
, int* shared_client
, int* shared_graph
, int* result
)
105 jack_log("JackSocketServerChannel::ClientAdd");
107 *result
= fServer
->GetEngine()->ClientExternalOpen(name
, pid
, &refnum
, shared_engine
, shared_client
, shared_graph
);
109 fSocketTable
[fd
].first
= refnum
;
112 jack_error("Cannot create new client");
116 void JackSocketServerChannel::ClientRemove(int fd
, int refnum
)
118 pair
<int, JackClientSocket
*> elem
= fSocketTable
[fd
];
119 JackClientSocket
* socket
= elem
.second
;
121 jack_log("JackSocketServerChannel::ClientRemove ref = %d", refnum
);
122 fSocketTable
.erase(fd
);
128 void JackSocketServerChannel::ClientKill(int fd
)
130 pair
<int, JackClientSocket
*> elem
= fSocketTable
[fd
];
131 JackClientSocket
* socket
= elem
.second
;
132 int refnum
= elem
.first
;
135 jack_log("JackSocketServerChannel::ClientKill ref = %d", refnum
);
137 if (refnum
== -1) { // Should never happen... correspond to a client that started the socket but never opened...
138 jack_log("Client was not opened : probably correspond to server_check");
140 fServer
->ClientKill(refnum
);
143 fSocketTable
.erase(fd
);
149 bool JackSocketServerChannel::HandleRequest(int fd
)
151 pair
<int, JackClientSocket
*> elem
= fSocketTable
[fd
];
152 JackClientSocket
* socket
= elem
.second
;
157 if (header
.Read(socket
) < 0) {
158 jack_log("HandleRequest: cannot read header");
159 ClientKill(fd
); // TO CHECK SOLARIS
164 switch (header
.fType
) {
166 case JackRequest::kClientCheck
: {
167 jack_log("JackRequest::ClientCheck");
168 JackClientCheckRequest req
;
169 JackClientCheckResult res
;
170 if (req
.Read(socket
) == 0)
171 res
.fResult
= fServer
->GetEngine()->ClientCheck(req
.fName
, res
.fName
, req
.fProtocol
, req
.fOptions
, &res
.fStatus
);
172 if (res
.Write(socket
) < 0)
173 jack_error("JackRequest::ClientCheck write error name = %s", req
.fName
);
177 case JackRequest::kClientOpen
: {
178 jack_log("JackRequest::ClientOpen");
179 JackClientOpenRequest req
;
180 JackClientOpenResult res
;
181 if (req
.Read(socket
) == 0)
182 ClientAdd(fd
, req
.fName
, req
.fPID
, &res
.fSharedEngine
, &res
.fSharedClient
, &res
.fSharedGraph
, &res
.fResult
);
183 if (res
.Write(socket
) < 0)
184 jack_error("JackRequest::ClientOpen write error name = %s", req
.fName
);
188 case JackRequest::kClientClose
: {
189 jack_log("JackRequest::ClientClose");
190 JackClientCloseRequest req
;
192 if (req
.Read(socket
) == 0)
193 res
.fResult
= fServer
->GetEngine()->ClientExternalClose(req
.fRefNum
);
194 if (res
.Write(socket
) < 0)
195 jack_error("JackRequest::ClientClose write error ref = %d", req
.fRefNum
);
196 ClientRemove(fd
, req
.fRefNum
);
200 case JackRequest::kActivateClient
: {
201 JackActivateRequest req
;
203 jack_log("JackRequest::ActivateClient");
204 if (req
.Read(socket
) == 0)
205 res
.fResult
= fServer
->GetEngine()->ClientActivate(req
.fRefNum
, req
.fIsRealTime
);
206 if (res
.Write(socket
) < 0)
207 jack_error("JackRequest::ActivateClient write error ref = %d", req
.fRefNum
);
211 case JackRequest::kDeactivateClient
: {
212 jack_log("JackRequest::DeactivateClient");
213 JackDeactivateRequest req
;
215 if (req
.Read(socket
) == 0)
216 res
.fResult
= fServer
->GetEngine()->ClientDeactivate(req
.fRefNum
);
217 if (res
.Write(socket
) < 0)
218 jack_error("JackRequest::DeactivateClient write error ref = %d", req
.fRefNum
);
222 case JackRequest::kRegisterPort
: {
223 jack_log("JackRequest::RegisterPort");
224 JackPortRegisterRequest req
;
225 JackPortRegisterResult res
;
226 if (req
.Read(socket
) == 0)
227 res
.fResult
= fServer
->GetEngine()->PortRegister(req
.fRefNum
, req
.fName
, req
.fPortType
, req
.fFlags
, req
.fBufferSize
, &res
.fPortIndex
);
228 if (res
.Write(socket
) < 0)
229 jack_error("JackRequest::RegisterPort write error ref = %d", req
.fRefNum
);
233 case JackRequest::kUnRegisterPort
: {
234 jack_log("JackRequest::UnRegisterPort");
235 JackPortUnRegisterRequest req
;
237 if (req
.Read(socket
) == 0)
238 res
.fResult
= fServer
->GetEngine()->PortUnRegister(req
.fRefNum
, req
.fPortIndex
);
239 if (res
.Write(socket
) < 0)
240 jack_error("JackRequest::UnRegisterPort write error ref = %d", req
.fRefNum
);
244 case JackRequest::kConnectNamePorts
: {
245 jack_log("JackRequest::ConnectNamePorts");
246 JackPortConnectNameRequest req
;
248 if (req
.Read(socket
) == 0)
249 res
.fResult
= fServer
->GetEngine()->PortConnect(req
.fRefNum
, req
.fSrc
, req
.fDst
);
250 if (res
.Write(socket
) < 0)
251 jack_error("JackRequest::ConnectNamePorts write error ref = %d", req
.fRefNum
);
255 case JackRequest::kDisconnectNamePorts
: {
256 jack_log("JackRequest::DisconnectNamePorts");
257 JackPortDisconnectNameRequest req
;
259 if (req
.Read(socket
) == 0)
260 res
.fResult
= fServer
->GetEngine()->PortDisconnect(req
.fRefNum
, req
.fSrc
, req
.fDst
);
261 if (res
.Write(socket
) < 0)
262 jack_error("JackRequest::DisconnectNamePorts write error ref = %d", req
.fRefNum
);
266 case JackRequest::kConnectPorts
: {
267 jack_log("JackRequest::ConnectPorts");
268 JackPortConnectRequest req
;
270 if (req
.Read(socket
) == 0)
271 res
.fResult
= fServer
->GetEngine()->PortConnect(req
.fRefNum
, req
.fSrc
, req
.fDst
);
272 if (res
.Write(socket
) < 0)
273 jack_error("JackRequest::ConnectPorts write error ref = %d", req
.fRefNum
);
277 case JackRequest::kDisconnectPorts
: {
278 jack_log("JackRequest::DisconnectPorts");
279 JackPortDisconnectRequest req
;
281 if (req
.Read(socket
) == 0)
282 res
.fResult
= fServer
->GetEngine()->PortDisconnect(req
.fRefNum
, req
.fSrc
, req
.fDst
);
283 if (res
.Write(socket
) < 0)
284 jack_error("JackRequest::DisconnectPorts write error ref = %d", req
.fRefNum
);
288 case JackRequest::kPortRename
: {
289 jack_log("JackRequest::PortRename");
290 JackPortRenameRequest req
;
292 if (req
.Read(socket
) == 0)
293 res
.fResult
= fServer
->GetEngine()->PortRename(req
.fRefNum
, req
.fPort
, req
.fName
);
294 if (res
.Write(socket
) < 0)
295 jack_error("JackRequest::PortRename write error ref = %d", req
.fRefNum
);
299 case JackRequest::kSetBufferSize
: {
300 jack_log("JackRequest::SetBufferSize");
301 JackSetBufferSizeRequest req
;
303 if (req
.Read(socket
) == 0)
304 res
.fResult
= fServer
->SetBufferSize(req
.fBufferSize
);
305 if (res
.Write(socket
) < 0)
306 jack_error("JackRequest::SetBufferSize write error");
310 case JackRequest::kSetFreeWheel
: {
311 jack_log("JackRequest::SetFreeWheel");
312 JackSetFreeWheelRequest req
;
314 if (req
.Read(socket
) == 0)
315 res
.fResult
= fServer
->SetFreewheel(req
.fOnOff
);
316 if (res
.Write(socket
) < 0)
317 jack_error("JackRequest::SetFreeWheel write error");
321 case JackRequest::kReleaseTimebase
: {
322 jack_log("JackRequest::ReleaseTimebase");
323 JackReleaseTimebaseRequest req
;
325 if (req
.Read(socket
) == 0)
326 res
.fResult
= fServer
->ReleaseTimebase(req
.fRefNum
);
327 if (res
.Write(socket
) < 0)
328 jack_error("JackRequest::ReleaseTimebase write error ref = %d", req
.fRefNum
);
332 case JackRequest::kSetTimebaseCallback
: {
333 jack_log("JackRequest::SetTimebaseCallback");
334 JackSetTimebaseCallbackRequest req
;
336 if (req
.Read(socket
) == 0)
337 res
.fResult
= fServer
->SetTimebaseCallback(req
.fRefNum
, req
.fConditionnal
);
338 if (res
.Write(socket
) < 0)
339 jack_error("JackRequest::SetTimebaseCallback write error ref = %d", req
.fRefNum
);
343 case JackRequest::kGetInternalClientName
: {
344 jack_log("JackRequest::GetInternalClientName");
345 JackGetInternalClientNameRequest req
;
346 JackGetInternalClientNameResult res
;
347 if (req
.Read(socket
) == 0)
348 res
.fResult
= fServer
->GetEngine()->GetInternalClientName(req
.fIntRefNum
, res
.fName
);
349 if (res
.Write(socket
) < 0)
350 jack_error("JackRequest::GetInternalClientName write error ref = %d", req
.fRefNum
);
354 case JackRequest::kInternalClientHandle
: {
355 jack_log("JackRequest::InternalClientHandle");
356 JackInternalClientHandleRequest req
;
357 JackInternalClientHandleResult res
;
358 if (req
.Read(socket
) == 0)
359 res
.fResult
= fServer
->GetEngine()->InternalClientHandle(req
.fName
, &res
.fStatus
, &res
.fIntRefNum
);
360 if (res
.Write(socket
) < 0)
361 jack_error("JackRequest::InternalClientHandle write error ref = %d", req
.fRefNum
);
365 case JackRequest::kInternalClientLoad
: {
366 jack_log("JackRequest::InternalClientLoad");
367 JackInternalClientLoadRequest req
;
368 JackInternalClientLoadResult res
;
369 if (req
.Read(socket
) == 0)
370 res
.fResult
= fServer
->InternalClientLoad(req
.fName
, req
.fDllName
, req
.fLoadInitName
, req
.fOptions
, &res
.fIntRefNum
, &res
.fStatus
);
371 if (res
.Write(socket
) < 0)
372 jack_error("JackRequest::InternalClientLoad write error name = %s", req
.fName
);
376 case JackRequest::kInternalClientUnload
: {
377 jack_log("JackRequest::InternalClientUnload");
378 JackInternalClientUnloadRequest req
;
379 JackInternalClientUnloadResult res
;
380 if (req
.Read(socket
) == 0)
381 res
.fResult
= fServer
->GetEngine()->InternalClientUnload(req
.fIntRefNum
, &res
.fStatus
);
382 if (res
.Write(socket
) < 0)
383 jack_error("JackRequest::InternalClientUnload write error ref = %d", req
.fRefNum
);
387 case JackRequest::kNotification
: {
388 jack_log("JackRequest::Notification");
389 JackClientNotificationRequest req
;
390 if (req
.Read(socket
) == 0)
391 fServer
->Notify(req
.fRefNum
, req
.fNotify
, req
.fValue
);
396 jack_error("Unknown request %ld", header
.fType
);
403 void JackSocketServerChannel::BuildPoolTable()
408 fPollTable
= new pollfd
[fSocketTable
.size() + 1];
410 jack_log("JackSocketServerChannel::BuildPoolTable size = %d", fSocketTable
.size() + 1);
412 // First fd is the server request socket
413 fPollTable
[0].fd
= fRequestListenSocket
.GetFd();
414 fPollTable
[0].events
= POLLIN
| POLLERR
;
416 // Next fd for clients
417 map
<int, pair
<int, JackClientSocket
*> >::iterator it
;
420 for (i
= 1, it
= fSocketTable
.begin(); it
!= fSocketTable
.end(); it
++, i
++) {
421 jack_log("fSocketTable i = %ld fd = %ld", i
, it
->first
);
422 fPollTable
[i
].fd
= it
->first
;
423 fPollTable
[i
].events
= POLLIN
| POLLPRI
| POLLERR
| POLLHUP
| POLLNVAL
;
428 bool JackSocketServerChannel::Init()
432 sigaddset(&set
, SIGPIPE
);
433 pthread_sigmask(SIG_BLOCK
, &set
, 0);
437 bool JackSocketServerChannel::Execute()
440 if ((poll(fPollTable
, fSocketTable
.size() + 1, 10000) < 0) && (errno
!= EINTR
)) {
441 jack_error("Engine poll failed err = %s request thread quits...", strerror(errno
));
446 for (unsigned int i
= 1; i
< fSocketTable
.size() + 1; i
++) {
447 int fd
= fPollTable
[i
].fd
;
448 jack_log("fPollTable i = %ld fd = %ld", i
, fd
);
449 if (fPollTable
[i
].revents
& ~POLLIN
) {
450 jack_log("Poll client error err = %s", strerror(errno
));
452 } else if (fPollTable
[i
].revents
& POLLIN
) {
453 if (!HandleRequest(fd
))
454 jack_log("Could not handle external client request");
458 // Check the server request socket */
459 if (fPollTable
[0].revents
& POLLERR
)
460 jack_error("Error on server request socket err = %s", strerror(errno
));
462 if (fPollTable
[0].revents
& POLLIN
)
470 } // end of namespace