Jack2 1.9.10

JackSocketClientChannel.cpp

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 #include "JackSocketClientChannel.h"
00021 #include "JackRequest.h"
00022 #include "JackClient.h"
00023 #include "JackGlobals.h"
00024 #include "JackError.h"
00025 
00026 namespace Jack
00027 {
00028 
00029 JackSocketClientChannel::JackSocketClientChannel()
00030     :JackGenericClientChannel(), fThread(this)
00031 {
00032     fRequest = new JackClientSocket();
00033     fNotificationSocket = NULL;
00034 }
00035 
00036 JackSocketClientChannel::~JackSocketClientChannel()
00037 {
00038     delete fRequest;
00039     delete fNotificationSocket;
00040 }
00041 
00042 int JackSocketClientChannel::Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status)
00043 {
00044     int result = 0;
00045     jack_log("JackSocketClientChannel::Open name = %s", name);
00046     
00047     // Before any server/client call
00048     fClient = client;
00049 
00050     if (fRequest->Connect(jack_server_dir, server_name, 0) < 0) {
00051         jack_error("Cannot connect to server socket");
00052         goto error;
00053     }
00054     
00055     // OK so server is there...
00056     JackGlobals::fServerRunning = true;
00057 
00058     // Check name in server
00059     ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, true);
00060     if (result < 0) {
00061         int status1 = *status;
00062         if (status1 & JackVersionError) {
00063             jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
00064         } else {
00065             jack_error("Client name = %s conflits with another running client", name);
00066         }
00067         goto error;
00068     }
00069 
00070     if (fNotificationListenSocket.Bind(jack_client_dir, name_res, 0) < 0) {
00071         jack_error("Cannot bind socket");
00072         goto error;
00073     }
00074     
00075     return 0;
00076 
00077 error:
00078     fRequest->Close();
00079     fNotificationListenSocket.Close();
00080     return -1;
00081 }
00082 
00083 void JackSocketClientChannel::Close()
00084 {
00085     fRequest->Close();
00086     fNotificationListenSocket.Close();
00087     if (fNotificationSocket) {
00088         fNotificationSocket->Close();
00089     }
00090 }
00091 
00092 int JackSocketClientChannel::Start()
00093 {
00094     jack_log("JackSocketClientChannel::Start");
00095     /*
00096      To be sure notification thread is started before ClientOpen is called.
00097     */
00098     if (fThread.StartSync() != 0) {
00099         jack_error("Cannot start Jack client listener");
00100         return -1;
00101     } else {
00102         return 0;
00103     }
00104 }
00105 
00106 void JackSocketClientChannel::Stop()
00107 {
00108     jack_log("JackSocketClientChannel::Stop");
00109     fThread.Kill();
00110 }
00111 
00112 bool JackSocketClientChannel::Init()
00113 {
00114     jack_log("JackSocketClientChannel::Init");
00115     fNotificationSocket = fNotificationListenSocket.Accept();
00116     
00117     // No more needed
00118     fNotificationListenSocket.Close();
00119     
00120     // Setup context
00121     if (!jack_tls_set(JackGlobals::fNotificationThread, this)) {
00122         jack_error("Failed to set thread notification key");
00123     }
00124 
00125     if (!fNotificationSocket) {
00126         jack_error("JackSocketClientChannel: cannot establish notication socket");
00127         return false;
00128     } else {
00129         return true;
00130     }
00131 }
00132 
00133 bool JackSocketClientChannel::Execute()
00134 {
00135     JackClientNotification event;
00136     JackResult res;
00137 
00138     if (event.Read(fNotificationSocket) < 0) {
00139         jack_error("JackSocketClientChannel read fail");
00140         goto error;
00141     }
00142 
00143     res.fResult = fClient->ClientNotify(event.fRefNum, event.fName, event.fNotify, event.fSync, event.fMessage, event.fValue1, event.fValue2);
00144 
00145     if (event.fSync) {
00146         if (res.Write(fNotificationSocket) < 0) {
00147             jack_error("JackSocketClientChannel write fail");
00148             goto error;
00149         }
00150     }
00151     return true;
00152 
00153 error:
00154     fNotificationSocket->Close();
00155     fClient->ShutDown(jack_status_t(JackFailure | JackServerError), JACK_SERVER_FAILURE);
00156     return false;
00157 }
00158 
00159 } // end of namespace
00160 
00161 
00162 
00163 
00164