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, 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, &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::kReleaseTimebase: {
00256 jack_log("JackRequest::ReleaseTimebase");
00257 JackReleaseTimebaseRequest req;
00258 JackResult res;
00259 if (req.Read(fPipe) == 0)
00260 res.fResult = fServer->ReleaseTimebase(req.fRefNum);
00261 res.Write(fPipe);
00262 break;
00263 }
00264
00265 case JackRequest::kSetTimebaseCallback: {
00266 jack_log("JackRequest::SetTimebaseCallback");
00267 JackSetTimebaseCallbackRequest req;
00268 JackResult res;
00269 if (req.Read(fPipe) == 0)
00270 res.fResult = fServer->SetTimebaseCallback(req.fRefNum, req.fConditionnal);
00271 res.Write(fPipe);
00272 break;
00273 }
00274
00275 case JackRequest::kGetInternalClientName: {
00276 jack_log("JackRequest::GetInternalClientName");
00277 JackGetInternalClientNameRequest req;
00278 JackGetInternalClientNameResult res;
00279 if (req.Read(fPipe) == 0)
00280 res.fResult = fServer->GetEngine()->GetInternalClientName(req.fIntRefNum, res.fName);
00281 res.Write(fPipe);
00282 break;
00283 }
00284
00285 case JackRequest::kInternalClientHandle: {
00286 jack_log("JackRequest::InternalClientHandle");
00287 JackInternalClientHandleRequest req;
00288 JackInternalClientHandleResult res;
00289 if (req.Read(fPipe) == 0)
00290 res.fResult = fServer->GetEngine()->InternalClientHandle(req.fName, &res.fStatus, &res.fIntRefNum);
00291 res.Write(fPipe);
00292 break;
00293 }
00294
00295 case JackRequest::kInternalClientLoad: {
00296 jack_log("JackRequest::InternalClientLoad");
00297 JackInternalClientLoadRequest req;
00298 JackInternalClientLoadResult res;
00299 if (req.Read(fPipe) == 0)
00300 res.fResult = fServer->InternalClientLoad(req.fName, req.fDllName, req.fLoadInitName, req.fOptions, &res.fIntRefNum, &res.fStatus);
00301 res.Write(fPipe);
00302 break;
00303 }
00304
00305 case JackRequest::kInternalClientUnload: {
00306 jack_log("JackRequest::InternalClientUnload");
00307 JackInternalClientUnloadRequest req;
00308 JackInternalClientUnloadResult res;
00309 if (req.Read(fPipe) == 0)
00310 res.fResult = fServer->GetEngine()->InternalClientUnload(req.fIntRefNum, &res.fStatus);
00311 res.Write(fPipe);
00312 break;
00313 }
00314
00315 case JackRequest::kNotification: {
00316 jack_log("JackRequest::Notification");
00317 JackClientNotificationRequest req;
00318 if (req.Read(fPipe) == 0) {
00319 if (req.fNotify == kQUIT) {
00320 jack_log("JackRequest::Notification kQUIT");
00321 throw JackQuitException();
00322 } else {
00323 fServer->Notify(req.fRefNum, req.fNotify, req.fValue);
00324 }
00325 }
00326 break;
00327 }
00328
00329 default:
00330 jack_log("Unknown request %ld", header.fType);
00331 break;
00332 }
00333 }
00334
00335
00336 ReleaseMutex(fMutex);
00337 return ret;
00338 }
00339
00340 void JackClientPipeThread::ClientAdd(char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result)
00341 {
00342 jack_log("JackClientPipeThread::ClientAdd %s", name);
00343 fRefNum = -1;
00344 *result = fServer->GetEngine()->ClientExternalOpen(name, pid, &fRefNum, shared_engine, shared_client, shared_graph);
00345 }
00346
00347 void JackClientPipeThread::ClientRemove()
00348 {
00349 jack_log("JackClientPipeThread::ClientRemove ref = %d", fRefNum);
00350
00351
00352
00353 fRefNum = -1;
00354 fPipe->Close();
00355 }
00356
00357 void JackClientPipeThread::ClientKill()
00358 {
00359 jack_log("JackClientPipeThread::ClientKill ref = %d", fRefNum);
00360
00361 if (fRefNum == -1) {
00362 jack_log("Kill a closed client");
00363 } else if (fRefNum == 0) {
00364 jack_log("Kill a not opened client");
00365 } else {
00366 fServer->ClientKill(fRefNum);
00367 }
00368
00369 Close();
00370 }
00371
00372 JackWinNamedPipeServerChannel::JackWinNamedPipeServerChannel():fThread(this)
00373 {}
00374
00375 JackWinNamedPipeServerChannel::~JackWinNamedPipeServerChannel()
00376 {
00377 std::list<JackClientPipeThread*>::iterator it;
00378
00379 for (it = fClientList.begin(); it != fClientList.end(); it++) {
00380 JackClientPipeThread* client = *it;
00381 client->Close();
00382 delete client;
00383 }
00384 }
00385
00386 int JackWinNamedPipeServerChannel::Open(const char* server_name, JackServer* server)
00387 {
00388 jack_log("JackWinNamedPipeServerChannel::Open ");
00389 snprintf(fServerName, sizeof(fServerName), server_name);
00390
00391
00392 if (fRequestListenPipe.Bind(jack_server_dir, server_name, 0) < 0) {
00393 jack_error("JackWinNamedPipeServerChannel::Open : cannot create result listen pipe");
00394 return -1;
00395 }
00396
00397 fServer = server;
00398 return 0;
00399 }
00400
00401 void JackWinNamedPipeServerChannel::Close()
00402 {
00403
00404
00405
00406
00407
00408
00409
00410
00411 fThread.Kill();
00412 fRequestListenPipe.Close();
00413 }
00414
00415 int JackWinNamedPipeServerChannel::Start()
00416 {
00417 if (fThread.Start() != 0) {
00418 jack_error("Cannot start Jack server listener");
00419 return -1;
00420 }
00421
00422 return 0;
00423 }
00424
00425 bool JackWinNamedPipeServerChannel::Init()
00426 {
00427 jack_log("JackWinNamedPipeServerChannel::Init ");
00428 JackWinNamedPipeClient* pipe;
00429
00430
00431 if ((pipe = fRequestListenPipe.AcceptClient()) == NULL) {
00432 jack_error("JackWinNamedPipeServerChannel::Init : cannot connect pipe");
00433 return false;
00434 } else {
00435 ClientAdd(pipe);
00436 return true;
00437 }
00438 }
00439
00440 bool JackWinNamedPipeServerChannel::Execute()
00441 {
00442 JackWinNamedPipeClient* pipe;
00443
00444 if (fRequestListenPipe.Bind(jack_server_dir, fServerName, 0) < 0) {
00445 jack_error("JackWinNamedPipeServerChannel::Open : cannot create result listen pipe");
00446 return false;
00447 }
00448
00449 if ((pipe = fRequestListenPipe.AcceptClient()) == NULL) {
00450 jack_error("JackWinNamedPipeServerChannel::Open : cannot connect pipe");
00451 return false;
00452 }
00453
00454 ClientAdd(pipe);
00455 return true;
00456 }
00457
00458 void JackWinNamedPipeServerChannel::ClientAdd(JackWinNamedPipeClient* pipe)
00459 {
00460
00461 std::list<JackClientPipeThread*>::iterator it = fClientList.begin();
00462 JackClientPipeThread* client;
00463
00464 jack_log("ClientAdd size %ld", fClientList.size());
00465
00466 while (it != fClientList.end()) {
00467 client = *it;
00468 jack_log("Remove dead client = %x running = %ld", client, client->IsRunning());
00469 if (client->IsRunning()) {
00470 it++;
00471 } else {
00472 it = fClientList.erase(it);
00473 delete client;
00474 }
00475 }
00476
00477 client = new JackClientPipeThread(pipe);
00478 client->Open(fServer);
00479
00480 fClientList.push_back(client);
00481 }
00482
00483 }
00484
00485