Jack2 1.9.6

JackServerAPI.cpp

00001 /*
00002 Copyright (C) 2001-2003 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 "JackGraphManager.h"
00023 #include "JackInternalClient.h"
00024 #include "JackServer.h"
00025 #include "JackDebugClient.h"
00026 #include "JackServerGlobals.h"
00027 #include "JackTools.h"
00028 #include "JackCompilerDeps.h"
00029 #include "JackLockedEngine.h"
00030 
00031 #ifdef __cplusplus
00032 extern "C"
00033 {
00034 #endif
00035 
00036     jack_client_t * jack_client_new_aux (const char *client_name,
00037             jack_options_t options,
00038             jack_status_t *status);
00039     jack_client_t * jack_client_open_aux (const char *client_name,
00040             jack_options_t options,
00041             jack_status_t *status, va_list ap);
00042     EXPORT jack_client_t * jack_client_open (const char *client_name,
00043             jack_options_t options,
00044             jack_status_t *status, ...);
00045     EXPORT int jack_client_close (jack_client_t *client);
00046     EXPORT int jack_get_client_pid (const char *name);
00047 
00048 #ifdef __cplusplus
00049 }
00050 #endif
00051 
00052 using namespace Jack;
00053 
00054 jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status)
00055 {
00056     jack_varargs_t va;          /* variable arguments */
00057     jack_status_t my_status;
00058     JackClient* client;
00059 
00060     if (client_name == NULL) {
00061         jack_error("jack_client_new called with a NULL client_name");
00062         return NULL;
00063     }
00064 
00065     jack_log("jack_client_new %s", client_name);
00066  
00067     if (status == NULL)                 /* no status from caller? */
00068         status = &my_status;    /* use local status word */
00069     *status = (jack_status_t)0;
00070 
00071     /* validate parameters */
00072     if ((options & ~JackOpenOptions)) {
00073         int my_status1 = *status | (JackFailure | JackInvalidOption);
00074         *status = (jack_status_t)my_status1;
00075         return NULL;
00076     }
00077 
00078     /* parse variable arguments */
00079     jack_varargs_init(&va);
00080  
00081     if (!JackServerGlobals::Init()) { // jack server initialisation
00082         int my_status1 = (JackFailure | JackServerError);
00083         *status = (jack_status_t)my_status1;
00084         return NULL;
00085     }
00086  
00087     if (JACK_DEBUG) {
00088         client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode
00089     } else {
00090         client = new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable());
00091     }
00092 
00093     int res = client->Open(va.server_name, client_name, options, status);
00094     if (res < 0) {
00095         delete client;
00096         JackServerGlobals::Destroy(); // jack server destruction
00097         int my_status1 = (JackFailure | JackServerError);
00098         *status = (jack_status_t)my_status1;
00099         return NULL;
00100     } else {
00101         return (jack_client_t*)client;
00102     }
00103 }
00104 
00105 jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t options, jack_status_t* status, va_list ap)
00106 {
00107     jack_varargs_t va;          /* variable arguments */
00108     jack_status_t my_status;
00109     JackClient* client;
00110 
00111     if (client_name == NULL) {
00112         jack_error("jack_client_open called with a NULL client_name");
00113         return NULL;
00114     }
00115 
00116     jack_log("jack_client_open %s", client_name);
00117  
00118     if (status == NULL)                 /* no status from caller? */
00119         status = &my_status;    /* use local status word */
00120     *status = (jack_status_t)0;
00121 
00122     /* validate parameters */
00123     if ((options & ~JackOpenOptions)) {
00124         int my_status1 = *status | (JackFailure | JackInvalidOption);
00125         *status = (jack_status_t)my_status1;
00126         return NULL;
00127     }
00128 
00129     /* parse variable arguments */
00130     jack_varargs_parse(options, ap, &va);
00131  
00132     if (!JackServerGlobals::Init()) { // jack server initialisation
00133         int my_status1 = (JackFailure | JackServerError);
00134         *status = (jack_status_t)my_status1;
00135         return NULL;
00136     }
00137  
00138     if (JACK_DEBUG) {
00139         client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode
00140     } else {
00141         client = new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable());
00142     }
00143 
00144     int res = client->Open(va.server_name, client_name, options, status);
00145     if (res < 0) {
00146         delete client;
00147         JackServerGlobals::Destroy(); // jack server destruction
00148         int my_status1 = (JackFailure | JackServerError);
00149         *status = (jack_status_t)my_status1;
00150         return NULL;
00151     } else {
00152         return (jack_client_t*)client;
00153     }
00154 }
00155 
00156 EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...)
00157 {
00158 #ifdef __CLIENTDEBUG__
00159     JackGlobals::CheckContext("jack_client_open");
00160 #endif
00161     try {
00162         assert(JackGlobals::fOpenMutex);
00163         JackGlobals::fOpenMutex->Lock();
00164         va_list ap;
00165         va_start(ap, status);
00166         jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap);
00167         va_end(ap);
00168         JackGlobals::fOpenMutex->Unlock();
00169         return res;
00170     } catch(std::bad_alloc& e) {
00171         jack_error("Memory allocation error...");
00172         return NULL;
00173     } catch (...) {
00174         jack_error("Unknown error...");
00175         return NULL;
00176     }
00177 }
00178 
00179 EXPORT int jack_client_close(jack_client_t* ext_client)
00180 {
00181 #ifdef __CLIENTDEBUG__
00182     JackGlobals::CheckContext("jack_client_close");
00183 #endif    
00184     assert(JackGlobals::fOpenMutex);
00185     JackGlobals::fOpenMutex->Lock();
00186     int res = -1;
00187     jack_log("jack_client_close");
00188     JackClient* client = (JackClient*)ext_client;
00189     if (client == NULL) {
00190         jack_error("jack_client_close called with a NULL client");
00191     } else {
00192         res = client->Close();
00193         delete client;
00194         JackServerGlobals::Destroy();   // jack server destruction
00195         jack_log("jack_client_close res = %d", res);
00196     }
00197     JackGlobals::fOpenMutex->Unlock();
00198     return res;
00199 }
00200 
00201 EXPORT int jack_get_client_pid(const char *name)
00202 {
00203     return (JackServerGlobals::fInstance != NULL) 
00204         ? JackServerGlobals::fInstance->GetEngine()->GetClientPID(name)
00205         : 0;
00206 }
00207