~ubuntu-branches/debian/sid/jackd2/sid

« back to all changes in this revision

Viewing changes to macosx/JackMachClientChannel.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adrian Knoth
  • Date: 2011-03-31 13:54:50 UTC
  • mfrom: (1.1.3 upstream) (2.1.4 experimental)
  • Revision ID: james.westby@ubuntu.com-20110331135450-zafc1di024kzeu31
Tags: 1.9.7~dfsg-1
* New upstream version 1.9.7 (ALSA resume, new latency API)
* Build with --mixed on i386 to be compatible with amd64.
* Don't patch jack_connect for fast consecutive calls anymore, it's now
  using the same code as in jackd1 and waits for the port connection to
  appear.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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 "JackMachClientChannel.h"
21
 
#include "JackRPCEngine.h"
22
 
#include "JackTools.h"
23
 
#include "JackRPCClientServer.c"
24
 
#include "JackError.h"
25
 
#include "JackLibClient.h"
26
 
#include "JackMachThread.h"
27
 
#include "JackConstants.h"
28
 
 
29
 
namespace Jack
30
 
{
31
 
 
32
 
std::map<mach_port_t, JackClient*> gClientTable;
33
 
 
34
 
JackMachClientChannel::JackMachClientChannel():fPrivatePort(0),fThread(this)
35
 
{}
36
 
 
37
 
JackMachClientChannel::~JackMachClientChannel()
38
 
{}
39
 
 
40
 
// Server <===> client
41
 
 
42
 
int JackMachClientChannel::ServerCheck(const char* server_name)
43
 
{
44
 
    jack_log("JackMachClientChannel::ServerCheck = %s", server_name);
45
 
    char jack_server_entry_name[512];
46
 
    snprintf(jack_server_entry_name, sizeof(jack_server_entry_name), "%s.%d_%s", jack_server_entry, JackTools::GetUID(), server_name);
47
 
 
48
 
    // Connect to server
49
 
    if (!fServerPort.ConnectPort(jack_server_entry_name)) {
50
 
        jack_error("Cannot connect to server Mach port");
51
 
        return -1;
52
 
    } else {
53
 
        return 0;
54
 
    }
55
 
}
56
 
 
57
 
int JackMachClientChannel::Open(const char* server_name, const char* name, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status)
58
 
{
59
 
    jack_log("JackMachClientChannel::Open name = %s", name);
60
 
    char jack_server_entry_name[512];
61
 
    snprintf(jack_server_entry_name, sizeof(jack_server_entry_name), "%s.%d_%s", jack_server_entry, JackTools::GetUID(), server_name);
62
 
 
63
 
    // Connect to server
64
 
    if (!fServerPort.ConnectPort(jack_server_entry_name)) {
65
 
        jack_error("Cannot connect to server Mach port");
66
 
        return -1;
67
 
    }
68
 
 
69
 
    // Check name in server
70
 
    int result = 0;
71
 
    ClientCheck(name, name_res, JACK_PROTOCOL_VERSION, (int)options, (int*)status, &result);
72
 
    if (result < 0) {
73
 
        int status1 = *status;
74
 
        if (status1 & JackVersionError)
75
 
            jack_error("JACK protocol mismatch %d", JACK_PROTOCOL_VERSION);
76
 
        else
77
 
            jack_error("Client name = %s conflits with another running client", name);
78
 
        return -1;
79
 
    }
80
 
 
81
 
    // Prepare local port using client name
82
 
    char buf[JACK_CLIENT_NAME_SIZE + 1];
83
 
    snprintf(buf, sizeof(buf) - 1, "%s:%s", jack_client_entry, name_res);
84
 
 
85
 
    if (!fClientPort.AllocatePort(buf, 16)) {
86
 
        jack_error("Cannot allocate client Mach port");
87
 
        return -1;
88
 
    }
89
 
 
90
 
    gClientTable[fClientPort.GetPort()] = client;
91
 
    return 0;
92
 
}
93
 
 
94
 
void JackMachClientChannel::Close()
95
 
{
96
 
    jack_log("JackMachClientChannel::Close");
97
 
    gClientTable.erase(fClientPort.GetPort());
98
 
    fServerPort.DisconnectPort();
99
 
    fClientPort.DestroyPort();
100
 
 
101
 
    if (fPrivatePort != 0) {
102
 
         kern_return_t res;
103
 
        if ((res = mach_port_destroy(mach_task_self(), fPrivatePort)) != KERN_SUCCESS) {
104
 
            jack_error("JackMachClientChannel::Close err = %s", mach_error_string(res));
105
 
        }
106
 
    }
107
 
}
108
 
 
109
 
int JackMachClientChannel::Start()
110
 
{
111
 
    jack_log("JackMachClientChannel::Start");
112
 
    /*
113
 
     To be sure notification thread is started before ClientOpen is called.
114
 
    */
115
 
    if (fThread.StartSync() != 0) {
116
 
        jack_error("Cannot start Jack client listener");
117
 
        return -1;
118
 
    } else {
119
 
        return 0;
120
 
    }
121
 
}
122
 
 
123
 
void JackMachClientChannel::Stop()
124
 
{
125
 
    jack_log("JackMachClientChannel::Stop");
126
 
    fThread.Kill();
127
 
}
128
 
 
129
 
void JackMachClientChannel::ClientCheck(const char* name, char* name_res, int protocol, int options, int* status, int* result)
130
 
{
131
 
    kern_return_t res = rpc_jack_client_check(fServerPort.GetPort(), (char*)name, name_res, protocol, options, status, result);
132
 
    if (res != KERN_SUCCESS) {
133
 
        *result = -1;
134
 
        jack_error("JackMachClientChannel::ClientCheck err = %s", mach_error_string(res));
135
 
    }
136
 
}
137
 
 
138
 
void JackMachClientChannel::ClientOpen(const char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result)
139
 
{
140
 
    kern_return_t res = rpc_jack_client_open(fServerPort.GetPort(), (char*)name, pid, &fPrivatePort, shared_engine, shared_client, shared_graph, result);
141
 
    if (res != KERN_SUCCESS) {
142
 
        *result = -1;
143
 
        jack_error("JackMachClientChannel::ClientOpen err = %s", mach_error_string(res));
144
 
    }
145
 
}
146
 
 
147
 
void JackMachClientChannel::ClientClose(int refnum, int* result)
148
 
{
149
 
    kern_return_t res = rpc_jack_client_close(fPrivatePort, refnum, result);
150
 
    if (res != KERN_SUCCESS) {
151
 
        *result = -1;
152
 
        jack_error("JackMachClientChannel::ClientClose err = %s", mach_error_string(res));
153
 
    }
154
 
}
155
 
 
156
 
void JackMachClientChannel::ClientActivate(int refnum, int is_real_time, int* result)
157
 
{
158
 
    kern_return_t res = rpc_jack_client_activate(fPrivatePort, refnum, is_real_time, result);
159
 
    if (res != KERN_SUCCESS) {
160
 
        *result = -1;
161
 
        jack_error("JackMachClientChannel::ClientActivate err = %s", mach_error_string(res));
162
 
    }
163
 
}
164
 
 
165
 
void JackMachClientChannel::ClientDeactivate(int refnum, int* result)
166
 
{
167
 
    kern_return_t res = rpc_jack_client_deactivate(fPrivatePort, refnum, result);
168
 
    if (res != KERN_SUCCESS) {
169
 
        *result = -1;
170
 
        jack_error("JackMachClientChannel::ClientDeactivate err = %s", mach_error_string(res));
171
 
    }
172
 
}
173
 
 
174
 
void JackMachClientChannel::PortRegister(int refnum, const char* name, const char* type, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result)
175
 
{
176
 
    kern_return_t res = rpc_jack_port_register(fPrivatePort, refnum, (char*)name, (char*)type, flags, buffer_size, port_index, result);
177
 
    if (res != KERN_SUCCESS) {
178
 
        *result = -1;
179
 
        jack_error("JackMachClientChannel::PortRegister err = %s", mach_error_string(res));
180
 
    }
181
 
}
182
 
 
183
 
void JackMachClientChannel::PortUnRegister(int refnum, jack_port_id_t port_index, int* result)
184
 
{
185
 
    kern_return_t res = rpc_jack_port_unregister(fPrivatePort, refnum, port_index, result);
186
 
    if (res != KERN_SUCCESS) {
187
 
        *result = -1;
188
 
        jack_error("JackMachClientChannel::PortUnRegister err = %s", mach_error_string(res));
189
 
    }
190
 
}
191
 
 
192
 
void JackMachClientChannel::PortConnect(int refnum, const char* src, const char* dst, int* result)
193
 
{
194
 
    kern_return_t res = rpc_jack_port_connect_name(fPrivatePort, refnum, (char*)src, (char*)dst, result);
195
 
    if (res != KERN_SUCCESS) {
196
 
        jack_error("JackMachClientChannel::PortConnect err = %s", mach_error_string(res));
197
 
    }
198
 
}
199
 
 
200
 
void JackMachClientChannel::PortDisconnect(int refnum, const char* src, const char* dst, int* result)
201
 
{
202
 
    kern_return_t res = rpc_jack_port_disconnect_name(fPrivatePort, refnum, (char*)src, (char*)dst, result);
203
 
    if (res != KERN_SUCCESS) {
204
 
        *result = -1;
205
 
        jack_error("JackMachClientChannel::PortDisconnect err = %s", mach_error_string(res));
206
 
    }
207
 
}
208
 
 
209
 
void JackMachClientChannel::PortConnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result)
210
 
