Jack2  1.9.8
JackInternalClient.cpp
1 /*
2 Copyright (C) 2001 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 "JackServerGlobals.h"
23 #include "JackGraphManager.h"
24 #include "JackConstants.h"
25 #include "JackInternalClient.h"
26 #include "JackLockedEngine.h"
27 #include "JackServer.h"
28 #include "JackEngineControl.h"
29 #include "JackClientControl.h"
30 #include "JackInternalClientChannel.h"
31 #include "JackTools.h"
32 #include <assert.h>
33 
34 namespace Jack
35 {
36 
37 JackGraphManager* JackInternalClient::fGraphManager = NULL;
38 JackEngineControl* JackInternalClient::fEngineControl = NULL;
39 
40 // Used for external C API (JackAPI.cpp)
41 SERVER_EXPORT JackGraphManager* GetGraphManager()
42 {
43  return JackServerGlobals::fInstance->GetGraphManager();
44 }
45 
46 SERVER_EXPORT JackEngineControl* GetEngineControl()
47 {
48  return JackServerGlobals::fInstance->GetEngineControl();
49 }
50 
51 SERVER_EXPORT JackSynchro* GetSynchroTable()
52 {
53  return JackServerGlobals::fInstance->GetSynchroTable();
54 }
55 
57 {
58  fChannel = new JackInternalClientChannel(server);
59 }
60 
61 JackInternalClient::~JackInternalClient()
62 {
63  delete fChannel;
64 }
65 
66 int JackInternalClient::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status)
67 {
68  int result;
69  char name_res[JACK_CLIENT_NAME_SIZE + 1];
70  jack_log("JackInternalClient::Open name = %s", name);
71 
72  strncpy(fServerName, server_name, sizeof(fServerName));
73 
74  fChannel->ClientCheck(name, uuid, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result, false);
75  if (result < 0) {
76  int status1 = *status;
77  if (status1 & JackVersionError) {
78  jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
79  } else {
80  jack_error("Client name = %s conflits with another running client", name);
81  }
82  goto error;
83  }
84 
85  strcpy(fClientControl.fName, name_res);
86 
87  // Require new client
88  fChannel->ClientOpen(name_res, &fClientControl.fRefNum, &fEngineControl, &fGraphManager, this, &result);
89  if (result < 0) {
90  jack_error("Cannot open client name = %s", name_res);
91  goto error;
92  }
93 
94  SetupDriverSync(false);
95  JackGlobals::fClientTable[fClientControl.fRefNum] = this;
96  JackGlobals::fServerRunning = true;
97  jack_log("JackInternalClient::Open name = %s refnum = %ld", name_res, fClientControl.fRefNum);
98  return 0;
99 
100 error:
101  fChannel->Stop();
102  fChannel->Close();
103  return -1;
104 }
105 
106 JackGraphManager* JackInternalClient::GetGraphManager() const
107 {
108  assert(fGraphManager);
109  return fGraphManager;
110 }
111 
112 JackEngineControl* JackInternalClient::GetEngineControl() const
113 {
114  assert(fEngineControl);
115  return fEngineControl;
116 }
117 
118 JackClientControl* JackInternalClient::GetClientControl() const
119 {
120  return const_cast<JackClientControl*>(&fClientControl);
121 }
122 
123 int JackLoadableInternalClient::Init(const char* so_name)
124 {
125  char path_to_so[JACK_PATH_MAX + 1];
126  BuildClientPath(path_to_so, sizeof(path_to_so), so_name);
127 
128  fHandle = LoadJackModule(path_to_so);
129  jack_log("JackLoadableInternalClient::JackLoadableInternalClient path_to_so = %s", path_to_so);
130 
131  if (fHandle == NULL) {
132  PrintLoadError(so_name);
133  return -1;
134  }
135 
136  fFinish = (FinishCallback)GetJackProc(fHandle, "jack_finish");
137  if (fFinish == NULL) {
138  UnloadJackModule(fHandle);
139  jack_error("symbol jack_finish cannot be found in %s", so_name);
140  return -1;
141  }
142 
143  fDescriptor = (JackDriverDescFunction)GetJackProc(fHandle, "jack_get_descriptor");
144  if (fDescriptor == NULL) {
145  jack_info("No jack_get_descriptor entry-point for %s", so_name);
146  }
147  return 0;
148 }
149 
150 int JackLoadableInternalClient1::Init(const char* so_name)
151 {
152  if (JackLoadableInternalClient::Init(so_name) < 0) {
153  return -1;
154  }
155 
156  fInitialize = (InitializeCallback)GetJackProc(fHandle, "jack_initialize");
157  if (fInitialize == NULL) {
158  UnloadJackModule(fHandle);
159  jack_error("symbol jack_initialize cannot be found in %s", so_name);
160  return -1;
161  }
162 
163  return 0;
164 }
165 
166 int JackLoadableInternalClient2::Init(const char* so_name)
167 {
168  if (JackLoadableInternalClient::Init(so_name) < 0) {
169  return -1;
170  }
171 
172  fInitialize = (InternalInitializeCallback)GetJackProc(fHandle, "jack_internal_initialize");
173  if (fInitialize == NULL) {
174  UnloadJackModule(fHandle);
175  jack_error("symbol jack_internal_initialize cannot be found in %s", so_name);
176  return -1;
177  }
178 
179  return 0;
180 }
181 
182 JackLoadableInternalClient1::JackLoadableInternalClient1(JackServer* server, JackSynchro* table, const char* object_data)
183  : JackLoadableInternalClient(server, table)
184 {
185  strncpy(fObjectData, object_data, JACK_LOAD_INIT_LIMIT);
186 }
187 
188 JackLoadableInternalClient2::JackLoadableInternalClient2(JackServer* server, JackSynchro* table, const JSList* parameters)
189  : JackLoadableInternalClient(server, table)
190 {
191  fParameters = parameters;
192 }
193 
194 JackLoadableInternalClient::~JackLoadableInternalClient()
195 {
196  if (fFinish != NULL)
197  fFinish(fProcessArg);
198  if (fHandle != NULL)
199  UnloadJackModule(fHandle);
200 }
201 
202 int JackLoadableInternalClient1::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status)
203 {
204  int res = -1;
205 
206  if (JackInternalClient::Open(server_name, name, uuid, options, status) == 0) {
207  if (fInitialize((jack_client_t*)this, fObjectData) == 0) {
208  res = 0;
209  } else {
210  JackInternalClient::Close();
211  fFinish = NULL;
212  }
213  }
214 
215  return res;
216 }
217 
218 int JackLoadableInternalClient2::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status)
219 {
220  int res = -1;
221 
222  if (JackInternalClient::Open(server_name, name, uuid, options, status) == 0) {
223  if (fInitialize((jack_client_t*)this, fParameters) == 0) {
224  res = 0;
225  } else {
226  JackInternalClient::Close();
227  fFinish = NULL;
228  }
229  }
230 
231  return res;
232 }
233 
234 } // end of namespace
235