Jack2
1.9.10
|
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