2 Copyright (C) 2004-2006 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 "JackEngine.h"
24 #include "JackGlobals.h"
25 #include "JackClient.h"
33 JackSocketServerChannel::JackSocketServerChannel()
35 fThread
= JackGlobals::MakeThread(this);
40 JackSocketServerChannel::~JackSocketServerChannel()
46 int JackSocketServerChannel::Open(JackServer
* server
)
48 JackLog("JackSocketServerChannel::Open \n");
51 // Prepare request socket
52 if (fRequestListenSocket
.Bind(jack_server_dir
, 0) < 0) {
53 JackLog("JackSocketServerChannel::Open : cannot create result listen socket\n");
61 if (fThread
->Start() != 0) {
62 jack_error("Cannot start Jack server listener");
69 fRequestListenSocket
.Close();
73 void JackSocketServerChannel::Close()
76 fRequestListenSocket
.Close();
79 void JackSocketServerChannel::CreateClient()
81 JackLog("JackSocketServerChannel::CreateClient socket\n");
82 JackClientSocket
* socket
= fRequestListenSocket
.Accept();
84 fSocketTable
[socket
->GetFd()] = make_pair( -1, socket
);
87 jack_error("Client socket cannot be created");
91 void JackSocketServerChannel::AddClient(int fd
, char* name
, int* shared_engine
, int* shared_client
, int* shared_graph
, int* result
)
93 JackLog("JackSocketServerChannel::AddClient\n");
95 *result
= fServer
->GetEngine()->ClientExternalOpen(name
, &refnum
, shared_engine
, shared_client
, shared_graph
);
97 fSocketTable
[fd
].first
= refnum
;
100 jack_error("Cannot create new client");
104 void JackSocketServerChannel::RemoveClient(int fd
, int refnum
)
106 pair
<int, JackClientSocket
*> elem
= fSocketTable
[fd
];
107 JackClientSocket
* socket
= elem
.second
;
109 JackLog("JackSocketServerChannel::RemoveClient ref = %d\n", refnum
);
110 fSocketTable
.erase(fd
);
116 void JackSocketServerChannel::KillClient(int fd
)
118 pair
<int, JackClientSocket
*> elem
= fSocketTable
[fd
];
119 JackClientSocket
* socket
= elem
.second
;
120 int refnum
= elem
.first
;
123 JackLog("JackSocketServerChannel::KillClient ref = %d\n", refnum
);
125 if (refnum
== -1) { // Should never happen... correspond to a client that started the socket but never opened...
126 jack_error("Client not opened");
128 fServer
->Notify(refnum
, JackNotifyChannelInterface::kDeadClient
, 0);
131 fSocketTable
.erase(fd
);
137 int JackSocketServerChannel::HandleRequest(int fd
)
139 pair
<int, JackClientSocket
*> elem
= fSocketTable
[fd
];
140 JackClientSocket
* socket
= elem
.second
;
145 if (header
.Read(socket
) < 0) {
146 jack_error("HandleRequest: cannot read header");
151 switch (header
.fType
) {
153 case JackRequest::kClientOpen
: {
154 JackLog("JackRequest::ClientOpen\n");
155 JackClientOpenRequest req
;
156 JackClientOpenResult res
;
157 if (req
.Read(socket
) == 0)
158 AddClient(fd
, req
.fName
, &res
.fSharedEngine
, &res
.fSharedClient
, &res
.fSharedGraph
, &res
.fResult
);
163 case JackRequest::kClientClose
: {
164 JackLog("JackRequest::ClientClose\n");
165 JackClientCloseRequest req
;
167 if (req
.Read(socket
) == 0)
168 res
.fResult
= fServer
->GetEngine()->ClientExternalClose(req
.fRefNum
);
170 RemoveClient(fd
, req
.fRefNum
);
174 case JackRequest::kActivateClient
: {
175 JackActivateRequest req
;
177 JackLog("JackRequest::ActivateClient\n");
178 if (req
.Read(socket
) == 0)
179 res
.fResult
= fServer
->GetEngine()->ClientActivate(req
.fRefNum
);
184 case JackRequest::kDeactivateClient
: {
185 JackLog("JackRequest::DeactivateClient\n");
186 JackDeactivateRequest req
;
188 if (req
.Read(socket
) == 0)
189 res
.fResult
= fServer
->GetEngine()->ClientDeactivate(req
.fRefNum
);
194 case JackRequest::kRegisterPort
: {
195 JackLog("JackRequest::RegisterPort\n");
196 JackPortRegisterRequest req
;
197 JackPortRegisterResult res
;
198 if (req
.Read(socket
) == 0)
199 res
.fResult
= fServer
->GetEngine()->PortRegister(req
.fRefNum
, req
.fName
, req
.fFlags
, req
.fBufferSize
, &res
.fPortIndex
);
204 case JackRequest::kUnRegisterPort
: {
205 JackLog("JackRequest::UnRegisterPort\n");
206 JackPortUnRegisterRequest req
;
208 if (req
.Read(socket
) == 0)
209 res
.fResult
= fServer
->GetEngine()->PortUnRegister(req
.fRefNum
, req
.fPortIndex
);
214 case JackRequest::kConnectNamePorts
: {
215 JackLog("JackRequest::ConnectPorts\n");
216 JackPortConnectNameRequest req
;
218 if (req
.Read(socket
) == 0)
219 res
.fResult
= fServer
->GetEngine()->PortConnect(req
.fRefNum
, req
.fSrc
, req
.fDst
);
224 case JackRequest::kDisconnectNamePorts
: {
225 JackLog("JackRequest::DisconnectPorts\n");
226 JackPortDisconnectNameRequest req
;
228 if (req
.Read(socket
) == 0)
229 res
.fResult
= fServer
->GetEngine()->PortDisconnect(req
.fRefNum
, req
.fSrc
, req
.fDst
);
234 case JackRequest::kConnectPorts
: {
235 JackLog("JackRequest::ConnectPorts\n");
236 JackPortConnectRequest req
;
238 if (req
.Read(socket
) == 0)
239 res
.fResult
= fServer
->GetEngine()->PortConnect(req
.fRefNum
, req
.fSrc
, req
.fDst
);
244 case JackRequest::kDisconnectPorts
: {
245 JackLog("JackRequest::DisconnectPorts\n");
246 JackPortDisconnectRequest req
;
248 if (req
.Read(socket
) == 0)
249 res
.fResult
= fServer
->GetEngine()->PortDisconnect(req
.fRefNum
, req
.fSrc
, req
.fDst
);
254 case JackRequest::kSetBufferSize
: {
255 JackLog("JackRequest::SetBufferSize\n");
256 JackSetBufferSizeRequest req
;
258 if (req
.Read(socket
) == 0)
259 res
.fResult
= fServer
->SetBufferSize(req
.fBufferSize
);
264 case JackRequest::kSetFreeWheel
: {
265 JackLog("JackRequest::SetFreeWheel\n");
266 JackSetFreeWheelRequest req
;
268 if (req
.Read(socket
) == 0)
269 res
.fResult
= fServer
->SetFreewheel(req
.fOnOff
);
274 case JackRequest::kReleaseTimebase
: {
275 JackLog("JackRequest::kReleaseTimebase\n");
276 JackReleaseTimebaseRequest req
;
278 if (req
.Read(socket
) == 0)
279 res
.fResult
= fServer
->GetEngine()->ReleaseTimebase(req
.fRefNum
);
284 case JackRequest::kSetTimebaseCallback
: {
285 JackLog("JackRequest::kSetTimebaseCallback\n");
286 JackSetTimebaseCallbackRequest req
;
288 if (req
.Read(socket
) == 0)
289 res
.fResult
= fServer
->GetEngine()->SetTimebaseCallback(req
.fRefNum
, req
.fConditionnal
);
294 case JackRequest::kNotification
: {
295 JackLog("JackRequest::Notification\n");
296 JackClientNotificationRequest req
;
297 if (req
.Read(socket
) == 0)
298 fServer
->Notify(req
.fRefNum
, req
.fNotify
, req
.fValue
);
303 JackLog("Unknown request %ld\n", header
.fType
);
310 void JackSocketServerChannel::BuildPoolTable()
315 fPollTable
= new pollfd
[fSocketTable
.size() + 1];
317 JackLog("JackSocketServerChannel::BuildPoolTable size = %d\n", fSocketTable
.size() + 1);
319 // First fd is the server request socket
320 fPollTable
[0].fd
= fRequestListenSocket
.GetFd();
321 fPollTable
[0].events
= POLLIN
| POLLERR
;
323 // Next fd for clients
324 map
<int, pair
<int, JackClientSocket
*> >::iterator it
;
327 for (i
= 1, it
= fSocketTable
.begin(); it
!= fSocketTable
.end(); it
++, i
++) {
328 JackLog("fSocketTable i = %ld fd = %ld\n", i
, it
->first
);
329 fPollTable
[i
].fd
= it
->first
;
330 fPollTable
[i
].events
= POLLIN
| POLLPRI
| POLLERR
| POLLHUP
| POLLNVAL
;
335 bool JackSocketServerChannel::Execute()
338 if ((poll(fPollTable
, fSocketTable
.size() + 1, 10000) < 0) && (errno
!= EINTR
)) {
339 jack_error("Engine poll failed err = %s request thread quits...", strerror(errno
));
344 for (unsigned int i
= 1; i
< fSocketTable
.size() + 1; i
++) {
345 int fd
= fPollTable
[i
].fd
;
346 JackLog("fPollTable i = %ld fd = %ld\n", i
, fd
);
347 if (fPollTable
[i
].revents
& ~POLLIN
) {
348 jack_error("Poll client error err = %s", strerror(errno
));
350 } else if (fPollTable
[i
].revents
& POLLIN
) {
351 if (HandleRequest(fd
) < 0) {
352 jack_error("Could not handle external client request");
353 //RemoveClient(fd); TO CHECK
358 // Check the server request socket */
359 if (fPollTable
[0].revents
& POLLERR
) {
360 jack_error("Error on server request socket err = %s", strerror(errno
));
361 //return false; TO CHECK
364 if (fPollTable
[0].revents
& POLLIN
) {
373 } // end of namespace