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