{
211
 
    kern_return_t res = rpc_jack_port_connect(fPrivatePort, refnum, src, dst, result);
212
 
    if (res != KERN_SUCCESS) {
213
 
        *result = -1;
214
 
        jack_error("JackMachClientChannel::PortConnect err = %s", mach_error_string(res));
215
 
    }
216
 
}
217
 
 
218
 
void JackMachClientChannel::PortDisconnect(int refnum, jack_port_id_t src, jack_port_id_t dst, int* result)
219
 
{
220
 
    kern_return_t res = rpc_jack_port_disconnect(fPrivatePort, refnum, src, dst, result);
221
 
    if (res != KERN_SUCCESS) {
222
 
        *result = -1;
223
 
        jack_error("JackMachClientChannel::PortDisconnect err = %s", mach_error_string(res));
224
 
    }
225
 
}
226
 
 
227
 
void JackMachClientChannel::PortRename(int refnum, jack_port_id_t port, const char* name, int* result)
228
 
{
229
 
    kern_return_t res = rpc_jack_port_rename(fPrivatePort, refnum, port, (char*)name, result);
230
 
    if (res != KERN_SUCCESS) {
231
 
        *result = -1;
232
 
        jack_error("JackMachClientChannel::PortRename err = %s", mach_error_string(res));
233
 
    }
234
 
}
235
 
 
236
 
