Jack2 1.9.8

JackLibClient.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 "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