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