void JackMachClientChannel::SetBufferSize(jack_nframes_t buffer_size, int* result)
237
 
{
238
 
    kern_return_t res = rpc_jack_set_buffer_size(fPrivatePort, buffer_size, result);
239
 
    if (res != KERN_SUCCESS) {
240
 
        *result = -1;
241
 
        jack_error("JackMachClientChannel::SetBufferSize err = %s", mach_error_string(res));
242
 
    }
243
 
}
244
 
 
245
 
void JackMachClientChannel::SetFreewheel(int onoff, int* result)
246
 
{
247
 
    kern_return_t res = rpc_jack_set_freewheel(fPrivatePort, onoff, result);
248
 
    if (res != KERN_SUCCESS) {
249
 
        *result = -1;
250
 
        jack_error("JackMachClientChannel::SetFreewheel err = %s", mach_error_string(res));
251
 
    }
252
 
}
253
 
 
254
 
void JackMachClientChannel::ReleaseTimebase(int refnum, int* result)
255
 
{
256
 
    kern_return_t res = rpc_jack_release_timebase(fPrivatePort, refnum, result);
257
 
    if (res != KERN_SUCCESS) {
258
 
        *result = -1;
259
 
        jack_error("JackMachClientChannel::ReleaseTimebase err = %s", mach_error_string(res));
260
 
    }
261
 
}
262
 
 
263
 
