00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JackWinNamedPipeServerChannel.h"
00022 #include "JackNotification.h"
00023 #include "JackRequest.h"
00024 #include "JackServer.h"
00025 #include "JackLockedEngine.h"
00026 #include "JackGlobals.h"
00027 #include "JackClient.h"
00028 #include "JackNotification.h"
00029 #include "JackException.h"
00030 #include <assert.h>
00031
00032 using namespace std;
00033
00034 namespace Jack
00035 {
00036
00037 HANDLE JackClientPipeThread::fMutex = NULL;
00038
00039
00040
00041 JackClientPipeThread::JackClientPipeThread(JackWinNamedPipeClient* pipe)
00042 :fPipe(pipe), fServer(NULL), fThread(this), fRefNum(0)
00043 {
00044
00045 if (fMutex == NULL) {
00046 fMutex = CreateMutex(NULL, FALSE, NULL);
00047 }
00048 }
00049
00050 JackClientPipeThread::~JackClientPipeThread()
00051 {
00052 jack_log("JackClientPipeThread::~JackClientPipeThread");
00053 delete fPipe;
00054 }
00055
00056 int JackClientPipeThread::Open(JackServer* server)
00057 {
00058
00059 if (fThread.Start() != 0) {
00060 jack_error("Cannot start Jack server listener\n");
00061 return -1;
00062 }
00063
00064 fServer = server;
00065 return 0;
00066 }
00067
00068 void JackClientPipeThread::Close()
00069 {
00070 jack_log("JackClientPipeThread::Close %x %ld", this, fRefNum);
00071
00072
00073
00074
00075
00076
00077 fThread.Kill();
00078 fPipe->Close();
00079 fRefNum = -1;
00080 }
00081
00082 bool JackClientPipeThread::Execute()
00083 {
00084 try{
00085 jack_log("JackClientPipeThread::Execute");
00086 return (HandleRequest());
00087 } catch (JackQuitException& e) {
00088 jack_log("JackClientPipeThread::Execute JackQuitException");
00089 return false;
00090 }
00091 }
00092
00093 bool JackClientPipeThread::HandleRequest()
00094 {
00095
00096 JackRequest header;
00097 int res = header.Read(fPipe);
00098 bool ret = true;
00099
00100
00101 if (WaitForSingleObject(fMutex, INFINITE) == WAIT_FAILED) {
00102 jack_error("JackClientPipeThread::HandleRequest: mutex wait error");
00103 }
00104
00105 if (res < 0) {
00106 jack_error("HandleRequest: cannot read header");
00107 ClientKill();
00108 ret = false;
00109 } else {
00110
00111
00112 switch (header.fType) {
00113
00114 case JackRequest::kClientCheck: {
00115 jack_log("JackRequest::ClientCheck");
00116 JackClientCheckRequest req;
00117 JackClientCheckResult res;
00118 if (req.Read(fPipe) == 0)
00119 res.fResult = fServer->GetEngine()->ClientCheck(req.fName, req.fUUID, res.fName, req.fProtocol, req.fOptions, &res.fStatus);
00120 res.Write(fPipe);
00121
00122 if (req.fOpen)
00123 HandleRequest();
00124 break;
00125 }
00126
00127 case JackRequest::kClientOpen: {
00128 jack_log("JackRequest::ClientOpen");
00129 JackClientOpenRequest req;
00130 JackClientOpenResult res;
00131 if (req.Read(fPipe) == 0)
00132 ClientAdd(req.fName, req.fPID, req.fUUID, &res.fSharedEngine, &res.fSharedClient, &res.fSharedGraph, &res.fResult);
00133 res.Write(fPipe);
00134 break;
00135 }
00136
00137 case JackRequest::kClientClose: {
00138 jack_log("JackRequest::ClientClose");
00139 JackClientCloseRequest req;
00140 JackResult res;
00141 if (req.Read(fPipe) == 0)
00142 res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum);
00143 res.Write(fPipe);
00144 ClientRemove();
00145 ret = false;
00146 break;
00147 }
00148
00149 case JackRequest::kActivateClient: {
00150 JackActivateRequest req;
00151 JackResult res;
00152 jack_log("JackRequest::ActivateClient");
00153 if (req.Read(fPipe) == 0)
00154 res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum, req.fIsRealTime);
00155 res.Write(fPipe);
00156 break;
00157 }
00158
00159 case JackRequest::kDeactivateClient: {
00160 jack_log("JackRequest::DeactivateClient");
00161 JackDeactivateRequest req;
00162 JackResult res;
00163 if (req.Read(fPipe) == 0)
00164 res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum);
00165 res.Write(fPipe);
00166 break;
00167 }
00168
00169 case JackRequest::kRegisterPort: {
00170 jack_log("JackRequest::RegisterPort");
00171 JackPortRegisterRequest req;
00172 JackPortRegisterResult res;
00173 if (req.Read(fPipe) == 0)
00174 res.fResult = fServer->GetEngine()->PortRegister(req.fRefNum, req.fName, req.fPortType, req.fFlags, req.fBufferSize, &res.fPortIndex);
00175 res.Write(fPipe);
00176 break;
00177 }
00178
00179 case JackRequest::kUnRegisterPort: {
00180 jack_log("JackRequest::UnRegisterPort");
00181 JackPortUnRegisterRequest req;
00182 JackResult res;
00183 if (req.Read(fPipe) == 0)
00184 res.fResult = fServer->GetEngine()->PortUnRegister(req.fRefNum, req.fPortIndex);
00185 res.Write(fPipe);
00186 break;
00187 }
00188
00189 case JackRequest::kConnectNamePorts: {
00190 jack_log("JackRequest::ConnectNamePorts");
00191 JackPortConnectNameRequest req;
00192 JackResult res;
00193 if (req.Read(fPipe) == 0)
00194 res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
00195 res.Write(fPipe);
00196 break;
00197 }
00198
00199 case JackRequest::kDisconnectNamePorts: {
00200 jack_log("JackRequest::DisconnectNamePorts");
00201 JackPortDisconnectNameRequest req;
00202 JackResult res;
00203 if (req.Read(fPipe) == 0)
00204 res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
00205 res.Write(fPipe);
00206 break;
00207 }
00208
00209 case JackRequest::kConnectPorts: {
00210 jack_log("JackRequest::ConnectPorts");
00211 JackPortConnectRequest req;
00212 JackResult res;
00213 if (req.Read(fPipe) == 0)
00214 res.fResult = fServer->GetEngine()->PortConnect(req.fRefNum, req.fSrc, req.fDst);
00215 res.Write(fPipe);
00216 break;
00217 }
00218
00219 case JackRequest::kDisconnectPorts: {
00220 jack_log("JackRequest::DisconnectPorts");
00221 JackPortDisconnectRequest req;
00222 JackResult res;
00223 if (req.Read(fPipe) == 0)
00224 res.fResult = fServer->GetEngine()->PortDisconnect(req.fRefNum, req.fSrc, req.fDst);
00225 res.Write(fPipe);
00226 break;
00227 }
00228
00229 case JackRequest::kPortRename: {
00230 jack_log("JackRequest::PortRename");
00231 JackPortRenameRequest req;
00232 JackResult res;
00233 if (req.Read(fPipe) == 0)
00234 res.fResult = fServer->GetEngine()->PortRename(req.fRefNum, req.fPort, req.fName);
00235 res.Write(fPipe);
00236 break;
00237 }
00238
00239 case JackRequest::kSetBufferSize: {
00240 jack_log("JackRequest::SetBufferSize");
00241 JackSetBufferSizeRequest req;
00242 JackResult res;
00243 if (req.Read(fPipe) == 0)
00244 res.fResult = fServer->SetBufferSize(req.fBufferSize);
00245 res.Write(fPipe);
00246 break;
00247 }
00248
00249 case JackRequest::kSetFreeWheel: {
00250 jack_log("JackRequest::SetFreeWheel");
00251 JackSetFreeWheelRequest req;
00252 JackResult res;
00253 if (req.Read(fPipe) == 0)
00254 res.fResult = fServer->SetFreewheel(req.fOnOff);
00255 res.Write(fPipe);
00256 break;
00257 }
00258
00259 case JackRequest::kComputeTotalLatencies: {
00260 jack_log("JackRequest::ComputeTotalLatencies");
00261 JackComputeTotalLatenciesRequest req;
00262 JackResult res;
00263 if (req.Read(fPipe) == 0)
00264 res.fResult = fServer->GetEngine()->ComputeTotalLatencies();
00265 res.Write(fPipe);
00266 break;
00267 }
00268
00269 case JackRequest::kReleaseTimebase: {
00270 jack_log("JackRequest::ReleaseTimebase");
00271 JackReleaseTimebaseRequest req;
00272 JackResult res;
00273 if (req.Read(fPipe) == 0)
00274 res.fResult = fServer->ReleaseTimebase(req.fRefNum);
00275 res.Write(fPipe);
00276 break;
00277 }
00278
00279 case JackRequest::kSetTimebaseCallback: {
00280 jack_log("JackRequest::SetTimebaseCallback");
00281 JackSetTimebaseCallbackRequest req;
00282 JackResult res;
00283 if (req.Read(fPipe) == 0)
00284 res.fResult = fServer->SetTimebaseCallback(req.fRefNum, req.fConditionnal);
00285 res.Write(fPipe);
00286 break;
00287 }
00288
00289 case JackRequest::kGetInternalClientName: {
00290 jack_log("JackRequest::GetInternalClientName");
00291 JackGetInternalClientNameRequest req;
00292 JackGetInternalClientNameResult res;
00293 if (req.Read(fPipe) == 0)
00294 res.fResult = fServer->GetEngine()->GetInternalClientName(req.fIntRefNum, res.fName);
00295 res.Write(fPipe);
00296 break;
00297 }
00298
00299 case JackRequest::kInternalClientHandle: {
00300 jack_log("JackRequest::InternalClientHandle");
00301 JackInternalClientHandleRequest req;
00302 JackInternalClientHandleResult res;
00303 if (req.Read(fPipe) == 0)
00304 res.fResult = fServer->GetEngine()->InternalClientHandle(req.fName, &res.fStatus, &res.fIntRefNum);
00305 res.Write(fPipe);
00306 break;
00307 }
00308
00309 case JackRequest::kInternalClientLoad: {
00310 jack_log("JackRequest::InternalClientLoad");
00311 JackInternalClientLoadRequest req;
00312 JackInternalClientLoadResult res;
00313 if (req.Read(fPipe) == 0)
00314 res.fResult = fServer->InternalClientLoad1(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, req.fUUID, &res.fStatus);
00315 res.Write(fPipe);
00316 break;
00317 }
00318
00319 case JackRequest::kInternalClientUnload: {
00320 jack_log("JackRequest::InternalClientUnload");
00321 JackInternalClientUnloadRequest req;
00322 JackInternalClientUnloadResult res;
00323 if (req.Read(fPipe) == 0)
00324 res.fResult = fServer->GetEngine()->InternalClientUnload(req.fIntRefNum, &res.fStatus);
00325 res.Write(fPipe);
00326 break;
00327 }
00328
00329 case JackRequest::kNotification: {
00330 jack_log("JackRequest::Notification");
00331 JackClientNotificationRequest req;
00332 if (req.Read(fPipe) == 0) {
00333 if (req.fNotify == kQUIT) {
00334 jack_log("JackRequest::Notification kQUIT");
00335 throw JackQuitException();
00336 } else {
00337 fServer->Notify(req.fRefNum, req.fNotify, req.fValue);
00338 }
00339 }
00340 break;
00341 }
00342
00343 case JackRequest::kSessionNotify: {
00344 jack_log("JackRequest::SessionNotify");
00345 JackSessionNotifyRequest req;
00346 if (req.Read(fPipe) == 0) {
00347 fServer->GetEngine()->SessionNotify(req.fRefNum, req.fDst, req.fEventType, req.fPath, fPipe, NULL);
00348 }
00349 break;
00350 }
00351
00352 case JackRequest::kSessionReply: {
00353 jack_log("JackRequest::SessionReply");
00354 JackSessionReplyRequest req;
00355 JackResult res;
00356 if (req.Read(fPipe) == 0) {
00357 fServer->GetEngine()->SessionReply(req.fRefNum);
00358 res.fResult = 0;
00359 }
00360 res.Write(fPipe);
00361 break;
00362 }
00363
00364 case JackRequest::kGetClientByUUID: {
00365 jack_log("JackRequest::GetClientByUUID");
00366 JackGetClientNameRequest req;
00367 JackClientNameResult res;
00368 if (req.Read(fPipe) == 0) {
00369 fServer->GetEngine()->GetClientNameForUUID(req.fUUID, res.fName, &res.fResult);
00370 }
00371 res.Write(fPipe);
00372 break;
00373 }
00374
00375 case JackRequest::kGetUUIDByClient: {
00376 jack_log("JackRequest::GetUUIDByClient");
00377 JackGetUUIDRequest req;
00378 JackUUIDResult res;
00379 if (req.Read(fPipe) == 0) {
00380 fServer->GetEngine()->GetUUIDForClientName(req.fName, res.fUUID, &res.fResult);
00381 }
00382 res.Write(fPipe);
00383 break;
00384 }
00385
00386 case JackRequest::kReserveClientName: {
00387 jack_log("JackRequest::ReserveClientName");
00388 JackReserveNameRequest req;
00389 JackResult res;
00390 if (req.Read(fPipe) == 0) {
00391 fServer->GetEngine()->ReserveClientName(req.fName, req.fUUID, &res.fResult);
00392 }
00393 res.Write(fPipe);
00394 break;
00395 }
00396
00397 case JackRequest::kClientHasSessionCallback: {
00398 jack_log("JackRequest::ClientHasSessionCallback");
00399 JackClientHasSessionCallbackRequest req;
00400 JackResult res;
00401 if (req.Read(fPipe) == 0) {
00402 fServer->GetEngine()->ClientHasSessionCallback(req.fName, &res.fResult);
00403 }
00404 res.Write(fPipe);
00405 break;
00406 }
00407
00408 default:
00409 jack_log("Unknown request %ld", header.fType);
00410 break;
00411 }
00412 }
00413
00414
00415 ReleaseMutex(fMutex);
00416 return ret;
00417 }
00418
00419 void JackClientPipeThread::ClientAdd(char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result)
00420 {
00421 jack_log("JackClientPipeThread::ClientAdd %s", name);
00422 fRefNum = -1;
00423 *result = fServer->GetEngine()->ClientExternalOpen(name, pid, uuid, &fRefNum, shared_engine, shared_client, shared_graph);
00424 }
00425
00426 void JackClientPipeThread::ClientRemove()
00427 {
00428 jack_log("JackClientPipeThread::ClientRemove ref = %d", fRefNum);
00429
00430
00431
00432 fRefNum = -1;
00433 fPipe->Close();
00434 }
00435
00436 void JackClientPipeThread::ClientKill()
00437 {
00438 jack_log("JackClientPipeThread::ClientKill ref = %d", fRefNum);
00439
00440 if (fRefNum == -1) {
00441 jack_log("Kill a closed client");
00442 } else if (fRefNum == 0) {
00443 jack_log("Kill a not opened client");
00444 } else {
00445 fServer->ClientKill(fRefNum);
00446 }
00447
00448 Close();
00449 }
00450
00451 JackWinNamedPipeServerChannel::JackWinNamedPipeServerChannel():fThread(this)
00452 {}
00453
00454 JackWinNamedPipeServerChannel::~JackWinNamedPipeServerChannel()
00455 {
00456 std::list<JackClientPipeThread*>::iterator it;
00457
00458 for (it = fClientList.begin(); it != fClientList.end(); it++) {
00459 JackClientPipeThread* client = *it;
00460 client->Close();
00461 delete client;
00462 }
00463 }
00464
00465 int JackWinNamedPipeServerChannel::Open(const char* server_name, JackServer* server)
00466 {
00467 jack_log("JackWinNamedPipeServerChannel::Open ");
00468 snprintf(fServerName, sizeof(fServerName), server_name);
00469
00470
00471 if (fRequestListenPipe.Bind(jack_server_dir, server_name, 0) < 0) {
00472 jack_error("JackWinNamedPipeServerChannel::Open : cannot create result listen pipe");
00473 return -1;
00474 }
00475
00476 fServer = server;
00477 return 0;
00478 }
00479
00480 void JackWinNamedPipeServerChannel::Close()
00481 {
00482
00483
00484
00485
00486
00487
00488
00489
00490 fRequestListenPipe.Close();
00491 }
00492
00493 int JackWinNamedPipeServerChannel::Start()
00494 {
00495 if (fThread.Start() != 0) {
00496 jack_error("Cannot start Jack server listener");
00497 return -1;
00498 } else {
00499 return 0;
00500 }
00501 }
00502
00503 void JackWinNamedPipeServerChannel::Stop()
00504 {
00505 fThread.Kill();
00506 }
00507
00508 bool JackWinNamedPipeServerChannel::Init()
00509 {
00510 jack_log("JackWinNamedPipeServerChannel::Init ");
00511 JackWinNamedPipeClient* pipe;
00512
00513
00514 if ((pipe = fRequestListenPipe.AcceptClient()) == NULL) {
00515 jack_error("JackWinNamedPipeServerChannel::Init : cannot connect pipe");
00516 return false;
00517 } else {
00518 ClientAdd(pipe);
00519 return true;
00520 }
00521 }
00522
00523 bool JackWinNamedPipeServerChannel::Execute()
00524 {
00525 JackWinNamedPipeClient* pipe;
00526
00527 if (fRequestListenPipe.Bind(jack_server_dir, fServerName, 0) < 0) {
00528 jack_error("JackWinNamedPipeServerChannel::Open : cannot create result listen pipe");
00529 return false;
00530 }
00531
00532 if ((pipe = fRequestListenPipe.AcceptClient()) == NULL) {
00533 jack_error("JackWinNamedPipeServerChannel::Open : cannot connect pipe");
00534 return false;
00535 }
00536
00537 ClientAdd(pipe);
00538 return true;
00539 }
00540
00541 void JackWinNamedPipeServerChannel::ClientAdd(JackWinNamedPipeClient* pipe)
00542 {
00543
00544 std::list<JackClientPipeThread*>::iterator it = fClientList.begin();
00545 JackClientPipeThread* client;
00546
00547 jack_log("ClientAdd size %ld", fClientList.size());
00548
00549 while (it != fClientList.end()) {
00550 client = *it;
00551 jack_log("Remove dead client = %x running = %ld", client, client->IsRunning());
00552 if (client->IsRunning()) {
00553 it++;
00554 } else {
00555 it = fClientList.erase(it);
00556 delete client;
00557 }
00558 }
00559
00560 client = new JackClientPipeThread(pipe);
00561 client->Open(fServer);
00562
00563 fClientList.push_back(client);
00564 }
00565
00566 }
00567
00568