Jack2 1.9.6
|
00001 /* 00002 Copyright (C) 2004-2008 Grame 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as published by 00006 the Free Software Foundation; either version 2.1 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 00018 */ 00019 00020 00021 #include "JackWinNamedPipeClientChannel.h" 00022 #include "JackRequest.h" 00023 #include "JackClient.h" 00024 #include "JackGlobals.h" 00025 #include "JackError.h" 00026 00027 namespace Jack 00028 { 00029 00030 JackWinNamedPipeClientChannel::JackWinNamedPipeClientChannel():fThread(this) 00031 { 00032 fClient = NULL; 00033 } 00034 00035 JackWinNamedPipeClientChannel::~JackWinNamedPipeClientChannel() 00036 {} 00037 00038 int JackWinNamedPipeClientChannel::ServerCheck(const char* server_name) 00039 { 00040 jack_log("JackWinNamedPipeClientChannel::ServerCheck = %s", server_name); 00041 00042 // Connect to server 00043 if (fRequestPipe.Connect(jack_server_dir, server_name, 0) < 0) { 00044 jack_error("Cannot connect to server pipe"); 00045 return -1; 00046 } else { 00047 return 0; 00048 } 00049 } 00050 00051 int JackWinNamedPipeClientChannel::Open(const char* server_name, const char* name, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status) 00052 { 00053 int result = 0; 00054 jack_log("JackWinNamedPipeClientChannel::Open name = %s", name); 00055 00056 /* 00057 16/08/07: was called before doing "fRequestPipe.Connect" .... still necessary? 00058 if (fNotificationListenPipe.Bind(jack_client_dir, name, 0) < 0) { 00059 jack_error("Cannot bind pipe"); 00060 goto error; 00061 } 00062 */ 00063 00064 if (fRequestPipe.Connect(jack_server_dir, server_name, 0) < 0) { 00065 jack_error("Cannot connect to server pipe"); 00066 goto error; 00067 } 00068 00069 // Check name in server 00070 ClientCheck(name, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result); 00071 if (result < 0) { 00072 jack_error("Client name = %s conflits with another running client", name); 00073 goto error; 00074 } 00075 00076 if (fNotificationListenPipe.Bind(jack_client_dir, name_res, 0) < 0) { 00077 jack_error("Cannot bind pipe"); 00078 goto error; 00079 } 00080 00081 fClient = obj; 00082 return 0; 00083 00084 error: 00085 fRequestPipe.Close(); 00086 fNotificationListenPipe.Close(); 00087 return -1; 00088 } 00089 00090 void JackWinNamedPipeClientChannel::Close() 00091 { 00092 fRequestPipe.Close(); 00093 fNotificationListenPipe.Close(); 00094 // Here the thread will correctly stop when the pipe are closed 00095 fThread.Stop(); 00096 } 00097 00098 int JackWinNamedPipeClientChannel::Start() 00099 { 00100 jack_log("JackWinNamedPipeClientChannel::Start"); 00101 /* 00102 To be sure notification thread is started before ClientOpen is called. 00103 */ 00104 if (fThread.StartSync() != 0) { 00105 jack_error("Cannot start Jack client listener"); 00106 return -1; 00107 } else { 00108 return 0; 00109 } 00110 } 00111 00112 void JackWinNamedPipeClientChannel::Stop() 00113 { 00114 jack_log("JackWinNamedPipeClientChannel::Stop"); 00115 fThread.Kill(); // Unsafe on WIN32... TODO : solve WIN32 thread Kill issue 00116 } 00117 00118 void JackWinNamedPipeClientChannel::ServerSyncCall(JackRequest* req, JackResult* res, int* result) 00119 { 00120 if (req->Write(&fRequestPipe) < 0) { 00121 jack_error("Could not write request type = %ld", req->fType); 00122 *result = -1; 00123 return ; 00124 } 00125 00126 if (res->Read(&fRequestPipe) < 0) { 00127 jack_error("Could not read result type = %ld", req->fType); 00128 *result = -1; 00129 return ; 00130 } 00131 00132 *result = res->fResult; 00133 } 00134 00135 void JackWinNamedPipeClientChannel::ServerAsyncCall(JackRequest* req, JackResult* res, int* result) 00136 { 00137 if (req->Write(&fRequestPipe) < 0) { 00138 jack_error("Could not write request type = %ld", req->fType); 00139 *result = -1; 00140 } else { 00141 *result = 0; 00142 } 00143 } 00144 00145 void JackWinNamedPipeClientChannel::ClientCheck(const char* name, char* name_res, int protocol, int options, int* status, int* result) 00146 { 00147 JackClientCheckRequest req(name, protocol, options); 00148 JackClientCheckResult res; 00149 ServerSyncCall(&req, &res, result); 00150 *status = res.fStatus; 00151 strcpy(name_res, res.fName); 00152 } 00153 00154 void JackWinNamedPipeClientChannel::ClientOpen(const char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result) 00155 { 00156 JackClientOpenRequest req(name, pid); 00157 JackClientOpenResult res; 00158 ServerSyncCall(&req, &res, result); 00159 *shared_engine = res.fSharedEngine; 00160 *shared_client = res.fSharedClient; 00161 *shared_graph = res.fSharedGraph; 00162 } 00163 00164 void JackWinNamedPipeClientChannel::ClientClose(int refnum, int* result) 00165 { 00166 JackClientCloseRequest req(refnum); 00167 JackResult res; 00168 ServerSyncCall(&req, &res, result); 00169 } 00170 00171 void JackWinNamedPipeClientChannel::ClientActivate(int refnum, int is_real_time, int* result) 00172 { 00173 JackActivateRequest req(refnum, is_real_time); 00174 JackResult res; 00175 ServerSyncCall(&req, &res, result); 00176 } 00177 00178 void JackWinNamedPipeClientChannel::ClientDeactivate(int refnum, int* result) 00179 { 00180 JackDeactivateRequest req(refnum); 00181 JackResult res; 00182 ServerSyncCall(&req, &res, result); 00183 } 00184 00185 void JackWinNamedPipeClientChannel::PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) 00186 { 00187 JackPortRegisterRequest req(refnum, name, type, flags, buffer_size); 00188 JackPortRegisterResult res; 00189 ServerSyncCall(&req, &res, result); 00190 *port_index = res.fPortIndex; 00191 } 00192 00193 void JackWinNamedPipeClientChannel::PortUnRegister(int refnum, jack_port_id_t port_index, int* result) 00194 { 00195 JackPortUnRegisterRequest req(refnum, port_index); 00196 JackResult res; 00197 ServerSyncCall(&req, &res, result); 00198 } 00199 00200 void JackWinNamedPipeClientChannel::PortConnect(int refnum, const char* src, const char* dst, int* result) 00201 { 00202 JackPortConnectNameRequest req(refnum, src, dst); 00203 JackResult res; 00204 ServerSyncCall(&req, &res, result); 00205 } 00206 00207 void JackWinNamedPipeClientChannel::PortDisconnect(int refnum, const char* src, const char* dst, int* result) 00208 { 00209 JackPortDisconnectNameRequest req(refnum, src, dst); 00210 JackResult res; 00211 ServerSyncCall(&req, &res, result); 00212 } 00213 00214 void JackWinNamedPipeClientChannel::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result) 00215 { 00216 JackPortConnectRequest req(refnum, src, dst); 00217 JackResult res; 00218 ServerSyncCall(&req, &res, result); 00219 } 00220 00221 void JackWinNamedPipeClientChannel::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result) 00222 { 00223 JackPortDisconnectRequest req(refnum, src, dst); 00224 JackResult res; 00225 ServerSyncCall(&req, &res, result); 00226 } 00227 00228 void JackWinNamedPipeClientChannel::PortRename(int refnum, jack_port_id_t port, const char* name, int* result) 00229 { 00230 JackPortRenameRequest req(refnum, port, name); 00231 JackResult res; 00232 ServerSyncCall(&req, &res, result); 00233 } 00234 00235 void JackWinNamedPipeClientChannel::SetBufferSize(jack_nframes_t buffer_size, int* result) 00236 { 00237 JackSetBufferSizeRequest req(buffer_size); 00238 JackResult res; 00239 ServerSyncCall(&req, &res, result); 00240 } 00241 00242 void JackWinNamedPipeClientChannel::SetFreewheel(int onoff, int* result) 00243 { 00244 JackSetFreeWheelRequest req(onoff); 00245 JackResult res; 00246 ServerSyncCall(&req, &res, result); 00247 } 00248 00249 void JackWinNamedPipeClientChannel::ReleaseTimebase(int refnum, int* result) 00250 { 00251 JackReleaseTimebaseRequest req(refnum); 00252 JackResult res; 00253 ServerSyncCall(&req, &res, result); 00254 } 00255 00256 void JackWinNamedPipeClientChannel::SetTimebaseCallback(int refnum, int conditional, int* result) 00257 { 00258 JackSetTimebaseCallbackRequest req(refnum, conditional); 00259 JackResult res; 00260 ServerSyncCall(&req, &res, result); 00261 } 00262 00263 void JackWinNamedPipeClientChannel::GetInternalClientName(int refnum, int int_ref, char* name_res, int* result) 00264 { 00265 JackGetInternalClientNameRequest req(refnum, int_ref); 00266 JackGetInternalClientNameResult res; 00267 ServerSyncCall(&req, &res, result); 00268 strcpy(name_res, res.fName); 00269 } 00270 00271 void JackWinNamedPipeClientChannel::InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result) 00272 { 00273 JackInternalClientHandleRequest req(refnum, client_name); 00274 JackInternalClientHandleResult res; 00275 ServerSyncCall(&req, &res, result); 00276 *int_ref = res.fIntRefNum; 00277 *status = res.fStatus; 00278 } 00279 00280 void JackWinNamedPipeClientChannel::InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int* result) 00281 { 00282 JackInternalClientLoadRequest req(refnum, client_name, so_name, objet_data, options); 00283 JackInternalClientLoadResult res; 00284 ServerSyncCall(&req, &res, result); 00285 *int_ref = res.fIntRefNum; 00286 *status = res.fStatus; 00287 } 00288 00289 void JackWinNamedPipeClientChannel::InternalClientUnload(int refnum, int int_ref, int* status, int* result) 00290 { 00291 JackInternalClientUnloadRequest req(refnum, int_ref); 00292 JackInternalClientUnloadResult res; 00293 ServerSyncCall(&req, &res, result); 00294 *status = res.fStatus; 00295 } 00296 00297 bool JackWinNamedPipeClientChannel::Init() 00298 { 00299 jack_log("JackWinNamedPipeClientChannel::Init"); 00300 00301 if (!fNotificationListenPipe.Accept()) { 00302 jack_error("JackWinNamedPipeClientChannel: cannot establish notification pipe"); 00303 return false; 00304 } else { 00305 return fClient->Init(); 00306 } 00307 } 00308 00309 bool JackWinNamedPipeClientChannel::Execute() 00310 { 00311 JackClientNotification event; 00312 JackResult res; 00313 00314 if (event.Read(&fNotificationListenPipe) < 0) { 00315 jack_error("JackWinNamedPipeClientChannel read fail"); 00316 goto error; 00317 } 00318 00319 res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fMessage, event.fValue1, event.fValue2); 00320 00321 if (event.fSync) { 00322 if (res.Write(&fNotificationListenPipe) < 0) { 00323 jack_error("JackWinNamedPipeClientChannel write fail"); 00324 goto error; 00325 } 00326 } 00327 return true; 00328 00329 error: 00330 // Close the pipes, server wont be able to create them otherwise. 00331 fNotificationListenPipe.Close(); 00332 fRequestPipe.Close(); 00333 fClient->ShutDown(); 00334 return false; 00335 } 00336 00337 } // end of namespace 00338 00339