Jack2 1.9.12

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
Jack::JackInternalClient
Internal clients in the server.
Definition: JackInternalClient.h:37
jack_varargs_t
Definition: varargs.h:34
jack_error
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:92
jack_client_open
SERVER_EXPORT jack_client_t * jack_client_open(const char *client_name, jack_options_t options, jack_status_t *status,...)
Definition: JackServerAPI.cpp:152
jack_get_client_pid
SERVER_EXPORT int jack_get_client_pid(const char *name)
Definition: JackServerAPI.cpp:195
Jack::JackDebugClient
A "decorator" debug client to validate API use.
Definition: JackDebugClient.h:49
jack_log
SERVER_EXPORT void jack_log(const char *fmt,...)
Definition: JackError.cpp:108
Jack::JackClient
The base class for clients: share part of the implementation for JackInternalClient and JackLibClient...
Definition: JackClient.h:47
jack_client_close
SERVER_EXPORT int jack_client_close(jack_client_t *client)
Definition: JackServerAPI.cpp:174