21 #include "JackWinNamedPipeServerChannel.h"
22 #include "JackNotification.h"
23 #include "JackRequest.h"
24 #include "JackServer.h"
25 #include "JackLockedEngine.h"
26 #include "JackGlobals.h"
27 #include "JackClient.h"
28 #include "JackNotification.h"
29 #include "JackException.h"
37 HANDLE JackClientPipeThread::fMutex = NULL;
41 JackClientPipeThread::JackClientPipeThread(JackWinNamedPipeClient* pipe)
42 :fPipe(pipe), fServer(NULL), fThread(this), fRefNum(0)
46 fMutex = CreateMutex(NULL, FALSE, NULL);
50 JackClientPipeThread::~JackClientPipeThread()
52 jack_log(
"JackClientPipeThread::~JackClientPipeThread");
56 int JackClientPipeThread::Open(JackServer* server)
59 if (fThread.Start() != 0) {
60 jack_error(
"Cannot start Jack server listener\n");
68 void JackClientPipeThread::Close()
70 jack_log(
"JackClientPipeThread::Close %x %ld",
this, fRefNum);
82 bool JackClientPipeThread::Execute()
85 jack_log(
"JackClientPipeThread::Execute");
86 return (HandleRequest());
87 }
catch (JackQuitException& e) {
88 jack_log(
"JackClientPipeThread::Execute JackQuitException");
93 bool JackClientPipeThread::HandleRequest()
97 int res = header.Read(fPipe);
101 if (WaitForSingleObject(fMutex, INFINITE) == WAIT_FAILED) {
102 jack_error(
"JackClientPipeThread::HandleRequest: mutex wait error");
106 jack_error(
"HandleRequest: cannot read header");
112 switch (header.fType) {
114 case JackRequest::kClientCheck: {
115 jack_log(
"JackRequest::ClientCheck");
116 JackClientCheckRequest req;
117 JackClientCheckResult res;
118 if (req.Read(fPipe) == 0)
119 res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus);
127 case JackRequest::kClientOpen: {
128 jack_log(
"JackRequest::ClientOpen");
129 JackClientOpenRequest req;
130 JackClientOpenResult res;
131 if (req.Read(fPipe) == 0)
132 ClientAdd(req.fName, req.fPID, req.fUUID, &res.fSharedEngine, &res.fSharedClient, &res.fSharedGraph, &res.fResult);
137 case JackRequest::kClientClose: {
138 jack_log(
"JackRequest::ClientClose");
139 JackClientCloseRequest req;
141 if (req.Read(fPipe) == 0)
142 res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum);
149 case JackRequest::kActivateClient: {
150 JackActivateRequest req;
152 jack_log(
"JackRequest::ActivateClient");
153 if (req.Read(fPipe) == 0)
154 res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime);
159 case JackRequest::kDeactivateClient: {
160 jack_log(
"JackRequest::DeactivateClient");
161 JackDeactivateRequest req;
163 if (req.Read(fPipe) == 0)
164 res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum);
169 case JackRequest::kRegisterPort: {
170 jack_log(
"JackRequest::RegisterPort");
171 JackPortRegisterRequest req;
172 JackPortRegisterResult res;
173 if (req.Read(fPipe) == 0)
174 res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fPortType, req.fFlags, req.fBufferSize, &res.fPortIndex);
179 case JackRequest::kUnRegisterPort: {
180 jack_log(
"JackRequest::UnRegisterPort");
181 JackPortUnRegisterRequest req;
183 if (req.Read(fPipe) == 0)
184 res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex);
189 case JackRequest::kConnectNamePorts: {
190 jack_log(
"JackRequest::ConnectNamePorts");
191 JackPortConnectNameRequest req;
193 if (req.Read(fPipe) == 0)
194 res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
199 case JackRequest::kDisconnectNamePorts: {
200 jack_log(
"JackRequest::DisconnectNamePorts");
201 JackPortDisconnectNameRequest req;
203 if (req.Read(fPipe) == 0)
204 res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
209 case JackRequest::kConnectPorts: {
210 jack_log(
"JackRequest::ConnectPorts");
211 JackPortConnectRequest req;
213 if (req.Read(fPipe) == 0)
214 res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
219 case JackRequest::kDisconnectPorts: {
220 jack_log(
"JackRequest::DisconnectPorts");
221 JackPortDisconnectRequest req;
223 if (req.Read(fPipe) == 0)
224 res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
229 case JackRequest::kPortRename: {
230 jack_log(
"JackRequest::PortRename");
231 JackPortRenameRequest req;
233 if (req.Read(fPipe) == 0)
234 res.fResult = fServer->GetEngine()->PortRename(req.fRefNum, req.fPort, req.fName);
239 case JackRequest::kSetBufferSize: {
240 jack_log(
"JackRequest::SetBufferSize");
241 JackSetBufferSizeRequest req;
243 if (req.Read(fPipe) == 0)
244 res.fResult = fServer->SetBufferSize(req.fBufferSize);
249 case JackRequest::kSetFreeWheel: {
250 jack_log(
"JackRequest::SetFreeWheel");
251 JackSetFreeWheelRequest req;
253 if (req.Read(fPipe) == 0)
254 res.fResult = fServer->SetFreewheel(req.fOnOff);
259 case JackRequest::kComputeTotalLatencies: {
260 jack_log(
"JackRequest::ComputeTotalLatencies");
261 JackComputeTotalLatenciesRequest req;
263 if (req.Read(fPipe) == 0)
264 res.fResult = fServer->GetEngine()->ComputeTotalLatencies();
269 case JackRequest::kReleaseTimebase: {
270 jack_log(
"JackRequest::ReleaseTimebase");
271 JackReleaseTimebaseRequest req;
273 if (req.Read(fPipe) == 0)
274 res.fResult = fServer->ReleaseTimebase(req.fRefNum);
279 case JackRequest::kSetTimebaseCallback: {
280 jack_log(
"JackRequest::SetTimebaseCallback");
281 JackSetTimebaseCallbackRequest req;
283 if (req.Read(fPipe) == 0)
284 res.fResult = fServer->SetTimebaseCallback(req.fRefNum, req.fConditionnal);
289 case JackRequest::kGetInternalClientName: {
290 jack_log(
"JackRequest::GetInternalClientName");
291 JackGetInternalClientNameRequest req;
292 JackGetInternalClientNameResult res;
293 if (req.Read(fPipe) == 0)
294 res.fResult = fServer->GetEngine()->GetInternalClientName(req.fIntRefNum, res.fName);
299 case JackRequest::kInternalClientHandle: {
300 jack_log(
"JackRequest::InternalClientHandle");
301 JackInternalClientHandleRequest req;
302 JackInternalClientHandleResult res;
303 if (req.Read(fPipe) == 0)
304 res.fResult = fServer->GetEngine()->InternalClientHandle(req.fName, &res.fStatus, &res.fIntRefNum);
309 case JackRequest::kInternalClientLoad: {
310 jack_log(
"JackRequest::InternalClientLoad");
311 JackInternalClientLoadRequest req;
312 JackInternalClientLoadResult res;
313 if (req.Read(fPipe) == 0)
314 res.fResult = fServer->InternalClientLoad1(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus);
319 case JackRequest::kInternalClientUnload: {
320 jack_log(
"JackRequest::InternalClientUnload");
321 JackInternalClientUnloadRequest req;
322 JackInternalClientUnloadResult res;
323 if (req.Read(fPipe) == 0)
324 res.fResult = fServer->GetEngine()->InternalClientUnload(req.fIntRefNum, &res.fStatus);
329 case JackRequest::kNotification: {
330 jack_log(
"JackRequest::Notification");
331 JackClientNotificationRequest req;
332 if (req.Read(fPipe) == 0) {
333 if (req.fNotify == kQUIT) {
334 jack_log(
"JackRequest::Notification kQUIT");
335 throw JackQuitException();
337 fServer->Notify(req.fRefNum, req.fNotify, req.fValue);
343 case JackRequest::kSessionNotify: {
344 jack_log(
"JackRequest::SessionNotify");
345 JackSessionNotifyRequest req;
346 if (req.Read(fPipe) == 0) {
347 fServer->GetEngine()->SessionNotify(req.fRefNum, req.fDst, req.fEventType, req.fPath, fPipe, NULL);
352 case JackRequest::kSessionReply: {
353 jack_log(
"JackRequest::SessionReply");
354 JackSessionReplyRequest req;
356 if (req.Read(fPipe) == 0) {
357 fServer->GetEngine()->SessionReply(req.fRefNum);
364 case JackRequest::kGetClientByUUID: {
365 jack_log(
"JackRequest::GetClientByUUID");
366 JackGetClientNameRequest req;
367 JackClientNameResult res;
368 if (req.Read(fPipe) == 0) {
369 fServer->GetEngine()->GetClientNameForUUID(req.fUUID, res.fName, &res.fResult);
375 case JackRequest::kGetUUIDByClient: {
376 jack_log(
"JackRequest::GetUUIDByClient");
377 JackGetUUIDRequest req;
379 if (req.Read(fPipe) == 0) {
380 fServer->GetEngine()->GetUUIDForClientName(req.fName, res.fUUID, &res.fResult);
386 case JackRequest::kReserveClientName: {
387 jack_log(
"JackRequest::ReserveClientName");
388 JackReserveNameRequest req;
390 if (req.Read(fPipe) == 0) {
391 fServer->GetEngine()->ReserveClientName(req.fName, req.fUUID, &res.fResult);
397 case JackRequest::kClientHasSessionCallback: {
398 jack_log(
"JackRequest::ClientHasSessionCallback");
399 JackClientHasSessionCallbackRequest req;
401 if (req.Read(fPipe) == 0) {
402 fServer->GetEngine()->ClientHasSessionCallback(req.fName, &res.fResult);
409 jack_log(
"Unknown request %ld", header.fType);
415 ReleaseMutex(fMutex);
419 void JackClientPipeThread::ClientAdd(
char* name,
int pid,
int uuid,
int* shared_engine,
int* shared_client,
int* shared_graph,
int* result)
421 jack_log(
"JackClientPipeThread::ClientAdd %s", name);
423 *result = fServer->GetEngine()->ClientExternalOpen(name, pid, uuid, &fRefNum, shared_engine, shared_client, shared_graph);
426 void JackClientPipeThread::ClientRemove()
428 jack_log(
"JackClientPipeThread::ClientRemove ref = %d", fRefNum);
436 void JackClientPipeThread::ClientKill()
438 jack_log(
"JackClientPipeThread::ClientKill ref = %d", fRefNum);
442 }
else if (fRefNum == 0) {
443 jack_log(
"Kill a not opened client");
445 fServer->ClientKill(fRefNum);
451 JackWinNamedPipeServerChannel::JackWinNamedPipeServerChannel():fThread(this)
454 JackWinNamedPipeServerChannel::~JackWinNamedPipeServerChannel()
456 std::list<JackClientPipeThread*>::iterator it;
458 for (it = fClientList.begin(); it != fClientList.end(); it++) {
459 JackClientPipeThread* client = *it;
465 int JackWinNamedPipeServerChannel::Open(
const char* server_name, JackServer* server)
467 jack_log(
"JackWinNamedPipeServerChannel::Open ");
468 snprintf(fServerName,
sizeof(fServerName), server_name);
471 if (fRequestListenPipe.Bind(jack_server_dir, server_name, 0) < 0) {
472 jack_error(
"JackWinNamedPipeServerChannel::Open : cannot create result listen pipe");
480 void JackWinNamedPipeServerChannel::Close()
490 fRequestListenPipe.Close();
493 int JackWinNamedPipeServerChannel::Start()
495 if (fThread.Start() != 0) {
496 jack_error(
"Cannot start Jack server listener");
503 void JackWinNamedPipeServerChannel::Stop()
510 jack_log(
"JackWinNamedPipeServerChannel::Init ");
514 if ((pipe = fRequestListenPipe.AcceptClient()) == NULL) {
515 jack_error(
"JackWinNamedPipeServerChannel::Init : cannot connect pipe");
523 bool JackWinNamedPipeServerChannel::Execute()
527 if (fRequestListenPipe.Bind(jack_server_dir, fServerName, 0) < 0) {
528 jack_error(
"JackWinNamedPipeServerChannel::Open : cannot create result listen pipe");
532 if ((pipe = fRequestListenPipe.AcceptClient()) == NULL) {
533 jack_error(
"JackWinNamedPipeServerChannel::Open : cannot connect pipe");
541 void JackWinNamedPipeServerChannel::ClientAdd(JackWinNamedPipeClient* pipe)
544 std::list<JackClientPipeThread*>::iterator it = fClientList.begin();
545 JackClientPipeThread* client;
547 jack_log(
"ClientAdd size %ld", fClientList.size());
549 while (it != fClientList.end()) {
551 jack_log(
"Remove dead client = %x running = %ld", client, client->IsRunning());
552 if (client->IsRunning()) {
555 it = fClientList.erase(it);
560 client =
new JackClientPipeThread(pipe);
561 client->Open(fServer);
563 fClientList.push_back(client);