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