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 #include "JackLibClient.h" 00021 #include "JackTime.h" 00022 #include "JackLibGlobals.h" 00023 #include "JackGlobals.h" 00024 #include "JackPlatformPlug.h" 00025 #include "JackTools.h" 00026 00027 namespace Jack 00028 { 00029 00030 // Used for external C API (JackAPI.cpp) 00031 JackGraphManager* GetGraphManager() 00032 { 00033 if (JackLibGlobals::fGlobals) { 00034 return JackLibGlobals::fGlobals->fGraphManager; 00035 } else { 00036 return NULL; 00037 } 00038 } 00039 00040 JackEngineControl* GetEngineControl() 00041 { 00042 if (JackLibGlobals::fGlobals) { 00043 return JackLibGlobals::fGlobals->fEngineControl; 00044 } else { 00045 return NULL; 00046 } 00047 } 00048 00049 JackSynchro* GetSynchroTable() 00050 { 00051 return (JackLibGlobals::fGlobals ? JackLibGlobals::fGlobals->fSynchroTable : 0); 00052 } 00053 00054 //------------------- 00055 // Client management 00056 //------------------- 00057 00058 JackLibClient::JackLibClient(JackSynchro* table): JackClient(table) 00059 { 00060 jack_log("JackLibClient::JackLibClient table = %x", table); 00061 fChannel = new JackClientChannel(); 00062 } 00063 00064 JackLibClient::~JackLibClient() 00065 { 00066 jack_log("JackLibClient::~JackLibClient"); 00067 delete fChannel; 00068 } 00069 00070 int JackLibClient::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status) 00071 { 00072 int shared_engine, shared_client, shared_graph, result; 00073 jack_log("JackLibClient::Open name = %s", name); 00074 00075 strncpy(fServerName, server_name, sizeof(fServerName)); 00076 00077 // Open server/client channel 00078 char name_res[JACK_CLIENT_NAME_SIZE + 1]; 00079 if (fChannel->Open(server_name, name, name_res, this, options, status) < 0) { 00080 jack_error("Cannot connect to the server"); 00081 goto error; 00082 } 00083 00084 // Start receiving notifications 00085 if (fChannel->Start() < 0) { 00086 jack_error("Cannot start channel"); 00087 goto error; 00088 } 00089 00090 // Require new client 00091 fChannel->ClientOpen(name_res, JackTools::GetPID(), &shared_engine, &shared_client, &shared_graph, &result); 00092 if (result < 0) { 00093 jack_error("Cannot open %s client", name_res); 00094 goto error; 00095 } 00096 00097 try { 00098 // Map shared memory segments 00099 JackLibGlobals::fGlobals->fEngineControl.SetShmIndex(shared_engine, fServerName); 00100 JackLibGlobals::fGlobals->fGraphManager.SetShmIndex(shared_graph, fServerName); 00101 fClientControl.SetShmIndex(shared_client, fServerName); 00102 JackGlobals::fVerbose = GetEngineControl()->fVerbose; 00103 } catch (int n) { 00104 jack_error("Map shared memory segments exception %d", n); 00105 goto error; 00106 } catch (...) { 00107 jack_error("Unknown error..."); 00108 goto error; 00109 } 00110 00111 SetupDriverSync(false); 00112 00113 // Connect shared synchro : the synchro must be usable in I/O mode when several clients live in the same process 00114 if (!fSynchroTable[GetClientControl()->fRefNum].Connect(name_res, fServerName)) { 00115 jack_error("Cannot ConnectSemaphore %s client", name_res); 00116 goto error; 00117 } 00118 00119 JackGlobals::fClientTable[GetClientControl()->fRefNum] = this; 00120 JackGlobals::fServerRunning = true; 00121 SetClockSource(GetEngineControl()->fClockSource); 00122 jack_log("JackLibClient::Open name = %s refnum = %ld", name_res, GetClientControl()->fRefNum); 00123 return 0; 00124 00125 error: 00126 fChannel->Stop(); 00127 fChannel->Close(); 00128 return -1; 00129 } 00130 00131 // Notifications received from the server 00132 // TODO this should be done once for all clients in the process, when a shared notification channel 00133 // will be shared by all clients... 00134 int JackLibClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) 00135 { 00136 int res = 0; 00137 00138 // Done all time 00139 switch (notify) { 00140 00141 case kAddClient: 00142 jack_log("JackClient::AddClient name = %s, ref = %ld ", name, refnum); 00143 // the synchro must be usable in I/O mode when several clients live in the same process 00144 res = fSynchroTable[refnum].Connect(name, fServerName) ? 0 : -1; 00145 break; 00146 00147 case kRemoveClient: 00148 jack_log("JackClient::RemoveClient name = %s, ref = %ld ", name, refnum); 00149 if (strcmp(GetClientControl()->fName, name) != 0) 00150 res = fSynchroTable[refnum].Disconnect() ? 0 : -1; 00151 break; 00152 } 00153 00154 return res; 00155 } 00156 00157 JackGraphManager* JackLibClient::GetGraphManager() const 00158 { 00159 assert(JackLibGlobals::fGlobals->fGraphManager); 00160 return JackLibGlobals::fGlobals->fGraphManager; 00161 } 00162 00163 JackEngineControl* JackLibClient::GetEngineControl() const 00164 { 00165 assert(JackLibGlobals::fGlobals->fEngineControl); 00166 return JackLibGlobals::fGlobals->fEngineControl; 00167 } 00168 00169 JackClientControl* JackLibClient::GetClientControl() const 00170 { 00171 return fClientControl; 00172 } 00173 00174 } // end of namespace 00175 00176 00177