Jack2  1.9.9
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 jack_client_t* jack_client_new_aux(const char* client_name, jack_options_t options, jack_status_t* status)
51 {
52  jack_varargs_t va; /* variable arguments */
53  jack_status_t my_status;
54  JackClient* client;
55 
56  if (client_name == NULL) {
57  jack_error("jack_client_new called with a NULL client_name");
58  return NULL;
59  }
60 
61  jack_log("jack_client_new %s", client_name);
62 
63  if (status == NULL) /* no status from caller? */
64  status = &my_status; /* use local status word */
65  *status = (jack_status_t)0;
66 
67  /* validate parameters */
68  if ((options & ~JackOpenOptions)) {
69  int my_status1 = *status | (JackFailure | JackInvalidOption);
70  *status = (jack_status_t)my_status1;
71  return NULL;
72  }
73 
74  /* parse variable arguments */
75  jack_varargs_init(&va);
76 
77  if (!JackServerGlobals::Init()) { // jack server initialisation
78  int my_status1 = (JackFailure | JackServerError);
79  *status = (jack_status_t)my_status1;
80  return NULL;
81  }
82 
83  if (JACK_DEBUG) {
84  client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode
85  } else {
86  client = new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable());
87  }
88 
89  int res = client->Open(va.server_name, client_name, va.session_id, options, status);
90  if (res < 0) {
91  delete client;
92  JackServerGlobals::Destroy(); // jack server destruction
93  int my_status1 = (JackFailure | JackServerError);
94  *status = (jack_status_t)my_status1;
95  return NULL;
96  } else {
97  return (jack_client_t*)client;
98  }
99 }
100 
101 jack_client_t* jack_client_open_aux(const char* client_name, jack_options_t options, jack_status_t* status, va_list ap)
102 {
103  jack_varargs_t va; /* variable arguments */
104  jack_status_t my_status;
105  JackClient* client;
106 
107  if (client_name == NULL) {
108  jack_error("jack_client_open called with a NULL client_name");
109  return NULL;
110  }
111 
112  jack_log("jack_client_open %s", client_name);
113 
114  if (status == NULL) /* no status from caller? */
115  status = &my_status; /* use local status word */
116  *status = (jack_status_t)0;
117 
118  /* validate parameters */
119  if ((options & ~JackOpenOptions)) {
120  int my_status1 = *status | (JackFailure | JackInvalidOption);
121  *status = (jack_status_t)my_status1;
122  return NULL;
123  }
124 
125  /* parse variable arguments */
126  jack_varargs_parse(options, ap, &va);
127 
128  if (!JackServerGlobals::Init()) { // jack server initialisation
129  int my_status1 = (JackFailure | JackServerError);
130  *status = (jack_status_t)my_status1;
131  return NULL;
132  }
133 
134  if (JACK_DEBUG) {
135  client = new JackDebugClient(new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable())); // Debug mode
136  } else {
137  client = new JackInternalClient(JackServerGlobals::fInstance, GetSynchroTable());
138  }
139 
140  int res = client->Open(va.server_name, client_name, va.session_id, options, status);
141  if (res < 0) {
142  delete client;
143  JackServerGlobals::Destroy(); // jack server destruction
144  int my_status1 = (JackFailure | JackServerError);
145  *status = (jack_status_t)my_status1;
146  return NULL;
147  } else {
148  return (jack_client_t*)client;
149  }
150 }
151 
152 SERVER_EXPORT jack_client_t* jack_client_open(const char* ext_client_name, jack_options_t options, jack_status_t* status, ...)
153 {
154  JackGlobals::CheckContext("jack_client_open");
155 
156  try {
157  assert(JackGlobals::fOpenMutex);
158  JackGlobals::fOpenMutex->Lock();
159  va_list ap;
160  va_start(ap, status);
161  jack_client_t* res = jack_client_open_aux(ext_client_name, options, status, ap);
162  va_end(ap);
163  JackGlobals::fOpenMutex->Unlock();
164  return res;
165  } catch (std::bad_alloc& e) {
166  jack_error("Memory allocation error...");
167  return NULL;
168  } catch (...) {
169  jack_error("Unknown error...");
170  return NULL;
171  }
172 }
173 
174 SERVER_EXPORT int jack_client_close(jack_client_t* ext_client)
175 {
176  JackGlobals::CheckContext("jack_client_close");
177 
178  assert(JackGlobals::fOpenMutex);
179  JackGlobals::fOpenMutex->Lock();
180  int res = -1;
181  jack_log("jack_client_close");
182  JackClient* client = (JackClient*)ext_client;
183  if (client == NULL) {
184  jack_error("jack_client_close called with a NULL client");
185  } else {
186  res = client->Close();
187  delete client;
188  JackServerGlobals::Destroy(); // jack server destruction
189  jack_log("jack_client_close res = %d", res);
190  }
191  JackGlobals::fOpenMutex->Unlock();
192  return res;
193 }
194 
195 SERVER_EXPORT int jack_get_client_pid(const char *name)
196 {
197  return (JackServerGlobals::fInstance != NULL)
198  ? JackServerGlobals::fInstance->GetEngine()->GetClientPID(name)
199  : 0;
200 }
201 
Internal clients in the server.
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:91
LIB_EXPORT jack_client_t * jack_client_open(const char *client_name, jack_options_t options, jack_status_t *status,...)
Definition: JackLibAPI.cpp:167
LIB_EXPORT int jack_get_client_pid(const char *name)
Definition: JackLibAPI.cpp:210
A &quot;decorator&quot; debug client to validate API use.
SERVER_EXPORT void jack_log(const char *fmt,...)
Definition: JackError.cpp:107
The base class for clients: share part of the implementation for JackInternalClient and JackLibClient...
Definition: JackClient.h:47
LIB_EXPORT int jack_client_close(jack_client_t *client)
Definition: JackLibAPI.cpp:189