Jack2
1.9.8
|
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, int uuid, 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, uuid, 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(), uuid, &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 (...) { 00104 jack_error("Map shared memory segments exception"); 00105 goto error; 00106 } 00107 00108 SetupDriverSync(false); 00109 00110 // Connect shared synchro : the synchro must be usable in I/O mode when several clients live in the same process 00111 if (!fSynchroTable[GetClientControl()->fRefNum].Connect(name_res, fServerName)) { 00112 jack_error("Cannot ConnectSemaphore %s client", name_res); 00113 goto error; 00114 } 00115 00116 JackGlobals::fClientTable[GetClientControl()->fRefNum] = this; 00117 JackGlobals::fServerRunning = true; 00118 SetClockSource(GetEngineControl()->fClockSource); 00119 jack_log("JackLibClient::Open name = %s refnum = %ld", name_res, GetClientControl()->fRefNum); 00120 return 0; 00121 00122 error: 00123 fChannel->Stop(); 00124 fChannel->Close(); 00125 return -1; 00126 } 00127 00128 // Notifications received from the server 00129 // TODO this should be done once for all clients in the process, when a shared notification channel 00130 // will be shared by all clients... 00131 int JackLibClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2) 00132 { 00133 int res = 0; 00134 00135 // Done all time 00136 switch (notify) { 00137 00138 case kAddClient: 00139 jack_log("JackClient::AddClient name = %s, ref = %ld ", name, refnum); 00140 // the synchro must be usable in I/O mode when several clients live in the same process 00141 res = fSynchroTable[refnum].Connect(name, fServerName) ? 0 : -1; 00142 break; 00143 00144 case kRemoveClient: 00145 jack_log("JackClient::RemoveClient name = %s, ref = %ld ", name, refnum); 00146 if (GetClientControl() && strcmp(GetClientControl()->fName, name) != 0) 00147 res = fSynchroTable[refnum].Disconnect() ? 0 : -1; 00148 break; 00149 } 00150 00151 return res; 00152 } 00153 00154 JackGraphManager* JackLibClient::GetGraphManager() const 00155 { 00156 assert(JackLibGlobals::fGlobals->fGraphManager); 00157 return JackLibGlobals::fGlobals->fGraphManager; 00158 } 00159 00160 JackEngineControl* JackLibClient::GetEngineControl() const 00161 { 00162 assert(JackLibGlobals::fGlobals->fEngineControl); 00163 return JackLibGlobals::fGlobals->fEngineControl; 00164 } 00165 00166 JackClientControl* JackLibClient::GetClientControl() const 00167 { 00168 return fClientControl; 00169 } 00170 00171 } // end of namespace 00172 00173 00174