Better isolation of server and clients system resources to allow starting the server...
[jack2.git] / common / JackLibClient.cpp
blob39a854e67be89f0268e10ca981f2a205ca8cfb43
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 //-------------------
55 // Client management
56 //-------------------
58 JackLibClient::JackLibClient(JackSynchro* table): JackClient(table)
60 jack_log("JackLibClient::JackLibClient table = %x", table);
61 fChannel = new JackClientChannel();
64 JackLibClient::~JackLibClient()
66 jack_log("JackLibClient::~JackLibClient");
67 delete fChannel;
70 int JackLibClient::Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status)
72 int shared_engine, shared_client, shared_graph, result;
73 jack_log("JackLibClient::Open %s", name);
75 snprintf(fServerName, sizeof(fServerName), server_name);
77 // Open server/client channel
78 char name_res[JACK_CLIENT_NAME_SIZE + 1];
79 if (fChannel->Open(server_name, name, name_res, this, options, status) < 0) {
80 jack_error("Cannot connect to the server");
81 goto error;
84 // Start receiving notifications
85 if (fChannel->Start() < 0) {
86 jack_error("Cannot start channel");
87 goto error;
90 // Require new client
91 fChannel->ClientOpen(name_res, JackTools::GetPID(), &shared_engine, &shared_client, &shared_graph, &result);
92 if (result < 0) {
93 jack_error("Cannot open %s client", name_res);
94 goto error;
97 try {
98 // Map shared memory segments
99 JackLibGlobals::fGlobals->fEngineControl.SetShmIndex(shared_engine, fServerName);
100 JackLibGlobals::fGlobals->fGraphManager.SetShmIndex(shared_graph, fServerName);
101 fClientControl.SetShmIndex(shared_client, fServerName);
102 jack_verbose = GetEngineControl()->fVerbose;
103 } catch (int n) {
104 jack_error("Map shared memory segments exception %d", n);
105 goto error;
108 SetupDriverSync(false);
110 // Connect shared synchro : the synchro must be usable in I/O mode when several clients live in the same process
111 if (!fSynchroTable[GetClientControl()->fRefNum].Connect(name_res, fServerName)) {
112 jack_error("Cannot ConnectSemaphore %s client", name_res);
113 goto error;
116 fClientTable[GetClientControl()->fRefNum] = this;
117 jack_log("JackLibClient::Open name = %s refnum = %ld", name_res, GetClientControl()->fRefNum);
118 return 0;
120 error:
121 fChannel->Stop();
122 fChannel->Close();
123 return -1;
126 // Notifications received from the server
127 // TODO this should be done once for all clients in the process, when a shared notification channel
128 // will be shared by all clients...
129 int JackLibClient::ClientNotifyImp(int refnum, const char* name, int notify, int sync, int value1, int value2)
131 int res = 0;
133 // Done all time
134 switch (notify) {
136 case kAddClient:
137 jack_log("JackClient::AddClient name = %s, ref = %ld ", name, refnum);
138 // the synchro must be usable in I/O mode when several clients live in the same process
139 res = fSynchroTable[refnum].Connect(name, fServerName) ? 0 : -1;
140 break;
142 case kRemoveClient:
143 jack_log("JackClient::RemoveClient name = %s, ref = %ld ", name, refnum);
144 if (strcmp(GetClientControl()->fName, name) != 0)
145 res = fSynchroTable[refnum].Disconnect() ? 0 : -1;
146 break;
149 return res;
152 JackGraphManager* JackLibClient::GetGraphManager() const
154 assert(JackLibGlobals::fGlobals->fGraphManager);
155 return JackLibGlobals::fGlobals->fGraphManager;
158 JackEngineControl* JackLibClient::GetEngineControl() const
160 assert(JackLibGlobals::fGlobals->fEngineControl);
161 return JackLibGlobals::fGlobals->fEngineControl;
164 JackClientControl* JackLibClient::GetClientControl() const
166 return fClientControl;
169 } // end of namespace