Jack2  1.9.8
JackServerAPI.cpp
1 /*
2 Copyright (C) 2001-2003 Paul Davis
3 Copyright (C) 2004-2008 Grame
4 
5 This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 
19 */
20 
21 #include "JackSystemDeps.h"
22 #include "JackGraphManager.h"
23 #include "JackInternalClient.h"
24 #include "JackServer.h"
25 #include "JackDebugClient.h"
26 #include "JackServerGlobals.h"
27 #include "JackTools.h"
28 #include "JackCompilerDeps.h"
29 #include "JackLockedEngine.h"
30 
31 #ifdef __cplusplus
32 extern "C"
33 {
34 #endif
35 
36  jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status);
37 
38  SERVER_EXPORT jack_client_t * jack_client_open (const char *client_name,
39  jack_options_t options,
40  jack_status_t *status, ...);
41  SERVER_EXPORT int jack_client_close (jack_client_t *client);
42  SERVER_EXPORT int jack_get_client_pid (const char *name);
43 
44 #ifdef __cplusplus
45 }
46 #endif
47 
48 using namespace Jack;
49 
50 static jack_client_t * jack_client_open_aux (const char *client_name,
51  jack_options_t options,
52  jack_status_t *status, va_list ap);
53 
54 jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status)
55 {
56  jack_varargs_t va; /* variable arguments */
57  jack_status_t my_status;
58  JackClient* client;
59 
60  if (client_name == NULL) {
61  jack_error("jack_client_new called with a NULL client_name");
62  return NULL;
63  }
64 
65  jack_log("jack_client_new %s", client_name);
66 
67  if (status == NULL) /* no status from caller? */
68  status = &my_status; /* use local status word */
69  *status = (jack_status_t)0;
70 
71  /* validate parameters */
72  if ((options & ~JackOpenOptions)) {
73  int my_status1 = *status | (JackFailure | JackInvalidOption);
74  *status = (jack_status_t)my_status1;
75  return NULL;
76  }
77 
78  /* parse variable arguments */
79  jack_varargs_init(&va);
80 
81  if (!JackServerGlobals::Init()) { // jack server initialisation
82  int my_status1 = (JackFailure | JackServerError);
83  *status = (jack_status_t)my_status1;
84  return NULL;
85  }
86 
87  if (JACK_DEBUG) {
88  client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode
89  } else {
90  client = new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable());
91  }
92 
93  int res = client->Open(va.server_name, client_name, va.session_id, options, status);
94  if (res < 0) {
95  delete client;
96  JackServerGlobals::Destroy(); // jack server destruction
97  int my_status1 = (JackFailure | JackServerError);
98  *status = (jack_status_t)my_status1;
99  return NULL;
100  } else {
101  return (jack_client_t*)client;
102  }
103 }
104 
105 jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t options, jack_status_t* status, va_list ap)
106 {
107  jack_varargs_t va; /* variable arguments */
108  jack_status_t my_status;
109  JackClient* client;
110 
111  if (client_name == NULL) {
112  jack_error("jack_client_open called with a NULL client_name");
113  return NULL;
114  }
115 
116  jack_log("jack_client_open %s", client_name);
117 
118  if (status == NULL) /* no status from caller? */
119  status = &my_status; /* use local status word */
120  *status = (jack_status_t)0;
121 
122  /* validate parameters */
123  if ((options & ~JackOpenOptions)) {
124  int my_status1 = *status | (JackFailure | JackInvalidOption);
125  *status = (jack_status_t)my_status1;
126  return NULL;
127  }
128 
129  /* parse variable arguments */
130  jack_varargs_parse(options, ap, &va);
131 
132  if (!JackServerGlobals::Init()) { // jack server initialisation
133  int my_status1 = (JackFailure | JackServerError);
134  *status = (jack_status_t)my_status1;
135  return NULL;
136  }
137 
138  if (JACK_DEBUG) {
139  client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode
140  } else {
141  client = new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable());
142  }
143 
144  int res = client->Open(va.server_name, client_name, va.session_id, options, status);
145  if (res < 0) {
146  delete client;
147  JackServerGlobals::Destroy(); // jack server destruction
148  int my_status1 = (JackFailure | JackServerError);
149  *status = (jack_status_t)my_status1;
150  return NULL;
151  } else {
152  return (jack_client_t*)client;
153  }
154 }
155 
156 SERVER_EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...)
157 {
158 #ifdef __CLIENTDEBUG__
159  JackGlobals::CheckContext("jack_client_open");
160 #endif
161  try {
162  assert(JackGlobals::fOpenMutex);
163  JackGlobals::fOpenMutex->Lock();
164  va_list ap;
165  va_start(ap, status);
166  jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap);
167  va_end(ap);
168  JackGlobals::fOpenMutex->Unlock();
169  return res;
170  } catch(std::bad_alloc& e) {
171  jack_error("Memory allocation error...");
172  return NULL;
173  } catch (...) {
174  jack_error("Unknown error...");
175  return NULL;
176  }
177 }
178 
179 SERVER_EXPORT int jack_client_close(jack_client_t* ext_client)
180 {
181 #ifdef __CLIENTDEBUG__
182  JackGlobals::CheckContext("jack_client_close");
183 #endif
184  assert(JackGlobals::fOpenMutex);
185  JackGlobals::fOpenMutex->Lock();
186  int res = -1;
187  jack_log("jack_client_close");
188  JackClient* client = (JackClient*)ext_client;
189  if (client == NULL) {
190  jack_error("jack_client_close called with a NULL client");
191  } else {
192  res = client->Close();
193  delete client;
194  JackServerGlobals::Destroy(); // jack server destruction
195  jack_log("jack_client_close res = %d", res);
196  }
197  JackGlobals::fOpenMutex->Unlock();
198  return res;
199 }
200 
201 SERVER_EXPORT int jack_get_client_pid(const char *name)
202 {
203  return (JackServerGlobals::fInstance != NULL)
204  ? JackServerGlobals::fInstance->GetEngine()->GetClientPID(name)
205  : 0;
206 }
207