Clarification about jack_port_get_latency_range().
[jack2.git] / common / JackLibClient.cpp
blob2e772977117f00a8444abc7958a4e9b08bc09aff
1 /*
2 Copyright (C) 2004-2008 Grame
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.
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.
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.
20 #include "JackLibClient.h"
21 #include "JackTime.h"
22 #include "JackLibGlobals.h"
23 #include "JackGlobals.h"
24 #include "JackPlatformPlug.h"
25 #include "JackTools.h"
27 namespace Jack
30 // Used for external C API (JackAPI.cpp)
31 JackGraphManager* GetGraphManager()
33 if (JackLibGlobals::fGlobals) {
34 return JackLibGlobals::fGlobals->fGraphManager;
35 } else {
36 return NULL;
40 JackEngineControl* GetEngineControl()
42 if (JackLibGlobals::fGlobals) {
43 return JackLibGlobals::fGlobals->fEngineControl;
44 } else {
45 return NULL;
49 JackSynchro* GetSynchroTable()
51 return (JackLibGlobals::fGlobals ? JackLibGlobals::fGlobals->fSynchroTable : 0);
54 // Used for client-side Metadata API (JackLibAPI.cpp)
55 JackMetadata* GetMetadata()
57 if (JackLibGlobals::fGlobals) {
58 return JackLibGlobals::fGlobals->fMetadata;
59 } else {
60 return NULL;
64 //-------------------
65 // Client management
66 //-------------------
69 ShutDown is called:
70 - from the RT thread when Execute method fails
71 - possibly from a "closed" notification channel
72 (Not needed since the synch object used (Sema of Fifo will fails when server quits... see ShutDown))
75 void JackLibClient::ShutDown(jack_status_t code, const char* message)
77 jack_log("JackLibClient::ShutDown");
78 JackGlobals::fServerRunning = false;
79 JackClient::ShutDown(code, message);
82 JackLibClient::JackLibClient(JackSynchro* table): JackClient(table)
84 jack_log("JackLibClient::JackLibClient table = %x", table);
85 fChannel = new JackClientChannel();
88 JackLibClient::~JackLibClient()
90 jack_log("JackLibClient::~JackLibClient");
91 delete fChannel;
94 int JackLibClient::Open(const char* server_name, const char* name, jack_uuid_t uuid, jack_options_t options, jack_status_t* status)
96 int shared_engine, shared_client, shared_graph, result;
97 bool res;
98 jack_log("JackLibClient::Open name = %s", name);
100 if (strlen(name) >= JACK_CLIENT_NAME_SIZE) {
101 jack_error("\"%s\" is too long to be used as a JACK client name.\n"
102 "Please use %lu characters or less",
103 name,
104 JACK_CLIENT_NAME_SIZE - 1);
105 return -1;
108 strncpy(fServerName, server_name, sizeof(fServerName));
109 fServerName[sizeof(fServerName) - 1] = 0;
111 // Open server/client channel
112 char name_res[JACK_CLIENT_NAME_SIZE+1];
113 if (fChannel->Open(server_name, name, uuid, name_res, this, options, status) < 0) {
114 jack_error("Cannot connect to the server");
115 goto error;
118 // Start receiving notifications
119 if (fChannel->Start() < 0) {
120 jack_error("Cannot start channel");
121 goto error;
124 // Require new client
125 fChannel->ClientOpen(name_res, JackTools::GetPID(), uuid, &shared_engine, &shared_client, &shared_graph, &result);
126 if (result < 0) {
127 jack_error("Cannot open %s client", name_res);
128 goto error;
131 try {
132 // Map shared memory segments
133 JackLibGlobals::fGlobals->fEngineControl.SetShmIndex(shared_engine, fServerName);
134 JackLibGlobals::fGlobals->fGraphManager.SetShmIndex(shared_graph, fServerName);
135 fClientControl.SetShmIndex(shared_client, fServerName);
136 JackGlobals::fVerbose = GetEngineControl()->fVerbose;
137 } catch (...) {
138 jack_error("Map shared memory segments exception");
139 goto error;
142 SetupDriverSync(false);
144 // Connect shared synchro : the synchro must be usable in I/O mode when several clients live in the same process
145 assert(JackGlobals::fSynchroMutex);
146 JackGlobals::fSynchroMutex->Lock();
147 res = fSynchroTable[GetClientControl()->fRefNum].Connect(name_res, fServerName);
148 JackGlobals::fSynchroMutex->Unlock();
149 if (!res) {
150 jack_error("Cannot ConnectSemaphore %s client", name_res);
151 goto error;
154 JackGlobals::fClientTable[GetClientControl()->fRefNum] = this;
155 SetClockSource(GetEngineControl()->fClockSource);
156 jack_log("JackLibClient::Open name = %s refnum = %ld", name_res, GetClientControl()->fRefNum);
157 return 0;
159 error:
160 fChannel->Stop();
161 fChannel->Close();
162 return -1;
165 // Notifications received from the server
166 // TODO this should be done once for all clients in the process, when a shared notification channel
167 // will be shared by all clients...
168 int JackLibClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, const char* message, int value1, int value2)
170 int res = 0;
171 assert(JackGlobals::fSynchroMutex);
172 JackGlobals::fSynchroMutex->Lock();
174 // Done all time
175 switch (notify) {
177 case kAddClient:
178 jack_log("JackClient::AddClient name = %s, ref = %ld ", name, refnum);
179 // the synchro must be usable in I/O mode when several clients live in the same process
180 res = fSynchroTable[refnum].Connect(name, fServerName) ? 0 : -1;
181 break;
183 case kRemoveClient:
184 jack_log("JackClient::RemoveClient name = %s, ref = %ld ", name, refnum);
185 if (GetClientControl() && strcmp(GetClientControl()->fName, name) != 0) {
186 res = fSynchroTable[refnum].Disconnect() ? 0 : -1;
188 break;
191 JackGlobals::fSynchroMutex->Unlock();
192 return res;
195 JackGraphManager* JackLibClient::GetGraphManager() const
197 assert(JackLibGlobals::fGlobals->fGraphManager);
198 return JackLibGlobals::fGlobals->fGraphManager;
201 JackEngineControl* JackLibClient::GetEngineControl() const
203 assert(JackLibGlobals::fGlobals->fEngineControl);
204 return JackLibGlobals::fGlobals->fEngineControl;
207 JackClientControl* JackLibClient::GetClientControl() const
209 return fClientControl;
212 } // end of namespace