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"
22 #include "JackLibGlobals.h"
23 #include "JackGlobals.h"
24 #include "JackPlatformPlug.h"
25 #include "JackTools.h"
30 // Used for external C API (JackAPI.cpp)
31 JackGraphManager
* GetGraphManager()
33 if (JackLibGlobals::fGlobals
) {
34 return JackLibGlobals::fGlobals
->fGraphManager
;
40 JackEngineControl
* GetEngineControl()
42 if (JackLibGlobals::fGlobals
) {
43 return JackLibGlobals::fGlobals
->fEngineControl
;
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
;
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");
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
;
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",
104 JACK_CLIENT_NAME_SIZE
- 1);
108 strncpy(fServerName
, server_name
, sizeof(fServerName
));
110 // Open server/client channel
111 char name_res
[JACK_CLIENT_NAME_SIZE
+1];
112 if (fChannel
->Open(server_name
, name
, uuid
, name_res
, this, options
, status
) < 0) {
113 jack_error("Cannot connect to the server");
117 // Start receiving notifications
118 if (fChannel
->Start() < 0) {
119 jack_error("Cannot start channel");
123 // Require new client
124 fChannel
->ClientOpen(name_res
, JackTools::GetPID(), uuid
, &shared_engine
, &shared_client
, &shared_graph
, &result
);
126 jack_error("Cannot open %s client", name_res
);
131 // Map shared memory segments
132 JackLibGlobals::fGlobals
->fEngineControl
.SetShmIndex(shared_engine
, fServerName
);
133 JackLibGlobals::fGlobals
->fGraphManager
.SetShmIndex(shared_graph
, fServerName
);
134 fClientControl
.SetShmIndex(shared_client
, fServerName
);
135 JackGlobals::fVerbose
= GetEngineControl()->fVerbose
;
137 jack_error("Map shared memory segments exception");
141 SetupDriverSync(false);
143 // Connect shared synchro : the synchro must be usable in I/O mode when several clients live in the same process
144 assert(JackGlobals::fSynchroMutex
);
145 JackGlobals::fSynchroMutex
->Lock();
146 res
= fSynchroTable
[GetClientControl()->fRefNum
].Connect(name_res
, fServerName
);
147 JackGlobals::fSynchroMutex
->Unlock();
149 jack_error("Cannot ConnectSemaphore %s client", name_res
);
153 JackGlobals::fClientTable
[GetClientControl()->fRefNum
] = this;
154 SetClockSource(GetEngineControl()->fClockSource
);
155 jack_log("JackLibClient::Open name = %s refnum = %ld", name_res
, GetClientControl()->fRefNum
);
164 // Notifications received from the server
165 // TODO this should be done once for all clients in the process, when a shared notification channel
166 // will be shared by all clients...
167 int JackLibClient::ClientNotifyImp(int refnum
, const char* name
, int notify
, int sync
, const char* message
, int value1
, int value2
)
170 assert(JackGlobals::fSynchroMutex
);
171 JackGlobals::fSynchroMutex
->Lock();
177 jack_log("JackClient::AddClient name = %s, ref = %ld ", name
, refnum
);
178 // the synchro must be usable in I/O mode when several clients live in the same process
179 res
= fSynchroTable
[refnum
].Connect(name
, fServerName
) ? 0 : -1;
183 jack_log("JackClient::RemoveClient name = %s, ref = %ld ", name
, refnum
);
184 if (GetClientControl() && strcmp(GetClientControl()->fName
, name
) != 0) {
185 res
= fSynchroTable
[refnum
].Disconnect() ? 0 : -1;
190 JackGlobals::fSynchroMutex
->Unlock();
194 JackGraphManager
* JackLibClient::GetGraphManager() const
196 assert(JackLibGlobals::fGlobals
->fGraphManager
);
197 return JackLibGlobals::fGlobals
->fGraphManager
;
200 JackEngineControl
* JackLibClient::GetEngineControl() const
202 assert(JackLibGlobals::fGlobals
->fEngineControl
);
203 return JackLibGlobals::fGlobals
->fEngineControl
;
206 JackClientControl
* JackLibClient::GetClientControl() const
208 return fClientControl
;
211 } // end of namespace