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