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