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