00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JackWinNamedPipeServerChannel.h"
00022 #include "JackNotification.h"
00023 #include "JackRequest.h"
00024 #include "JackServer.h"
00025 #include "JackLockedEngine.h"
00026 #include "JackGlobals.h"
00027 #include "JackClient.h"
00028 #include "JackNotification.h"
00029 #include "JackException.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), fDecoder(NULL), fServer(NULL), fThread(this), fRefNum(0)
00043 {
00044
00045 if (fMutex == NULL) {
00046 fMutex = CreateMutex(NULL, FALSE, NULL);
00047 }
00048 }
00049
00050 JackClientPipeThread::~JackClientPipeThread()
00051 {
00052 jack_log("JackClientPipeThread::~JackClientPipeThread");
00053 delete fPipe;
00054 }
00055
00056 int JackClientPipeThread::Open(JackServer* server)
00057 {
00058
00059 if (fThread.Start() != 0) {
00060 jack_error("Cannot start Jack server listener\n");
00061 return -1;
00062 } else {
00063 fDecoder = new JackRequestDecoder(server, this);
00064 fServer = server;
00065 return 0;
00066 }
00067 }
00068
00069 void JackClientPipeThread::Close()
00070 {
00071 jack_log("JackClientPipeThread::Close 0 %x %ld", this, fRefNum);
00072
00073
00074 fPipe->Close();
00075 fRefNum = -1;
00076
00077 delete fDecoder;
00078 fDecoder = NULL;
00079 }
00080
00081 bool JackClientPipeThread::Execute()
00082 {
00083 try {
00084
00085 jack_log("JackClientPipeThread::Execute %x", this);
00086 JackRequest header;
00087 int res = header.Read(fPipe);
00088 bool ret = true;
00089
00090
00091 if (WaitForSingleObject(fMutex, INFINITE) == WAIT_FAILED) {
00092 jack_error("JackClientPipeThread::Execute : mutex wait error");
00093 }
00094
00095
00096 if (res < 0) {
00097 jack_log("JackClientPipeThread::Execute : cannot decode header");
00098 ClientKill();
00099 ret = false;
00100
00101 } else if (fDecoder->HandleRequest(fPipe, header.fType) < 0) {
00102 ret = false;
00103 }
00104
00105
00106 if (!ReleaseMutex(fMutex)) {
00107 jack_error("JackClientPipeThread::Execute : mutex release error");
00108 }
00109 return ret;
00110
00111 } catch (JackQuitException& e) {
00112 jack_log("JackClientPipeThread::Execute : JackQuitException");
00113 return false;
00114 }
00115 }
00116
00117 void JackClientPipeThread::ClientAdd(detail::JackChannelTransactionInterface* socket, JackClientOpenRequest* req, JackClientOpenResult *res)
00118 {
00119 jack_log("JackClientPipeThread::ClientAdd %x %s", this, req->fName);
00120 fRefNum = -1;
00121 res->fResult = fServer->GetEngine()->ClientExternalOpen(req->fName, req->fPID, req->fUUID, &fRefNum, &res->fSharedEngine, &res->fSharedClient, &res->fSharedGraph);
00122 }
00123
00124 void JackClientPipeThread::ClientRemove(detail::JackChannelTransactionInterface* socket_aux, int refnum)
00125 {
00126 jack_log("JackClientPipeThread::ClientRemove ref = %d", refnum);
00127 Close();
00128 }
00129
00130 void JackClientPipeThread::ClientKill()
00131 {
00132 jack_log("JackClientPipeThread::ClientKill ref = %d", fRefNum);
00133
00134 if (fRefNum == -1) {
00135 jack_log("Kill a closed client %x", this);
00136 } else if (fRefNum == 0) {
00137 jack_log("Kill a not opened client %x", this);
00138 } else {
00139 fServer->GetEngine()->ClientKill(fRefNum);
00140 }
00141
00142 Close();
00143 }
00144
00145 JackWinNamedPipeServerChannel::JackWinNamedPipeServerChannel():fThread(this)
00146 {}
00147
00148 JackWinNamedPipeServerChannel::~JackWinNamedPipeServerChannel()
00149 {
00150 std::list<JackClientPipeThread*>::iterator it;
00151
00152 for (it = fClientList.begin(); it != fClientList.end(); it++) {
00153 JackClientPipeThread* client = *it;
00154 client->Close();
00155 delete client;
00156 }
00157 }
00158
00159 int JackWinNamedPipeServerChannel::Open(const char* server_name, JackServer* server)
00160 {
00161 jack_log("JackWinNamedPipeServerChannel::Open");
00162 snprintf(fServerName, sizeof(fServerName), server_name);
00163
00164
00165 if (ClientListen()) {
00166 fServer = server;
00167 return 0;
00168 } else {
00169 jack_error("JackWinNamedPipeServerChannel::Open : cannot create result listen pipe");
00170 return -1;
00171 }
00172 }
00173
00174 void JackWinNamedPipeServerChannel::Close()
00175 {
00176
00177
00178
00179
00180
00181
00182
00183
00184 fRequestListenPipe.Close();
00185 }
00186
00187 int JackWinNamedPipeServerChannel::Start()
00188 {
00189 if (fThread.Start() != 0) {
00190 jack_error("Cannot start Jack server listener");
00191 return -1;
00192 } else {
00193 return 0;
00194 }
00195 }
00196
00197 void JackWinNamedPipeServerChannel::Stop()
00198 {
00199 fThread.Kill();
00200 }
00201
00202 bool JackWinNamedPipeServerChannel::Init()
00203 {
00204 jack_log("JackWinNamedPipeServerChannel::Init");
00205
00206 return ClientAccept();
00207 }
00208
00209 bool JackWinNamedPipeServerChannel::ClientListen()
00210 {
00211 if (fRequestListenPipe.Bind(jack_server_dir, fServerName, 0) < 0) {
00212 jack_error("JackWinNamedPipeServerChannel::ClientListen : cannot create result listen pipe");
00213 return false;
00214 } else {
00215 return true;
00216 }
00217 }
00218
00219 bool JackWinNamedPipeServerChannel::ClientAccept()
00220 {
00221 JackWinNamedPipeClient* pipe;
00222
00223 if ((pipe = fRequestListenPipe.AcceptClient()) == NULL) {
00224 jack_error("JackWinNamedPipeServerChannel::ClientAccept : cannot connect pipe");
00225 return false;
00226 } else {
00227 ClientAdd(pipe);
00228 return true;
00229 }
00230 }
00231
00232 bool JackWinNamedPipeServerChannel::Execute()
00233 {
00234 if (!ClientListen()) {
00235 return false;
00236 }
00237
00238 return ClientAccept();
00239 }
00240
00241 void JackWinNamedPipeServerChannel::ClientAdd(JackWinNamedPipeClient* pipe)
00242 {
00243
00244 std::list<JackClientPipeThread*>::iterator it = fClientList.begin();
00245 JackClientPipeThread* client;
00246
00247 jack_log("JackWinNamedPipeServerChannel::ClientAdd size %ld", fClientList.size());
00248
00249 while (it != fClientList.end()) {
00250 client = *it;
00251 if (client->IsRunning()) {
00252 it++;
00253 } else {
00254 it = fClientList.erase(it);
00255 delete client;
00256 }
00257 }
00258
00259 client = new JackClientPipeThread(pipe);
00260 client->Open(fServer);
00261
00262
00263 fClientList.push_back(client);
00264 }
00265
00266 }
00267
00268