Jack2 1.9.6

JackInternalClient.cpp

00001 /*
00002 Copyright (C) 2001 Paul Davis
00003 Copyright (C) 2004-2008 Grame
00004 
00005 This program is free software; you can redistribute it and/or modify
00006 it under the terms of the GNU General Public License as published by
00007 the Free Software Foundation; either version 2 of the License, or
00008 (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 
00019 */
00020 
00021 #include "JackSystemDeps.h"
00022 #include "JackServerGlobals.h"
00023 #include "JackGraphManager.h"
00024 #include "JackConstants.h"
00025 #include "JackInternalClient.h"
00026 #include "JackLockedEngine.h"
00027 #include "JackServer.h"
00028 #include "JackEngineControl.h"
00029 #include "JackClientControl.h"
00030 #include "JackInternalClientChannel.h"
00031 #include "JackTools.h"
00032 #include <assert.h>
00033 
00034 namespace Jack
00035 {
00036 
00037 JackGraphManager* JackInternalClient::fGraphManager = NULL;
00038 JackEngineControl* JackInternalClient::fEngineControl = NULL;
00039 
00040 // Used for external C API (JackAPI.cpp)
00041 EXPORT JackGraphManager* GetGraphManager()
00042 {
00043     return JackServerGlobals::fInstance->GetGraphManager();
00044 }
00045 
00046 EXPORT JackEngineControl* GetEngineControl()
00047 {
00048     return JackServerGlobals::fInstance->GetEngineControl();
00049 }
00050 
00051 EXPORT JackSynchro* GetSynchroTable()
00052 {
00053     return JackServerGlobals::fInstance->GetSynchroTable();
00054 }
00055 
00056 JackInternalClient::JackInternalClient(JackServer* server, JackSynchro* table): JackClient(table)
00057 {
00058     fChannel = new JackInternalClientChannel(server);
00059 }
00060 
00061 JackInternalClient::~JackInternalClient()
00062 {
00063     delete fChannel;
00064 }
00065 
00066 int JackInternalClient::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status)
00067 {
00068     int result;
00069     char name_res[JACK_CLIENT_NAME_SIZE + 1];
00070     jack_log("JackInternalClient::Open name = %s", name);
00071 
00072     strncpy(fServerName, server_name, sizeof(fServerName));
00073 
00074     fChannel->ClientCheck(name, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result);
00075     if (result < 0) {
00076         int status1 = *status;
00077         if (status1 & JackVersionError)
00078             jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
00079         else
00080             jack_error("Client name = %s conflits with another running client", name);
00081         goto error;
00082     }
00083 
00084     strcpy(fClientControl.fName, name_res);
00085 
00086     // Require new client
00087     fChannel->ClientOpen(name_res, &fClientControl.fRefNum, &fEngineControl, &fGraphManager, this, &result);
00088     if (result < 0) {
00089         jack_error("Cannot open client name = %s", name_res);
00090         goto error;
00091     }
00092 
00093     SetupDriverSync(false);
00094     JackGlobals::fClientTable[fClientControl.fRefNum] = this;
00095     JackGlobals::fServerRunning = true;
00096     jack_log("JackInternalClient::Open name = %s refnum = %ld", name_res, fClientControl.fRefNum);
00097     return 0;
00098 
00099 error:
00100     fChannel->Stop();
00101     fChannel->Close();
00102     return -1;
00103 }
00104 
00105 JackGraphManager* JackInternalClient::GetGraphManager() const
00106 {
00107     assert(fGraphManager);
00108     return fGraphManager;
00109 }
00110 
00111 JackEngineControl* JackInternalClient::GetEngineControl() const
00112 {
00113     assert(fEngineControl);
00114     return fEngineControl;
00115 }
00116 
00117 JackClientControl* JackInternalClient::GetClientControl() const
00118 {
00119     return const_cast<JackClientControl*>(&fClientControl);
00120 }
00121 
00122 int JackLoadableInternalClient::Init(const char* so_name)
00123 {
00124     char path_to_so[JACK_PATH_MAX + 1];
00125     BuildClientPath(path_to_so, sizeof(path_to_so), so_name);
00126  
00127     fHandle = LoadJackModule(path_to_so);
00128     jack_log("JackLoadableInternalClient::JackLoadableInternalClient path_to_so = %s", path_to_so);
00129 
00130     if (fHandle == NULL) {
00131         PrintLoadError(so_name);
00132         return -1;
00133     }
00134 
00135     fFinish = (FinishCallback)GetJackProc(fHandle, "jack_finish");
00136     if (fFinish == NULL) {
00137         UnloadJackModule(fHandle);
00138         jack_error("symbol jack_finish cannot be found in %s", so_name);
00139         return -1;
00140     }
00141 
00142     fDescriptor = (JackDriverDescFunction)GetJackProc(fHandle, "jack_get_descriptor");
00143     if (fDescriptor == NULL) {
00144         jack_info("No jack_get_descriptor entry-point for %s", so_name);
00145     }
00146     return 0;
00147 }
00148 
00149 int JackLoadableInternalClient1::Init(const char* so_name)
00150 {
00151     if (JackLoadableInternalClient::Init(so_name) < 0) {
00152         return -1;
00153     }
00154     
00155     fInitialize = (InitializeCallback)GetJackProc(fHandle, "jack_initialize");
00156     if (fInitialize == NULL) {
00157         UnloadJackModule(fHandle);
00158         jack_error("symbol jack_initialize cannot be found in %s", so_name);
00159         return -1;
00160     }
00161 
00162     return 0;
00163 }
00164 
00165 int JackLoadableInternalClient2::Init(const char* so_name)
00166 {
00167     if (JackLoadableInternalClient::Init(so_name) < 0) {
00168         return -1;
00169     }
00170     
00171     fInitialize = (InternalInitializeCallback)GetJackProc(fHandle, "jack_internal_initialize");
00172     if (fInitialize == NULL) {
00173         UnloadJackModule(fHandle);
00174         jack_error("symbol jack_internal_initialize cannot be found in %s", so_name);
00175         return -1;
00176     }
00177 
00178     return 0;
00179 }
00180 
00181 JackLoadableInternalClient1::JackLoadableInternalClient1(JackServer* server, JackSynchro* table, const char* object_data)
00182         : JackLoadableInternalClient(server, table)
00183 {
00184     strncpy(fObjectData, object_data, JACK_LOAD_INIT_LIMIT);   
00185 }
00186 
00187 JackLoadableInternalClient2::JackLoadableInternalClient2(JackServer* server, JackSynchro* table, const JSList*  parameters)
00188         : JackLoadableInternalClient(server, table)
00189 {
00190     fParameters = parameters;
00191 }
00192 
00193 JackLoadableInternalClient::~JackLoadableInternalClient()
00194 {
00195     if (fFinish != NULL)
00196         fFinish(fProcessArg);
00197     if (fHandle != NULL)
00198         UnloadJackModule(fHandle);
00199 }
00200 
00201 int JackLoadableInternalClient1::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status)
00202 {
00203     int res = -1;
00204     
00205     if (JackInternalClient::Open(server_name, name, options, status) == 0) {
00206         if (fInitialize((jack_client_t*)this, fObjectData) == 0) {
00207             res = 0;
00208         } else {
00209             JackInternalClient::Close();
00210             fFinish = NULL;
00211         }
00212     }
00213     
00214     return res;
00215 }
00216 
00217 int JackLoadableInternalClient2::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status)
00218 {
00219     int res = -1;
00220     
00221     if (JackInternalClient::Open(server_name, name, options, status) == 0) {
00222         if (fInitialize((jack_client_t*)this, fParameters) == 0) {
00223             res = 0;
00224         } else {
00225             JackInternalClient::Close();
00226             fFinish = NULL;
00227         }
00228     }
00229     
00230     return res;
00231 }
00232 
00233 } // end of namespace
00234