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