Jack2 1.9.12

JackLibClient.cpp
1 /*
2 Copyright (C) 2004-2008 Grame
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU Lesser General Public License as published by
6 the Free Software Foundation; either version 2.1 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
18 */
19
20 #include "JackLibClient.h"
21 #include "JackTime.h"
22 #include "JackLibGlobals.h"
23 #include "JackGlobals.h"
24 #include "JackPlatformPlug.h"
25 #include "JackTools.h"
26
27 namespace Jack
28 {
29
30 // Used for external C API (JackAPI.cpp)
31 JackGraphManager* GetGraphManager()
32 {
33 if (JackLibGlobals::fGlobals) {
34 return JackLibGlobals::fGlobals->fGraphManager;
35 } else {
36 return NULL;
37 }
38 }
39
40 JackEngineControl* GetEngineControl()
41 {
42 if (JackLibGlobals::fGlobals) {
43 return JackLibGlobals::fGlobals->fEngineControl;
44 } else {
45 return NULL;
46 }
47 }
48
49 JackSynchro* GetSynchroTable()
50 {
51 return (JackLibGlobals::fGlobals ? JackLibGlobals::fGlobals->fSynchroTable : 0);
52 }
53
54 //-------------------
55 // Client management
56 //-------------------
57
58 /*
59 ShutDown is called:
60 - from the RT thread when Execute method fails
61 - possibly from a "closed" notification channel
62 (Not needed since the synch object used (Sema of Fifo will fails when server quits... see ShutDown))
63 */
64
65 void JackLibClient::ShutDown(jack_status_t code, const char* message)
66 {
67 jack_log("JackLibClient::ShutDown");
68 JackGlobals::fServerRunning = false;
69 JackClient::ShutDown(code, message);
70 }
71
72 JackLibClient::JackLibClient(JackSynchro* table): JackClient(table)
73 {
74 jack_log("JackLibClient::JackLibClient table = %x", table);
75 fChannel = new JackClientChannel();
76 }
77
78 JackLibClient::~JackLibClient()
79 {
80 jack_log("JackLibClient::~JackLibClient");
81 delete fChannel;
82 }
83
84 int JackLibClient::Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status)
85 {
86 int shared_engine, shared_client, shared_graph, result;
87 bool res;
88 jack_log("JackLibClient::Open name = %s", name);
89
90 if (strlen(name) >= JACK_CLIENT_NAME_SIZE) {
91 jack_error("\"%s\" is too long to be used as a JACK client name.\n"
92 "Please use %lu characters or less",
93 name,
94 JACK_CLIENT_NAME_SIZE - 1);
95 return -1;
96 }
97
98 strncpy(fServerName, server_name, sizeof(fServerName));
99
100 // Open server/client channel
101 char name_res[JACK_CLIENT_NAME_SIZE+1];
102 if (fChannel->Open(server_name, name, uuid, name_res, this, options, status) < 0) {
103 jack_error("Cannot connect to the server");
104 goto error;
105 }
106
107 // Start receiving notifications
108 if (fChannel->Start() < 0) {
109 jack_error("Cannot start channel");
110 goto error;
111 }
112
113 // Require new client
114 fChannel->ClientOpen(name_res, JackTools::GetPID(), uuid, &shared_engine, &shared_client, &shared_graph, &result);
115 if (result < 0) {
116 jack_error("Cannot open %s client", name_res);
117 goto error;
118 }
119
120 try {
121 // Map shared memory segments
122 JackLibGlobals::fGlobals->fEngineControl.SetShmIndex(shared_engine, fServerName);
123 JackLibGlobals::fGlobals->fGraphManager.SetShmIndex(shared_graph, fServerName);
124 fClientControl.SetShmIndex(shared_client, fServerName);
125 JackGlobals::fVerbose = GetEngineControl()->fVerbose;
126 } catch (...) {
127 jack_error("Map shared memory segments exception");
128 goto error;
129 }
130
131 SetupDriverSync(false);
132
133 // Connect shared synchro : the synchro must be usable in I/O mode when several clients live in the same process
134 assert(JackGlobals::fSynchroMutex);
135 JackGlobals::fSynchroMutex->Lock();
136 res = fSynchroTable[GetClientControl()->fRefNum].Connect(name_res, fServerName);
137 JackGlobals::fSynchroMutex->Unlock();
138 if (!res) {
139 jack_error("Cannot ConnectSemaphore %s client", name_res);
140 goto error;
141 }
142
143 JackGlobals::fClientTable[GetClientControl()->fRefNum] = this;
144 SetClockSource(GetEngineControl()->fClockSource);
145 jack_log("JackLibClient::Open name = %s refnum = %ld", name_res, GetClientControl()->fRefNum);
146 return 0;
147
148 error:
149 fChannel->Stop();
150 fChannel->Close();
151 return -1;
152 }
153
154 // Notifications received from the server
155 // TODO this should be done once for all clients in the process, when a shared notification channel
156 // will be shared by all clients...
157 int JackLibClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2)
158 {
159 int res = 0;
160 assert(JackGlobals::fSynchroMutex);
161 JackGlobals::fSynchroMutex->Lock();
162
163 // Done all time
164 switch (notify) {
165
166 case kAddClient:
167 jack_log("JackClient::AddClient name = %s, ref = %ld ", name, refnum);
168 // the synchro must be usable in I/O mode when several clients live in the same process
169 res = fSynchroTable[refnum].Connect(name, fServerName) ? 0 : -1;
170 break;
171
172 case kRemoveClient:
173 jack_log("JackClient::RemoveClient name = %s, ref = %ld ", name, refnum);
174 if (GetClientControl() && strcmp(GetClientControl()->fName, name) != 0) {
175 res = fSynchroTable[refnum].Disconnect() ? 0 : -1;
176 }
177 break;
178 }
179
180 JackGlobals::fSynchroMutex->Unlock();
181 return res;
182 }
183
184 JackGraphManager* JackLibClient::GetGraphManager() const
185 {
186 assert(JackLibGlobals::fGlobals->fGraphManager);
187 return JackLibGlobals::fGlobals->fGraphManager;
188 }
189
190 JackEngineControl* JackLibClient::GetEngineControl() const
191 {
192 assert(JackLibGlobals::fGlobals->fEngineControl);
193 return JackLibGlobals::fGlobals->fEngineControl;
194 }
195
196 JackClientControl* JackLibClient::GetClientControl() const
197 {
198 return fClientControl;
199 }
200
201 } // end of namespace
202
203
204
Jack::JackPosixSemaphore
Inter process synchronization using POSIX semaphore.
Definition: JackPosixSemaphore.h:36
jack_error
SERVER_EXPORT void jack_error(const char *fmt,...)
Definition: JackError.cpp:92
Jack::JackGraphManager
Graph manager: contains the connection manager and the port array.
Definition: JackGraphManager.h:40
Jack::JackClient::SetupDriverSync
void SetupDriverSync(bool freewheel)
Definition: JackClient.cpp:138
Jack::JackSocketClientChannel
JackClientChannel using sockets.
Definition: JackSocketClientChannel.h:37
Jack::JackLibClient::JackLibClient
JackLibClient(JackSynchro *table)
Definition: JackLibClient.cpp:72
Jack::JackLibClient::ClientNotifyImp
int ClientNotifyImp(int refnum, const char *name, int notify, int sync, const char *message, int value1, int value2)
Notification received from the server.
Definition: JackLibClient.cpp:157
Jack::JackClient::fChannel
detail::JackClientChannelInterface * fChannel
Definition: JackClient.h:93
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