void JackMachClientChannel::SetTimebaseCallback(int refnum, int conditional, int* result)
264
 
{
265
 
    kern_return_t res = rpc_jack_set_timebase_callback(fPrivatePort, refnum, conditional, result);
266
 
    if (res != KERN_SUCCESS) {
267
 
        *result = -1;
268
 
        jack_error("JackMachClientChannel::SetTimebaseCallback err = %s", mach_error_string(res));
269
 
    }
270
 
}
271
 
 
272
 
void JackMachClientChannel::GetInternalClientName(int refnum, int int_ref, char* name_res, int* result)
273
 
{
274
 
    kern_return_t res = rpc_jack_get_internal_clientname(fPrivatePort, refnum, int_ref, name_res, result);
275
 
    if (res != KERN_SUCCESS) {
276
 
        *result = -1;
277
 
        jack_error("JackMachClientChannel::GetInternalClientName err = %s", mach_error_string(res));
278
 
    }
279
 
}
280
 
 
281
 
void JackMachClientChannel::InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result)
282
 
{
283
 
    kern_return_t res = rpc_jack_internal_clienthandle(fPrivatePort, refnum, (char*)client_name, status, int_ref, result);
284
 
    if (res != KERN_SUCCESS) {
285
 
        *result = -1;
286
 
        jack_error("JackMachClientChannel::InternalClientHandle err = %s", mach_error_string(res));
287
 
    }
288
 
}
289
 
 
290
 
void JackMachClientChannel::InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int* result)
291
 
{
292
 
    const char* int_client_name = (client_name) ? client_name : "";
293
 
    const char* int_so_name = (so_name) ? so_name : "";
294
 
    const char* int_objet_data = (objet_data) ? objet_data : "";
295
 
    
296
 
    kern_return_t res = rpc_jack_internal_clientload(fPrivatePort, refnum, (char*)int_client_name, (char*)int_so_name, (char*)int_objet_data, options, status, int_ref, result);
297
 
    if (res != KERN_SUCCESS) {
298
 
        *result = -1;
299
 
        jack_error("JackMachClientChannel::InternalClientLoad err = %s", mach_error_string(res));
300
 
    }
301
 
}
302
 
 
303
 
void JackMachClientChannel::InternalClientUnload(int refnum, int int_ref, int* status, int* result)
304
 
{
305
 
    kern_return_t res = rpc_jack_internal_clientunload(fPrivatePort, refnum, int_ref, status, result);
306
 
    if (res != KERN_SUCCESS) {
307
 
        *result = -1;
308
 
        jack_error("JackMachClientChannel::InternalClientUnload err = %s", mach_error_string(res));
309
 
    }
310
 
}
311
 
 
312
 
bool JackMachClientChannel::Init()
313
 
{
314
 
    jack_log("JackMachClientChannel::Init");
315
 
    JackClient* client = gClientTable[fClientPort.GetPort()];
316
 
    return client->Init();
317
 
}
318
 
 
319
 
bool JackMachClientChannel::Execute()
320
 
{
321
 
    kern_return_t res;
322
 
    if ((res = mach_msg_server(JackRPCClient_server, 1024, fClientPort.GetPort(), 0)) != KERN_SUCCESS) {
323
 
        jack_error("JackMachClientChannel::Execute err = %s", mach_error_string(res));
324
 
        JackClient* client = gClientTable[fClientPort.GetPort()];
325
 
        client->ShutDown();
326
 
        return false;
327
 
    } else {
328
 
        return true;
329
 
    }
330
 
}
331
 
 
332
 
} // end of namespace
333
 
 
334