JackWinNamedPipeClientChannel.cpp

00001 /*
00002 Copyright (C) 2004-2006 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 #include "JackWinNamedPipeClientChannel.h"
00021 #include "JackRequest.h"
00022 #include "JackClient.h"
00023 #include "JackGlobals.h"
00024 
00025 namespace Jack
00026 {
00027 
00028 JackWinNamedPipeClientChannel::JackWinNamedPipeClientChannel()
00029 {
00030     fThread = JackGlobals::MakeThread(this);
00031     fClient = NULL;
00032 }
00033 
00034 JackWinNamedPipeClientChannel::~JackWinNamedPipeClientChannel()
00035 {
00036     delete fThread;
00037 }
00038 
00039 int JackWinNamedPipeClientChannel::ServerCheck(const char* server_name)
00040 {
00041         JackLog("JackWinNamedPipeClientChannel::ServerCheck = %s\n", server_name);
00042         
00043         // Connect to server
00044     if (fRequestPipe.Connect(jack_server_dir, server_name, 0) < 0) {
00045         jack_error("Cannot connect to server pipe");
00046         return -1;
00047     } else {
00048                 return 0;
00049         }
00050 }
00051 
00052 int JackWinNamedPipeClientChannel::Open(const char* server_name, const char* name, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status)
00053 {
00054         int result = 0;
00055     JackLog("JackWinNamedPipeClientChannel::Open name = %s\n", name);
00056 
00057         /* 
00058         16/08/07: was called before doing "fRequestPipe.Connect" .... still necessary?
00059     if (fNotificationListenPipe.Bind(jack_client_dir, name, 0) < 0) {
00060         jack_error("Cannot bind pipe");
00061         goto error;
00062     }
00063         */
00064         
00065     if (fRequestPipe.Connect(jack_server_dir, server_name, 0) < 0) {
00066         jack_error("Cannot connect to server pipe");
00067         goto error;
00068     }
00069 
00070         // Check name in server
00071         ClientCheck(name, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result);
00072     if (result < 0) {
00073         jack_error("Client name = %s conflits with another running client", name);
00074                 goto error;
00075     }
00076         
00077         if (fNotificationListenPipe.Bind(jack_client_dir, name_res, 0) < 0) {
00078         jack_error("Cannot bind pipe");
00079         goto error;
00080     }
00081         
00082 
00083     fClient = obj;
00084     return 0;
00085 
00086 error:
00087     fRequestPipe.Close();
00088     fNotificationListenPipe.Close();
00089     return -1;
00090 }
00091 
00092 void JackWinNamedPipeClientChannel::Close()
00093 {
00094     fRequestPipe.Close();
00095     fNotificationListenPipe.Close();
00096         // Here the thread will correctly stop when the pipe are closed
00097         fThread->Stop();
00098 }
00099 
00100 int JackWinNamedPipeClientChannel::Start()
00101 {
00102     JackLog("JackWinNamedPipeClientChannel::Start\n");
00103         
00104     if (fThread->Start() != 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     JackLog("JackWinNamedPipeClientChannel::Stop\n");
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* shared_engine, int* shared_client, int* shared_graph, int* result)
00155 {
00156     JackClientOpenRequest req(name);
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     ServerAsyncCall(&req, &res, result);
00169 }
00170 
00171 void JackWinNamedPipeClientChannel::ClientActivate(int refnum, int* result)
00172 {
00173     JackActivateRequest req(refnum);
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, unsigned int* 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::SetBufferSize(jack_nframes_t buffer_size, int* result)
00229 {
00230     JackSetBufferSizeRequest req(buffer_size);
00231     JackResult res;
00232     ServerSyncCall(&req, &res, result);
00233 }
00234 
00235 void JackWinNamedPipeClientChannel::SetFreewheel(int onoff, int* result)
00236 {
00237     JackSetFreeWheelRequest req(onoff);
00238     JackResult res;
00239     ServerSyncCall(&req, &res, result);
00240 }
00241 
00242 void JackWinNamedPipeClientChannel::ReleaseTimebase(int refnum, int* result)
00243 {
00244     JackReleaseTimebaseRequest req(refnum);
00245     JackResult res;
00246     ServerSyncCall(&req, &res, result);
00247 }
00248 
00249 void JackWinNamedPipeClientChannel::SetTimebaseCallback(int refnum, int conditional, int* result)
00250 {
00251     JackSetTimebaseCallbackRequest req(refnum, conditional);
00252     JackResult res;
00253     ServerSyncCall(&req, &res, result);
00254 }
00255 
00256 void JackWinNamedPipeClientChannel::GetInternalClientName(int refnum, int int_ref, char* name_res, int* result)
00257 {
00258     JackGetInternalClientNameRequest req(refnum, int_ref);
00259     JackGetInternalClientNameResult res;
00260     ServerSyncCall(&req, &res, result);
00261         strcpy(name_res, res.fName);
00262 }
00263 
00264 void JackWinNamedPipeClientChannel::InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result)
00265 {
00266     JackInternalClientHandleRequest req(refnum, client_name);
00267     JackInternalClientHandleResult res;
00268     ServerSyncCall(&req, &res, result);
00269         *int_ref = res.fIntRefNum;
00270         *status = res.fStatus;
00271 }
00272 
00273 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)
00274 {
00275     JackInternalClientLoadRequest req(refnum, client_name, so_name, objet_data, options);
00276     JackInternalClientLoadResult res;
00277     ServerSyncCall(&req, &res, result);
00278         *int_ref = res.fIntRefNum;
00279         *status = res.fStatus;
00280 }
00281 
00282 void JackWinNamedPipeClientChannel::InternalClientUnload(int refnum, int int_ref, int* status, int* result)
00283 {
00284     JackInternalClientUnloadRequest req(refnum, int_ref);
00285     JackInternalClientUnloadResult res;
00286     ServerSyncCall(&req, &res, result);
00287         *status = res.fStatus;
00288 }
00289 
00290 bool JackWinNamedPipeClientChannel::Init()
00291 {
00292     JackLog("JackWinNamedPipeClientChannel::Init \n");
00293 
00294     if (!fNotificationListenPipe.Accept()) {
00295         jack_error("JackWinNamedPipeClientChannel: cannot establish notification pipe");
00296         return false;
00297     } else {
00298                 return true;
00299     }
00300 }
00301 
00302 bool JackWinNamedPipeClientChannel::Execute()
00303 {
00304     JackClientNotification event;
00305     JackResult res;
00306 
00307     if (event.Read(&fNotificationListenPipe) < 0) {
00308         fNotificationListenPipe.Close();
00309         jack_error("JackWinNamedPipeClientChannel read fail");
00310         goto error;
00311     }
00312 
00313     res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fValue1, event.fValue2);
00314 
00315     if (event.fSync) {
00316         if (res.Write(&fNotificationListenPipe) < 0) {
00317             fNotificationListenPipe.Close();
00318             jack_error("JackWinNamedPipeClientChannel write fail");
00319             goto error;
00320         }
00321     }
00322     return true;
00323 
00324 error:
00325 
00326     //fClient->ShutDown(); needed ??
00327     return false;
00328 }
00329 
00330 } // end of namespace
00331 
00332 

Generated on Thu Feb 14 11:16:02 2008 for Jackdmp by  doxygen 1.5.1