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

« back to all changes in this revision

Viewing changes to macosx/JackMachPort.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 "JackMachPort.h"
21
 
#include "JackError.h"
22
 
 
23
 
namespace Jack
24
 
{
25
 
 
26
 
// Server side : port is published to be accessible from other processes (clients)
27
 
 
28
 
bool JackMachPort::AllocatePort(const char* name, int queue)
29
 
{
30
 
    mach_port_t task = mach_task_self();
31
 
    kern_return_t res;
32
 
 
33
 
    if ((res = task_get_bootstrap_port(task, &fBootPort)) != KERN_SUCCESS) {
34
 
        jack_error("AllocatePort: Can't find bootstrap mach port err = %s", mach_error_string(res));
35
 
        return false;
36
 
    }
37
 
 
38
 
    if ((res = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &fServerPort)) != KERN_SUCCESS) {
39
 
        jack_error("AllocatePort: can't allocate mach port err = %s", mach_error_string(res));
40
 
        return false;
41
 
    }
42
 
 
43
 
    if ((res = mach_port_insert_right(task, fServerPort, fServerPort, MACH_MSG_TYPE_MAKE_SEND)) != KERN_SUCCESS) {
44
 
        jack_error("AllocatePort: error inserting mach rights err = %s", mach_error_string(res));
45
 
        return false;
46
 
    }
47
 
 
48
 
    if ((res = bootstrap_register(fBootPort, (char*)name, fServerPort)) != KERN_SUCCESS) {
49
 
        jack_error("Allocate: can't check in mach port name = %s err = %s", name, mach_error_string(res));
50
 
        return false;
51
 
    }
52
 
 
53
 
    mach_port_limits_t qlimits;
54
 
    mach_msg_type_number_t info_cnt = MACH_PORT_LIMITS_INFO_COUNT;
55
 
    if ((res = mach_port_get_attributes(task, fServerPort, MACH_PORT_LIMITS_INFO, (mach_port_info_t) & qlimits, &info_cnt)) != KERN_SUCCESS) {
56
 
        jack_error("Allocate: mach_port_get_attributes error err = %s", name, mach_error_string(res));
57
 
    }
58
 
 
59
 
    jack_log("AllocatePort: queue limit %ld", qlimits.mpl_qlimit);
60
 
 
61
 
    if (queue > 0) {
62
 
        qlimits.mpl_qlimit = queue;
63
 
        if ((res = mach_port_set_attributes(task, fServerPort, MACH_PORT_LIMITS_INFO, (mach_port_info_t) & qlimits, MACH_PORT_LIMITS_INFO_COUNT)) != KERN_SUCCESS) {
64
 
            jack_error("Allocate: mach_port_set_attributes error name = %s err = %s", name, mach_error_string(res));
65
 
        }
66
 
    }
67
 
 
68
 
    return true;
69
 
}
70
 
 
71
 
// Server side : port is published to be accessible from other processes (clients)
72
 
 
73
 
bool JackMachPort::AllocatePort(const char* name)
74
 
{
75
 
    return AllocatePort(name, -1);
76
 
}
77
 
 
78
 
// Client side : get the published port from server
79
 
 
80
 
bool JackMachPort::ConnectPort(const char* name)
81
 
{
82
 
    kern_return_t res;
83
 
 
84
 
    jack_log("JackMachPort::ConnectPort %s", name);
85
 
 
86
 
    if ((res = task_get_bootstrap_port(mach_task_self(), &fBootPort)) != KERN_SUCCESS) {
87
 
        jack_error("ConnectPort: can't find bootstrap port err = %s", mach_error_string(res));
88
 
        return false;
89
 
    }
90
 
 
91
 
    if ((res = bootstrap_look_up(fBootPort, (char*)name, &fServerPort)) != KERN_SUCCESS) {
92
 
        jack_error("ConnectPort: can't find mach server port name = %s err = %s", name, mach_error_string(res));
93
 
        return false;
94
 
    }
95
 
 
96
 
    return true;
97
 
}
98
 
 
99
 
bool JackMachPort::DisconnectPort()
100
 
{
101
 
    jack_log("JackMacRPC::DisconnectPort");
102
 
    kern_return_t res;
103
 
    mach_port_t task = mach_task_self();
104
 
 
105
 
    if (fBootPort != 0) {
106
 
        if ((res = mach_port_deallocate(task, fBootPort)) != KERN_SUCCESS) {
107
 
            jack_error("JackMacRPC::DisconnectPort mach_port_deallocate fBootPort err = %s", mach_error_string(res));
108
 
        }
109
 
    }
110
 
 
111
 
    if (fServerPort != 0) {
112
 
        if ((res = mach_port_deallocate(task, fServerPort)) != KERN_SUCCESS) {
113
 
            jack_error("JackMacRPC::DisconnectPort mach_port_deallocate fServerPort err = %s", mach_error_string(res));
114
 
        }
115
 
    }
116
 
    
117
 
    return true;
118
 
}
119
 
 
120
 
bool JackMachPort::DestroyPort()
121
 
{
122
 
    jack_log("JackMacRPC::DisconnectPort");
123
 
    kern_return_t res;
124
 
    mach_port_t task = mach_task_self();
125
 
 
126
 
    if (fBootPort != 0) {
127
 
        if ((res = mach_port_deallocate(task, fBootPort)) != KERN_SUCCESS) {
128
 
            jack_error("JackMacRPC::DisconnectPort mach_port_deallocate fBootPort err = %s", mach_error_string(res));
129
 
        }
130
 
    }
131
 
 
132
 
    if (fServerPort != 0) {
133
 
        if ((res = mach_port_destroy(task, fServerPort)) != KERN_SUCCESS) {
134
 
            jack_error("JackMacRPC::DisconnectPort mach_port_destroy fServerPort err = %s", mach_error_string(res));
135
 
        }
136
 
    }
137
 
 
138
 
    return true;
139
 
}
140
 
 
141
 
mach_port_t JackMachPort::GetPort()
142
 
{
143
 
    return fServerPort;
144
 
}
145
 
 
146
 
bool JackMachPortSet::AllocatePort(const char* name, int queue)
147
 
{
148
 
    kern_return_t res;
149
 
    mach_port_t task = mach_task_self();
150
 
 
151
 
    jack_log("JackMachPortSet::AllocatePort");
152
 
 
153
 
    if ((res = task_get_bootstrap_port(task, &fBootPort)) != KERN_SUCCESS) {
154
 
        jack_error("AllocatePort: Can't find bootstrap mach port err = %s", mach_error_string(res));
155
 
        return false;
156
 
    }
157
 
 
158
 
    if ((res = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &fServerPort)) != KERN_SUCCESS) {
159
 
        jack_error("AllocatePort: can't allocate mach port err = %s", mach_error_string(res));
160
 
        return false;
161
 
    }
162
 
 
163
 
    if ((res = mach_port_insert_right(task, fServerPort, fServerPort, MACH_MSG_TYPE_MAKE_SEND)) != KERN_SUCCESS) {
164
 
        jack_error("AllocatePort: error inserting mach rights err = %s", mach_error_string(res));
165
 
        return false;
166
 
    }
167
 
 
168
 
    if ((res = mach_port_allocate(task, MACH_PORT_RIGHT_PORT_SET, &fPortSet)) != KERN_SUCCESS) {
169
 
        jack_error("AllocatePort: can't allocate mach port err = %s", mach_error_string(res));
170
 
        return false;
171
 
    }
172
 
 
173
 
    if ((res = mach_port_move_member(task, fServerPort, fPortSet)) != KERN_SUCCESS) {
174
 
        jack_error("AllocatePort: error in mach_port_move_member err = %s", mach_error_string(res));
175
 
        return false;
176
 
    }
177
 
 
178
 
    if ((res = bootstrap_register(fBootPort, (char*)name, fServerPort)) != KERN_SUCCESS) {
179
 
        jack_error("Allocate: can't check in mach port name = %s err = %s", name, mach_error_string(res));
180
 
        return false;
181
 
    }
182
 
 
183
 
    mach_port_limits_t qlimits;
184
 
    mach_msg_type_number_t info_cnt = MACH_PORT_LIMITS_INFO_COUNT;
185
 
    if ((res = mach_port_get_attributes(task, fServerPort, MACH_PORT_LIMITS_INFO, (mach_port_info_t) & qlimits, &info_cnt)) != KERN_SUCCESS) {
186
 
        jack_error("Allocate: mach_port_get_attributes error name = %s err = %s", name, mach_error_string(res));
187
 
    }
188
 
 
189
 
    jack_log("AllocatePort: queue limit = %ld", qlimits.mpl_qlimit);
190
 
 
191
 
    if (queue > 0) {
192
 
        qlimits.mpl_qlimit = queue;
193
 
 
194
 
        if ((res = mach_port_set_attributes(task, fServerPort, MACH_PORT_LIMITS_INFO, (mach_port_info_t) & qlimits, MACH_PORT_LIMITS_INFO_COUNT)) != KERN_SUCCESS) {
195
 
            jack_error("Allocate: mach_port_set_attributes error name = %s err = %s", name, mach_error_string(res));
196
 
        }
197
 
    }
198
 
 
199
 
    return true;
200
 
}
201
 
 
202
 
// Server side : port is published to be accessible from other processes (clients)
203
 
 
204
 
bool JackMachPortSet::AllocatePort(const char* name)
205
 
{
206
 
    return AllocatePort(name, -1);
207
 
}
208
 
 
209
 
bool JackMachPortSet::DisconnectPort()
210
 
{
211
 
    kern_return_t res;
212
 
    mach_port_t task = mach_task_self();
213
 
 
214
 
    jack_log("JackMachPortSet::DisconnectPort");
215
 
 
216
 
    if (fBootPort != 0) {
217
 
        if ((res = mach_port_deallocate(task, fBootPort)) != KERN_SUCCESS) {
218
 
            jack_error("JackMachPortSet::DisconnectPort mach_port_deallocate fBootPort err = %s", mach_error_string(res));
219
 
        }
220
 
    }
221
 
 
222
 
    if (fServerPort != 0) {
223
 
        if ((res = mach_port_deallocate(task, fServerPort)) != KERN_SUCCESS) {
224
 
            jack_error("JackMachPortSet::DisconnectPort mach_port_deallocate fServerPort err = %s", mach_error_string(res));
225
 
        }
226
 
    }
227
 
 
228
 
    return true;
229
 
}
230
 
 
231
 
bool JackMachPortSet::DestroyPort()
232
 
{
233
 
    kern_return_t res;
234
 
    mach_port_t task = mach_task_self();
235
 
 
236
 
    jack_log("JackMachPortSet::DisconnectPort");
237
 
 
238
 
    if (fBootPort != 0) {
239
 
        if ((res = mach_port_deallocate(task, fBootPort)) != KERN_SUCCESS) {
240
 
            jack_error("JackMachPortSet::DisconnectPort mach_port_deallocate err = %s", mach_error_string(res));
241
 
        }
242
 
    }
243
 
 
244
 
    if (fServerPort != 0) {
245
 
        if ((res = mach_port_destroy(task, fServerPort)) != KERN_SUCCESS) {
246
 
            jack_error("JackMachPortSet::DisconnectPort mach_port_destroy fServerPort err = %s", mach_error_string(res));
247
 
        }
248
 
    }
249
 
 
250
 
    return true;
251
 
}
252
 
 
253
 
mach_port_t JackMachPortSet::GetPortSet()
254
 
{
255
 
    return fPortSet;
256
 
}
257
 
 
258
 
mach_port_t JackMachPortSet::AddPort()
259
 
{
260
 
    kern_return_t res;
261
 
    mach_port_t task = mach_task_self();
262
 
    mach_port_t old_port, result = 0;
263
 
 
264
 
    jack_log("JackMachPortSet::AddPort");
265
 
 
266
 
    if ((res = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &result)) != KERN_SUCCESS) {
267
 
        jack_error("AddPort: can't allocate mach port err = %s", mach_error_string(res));
268
 
        goto error;
269
 
    }
270
 
 
271
 
    if ((res = mach_port_request_notification(task, result, MACH_NOTIFY_NO_SENDERS,
272
 
               1, result, MACH_MSG_TYPE_MAKE_SEND_ONCE, &old_port)) != KERN_SUCCESS) {
273
 
        jack_error("AddPort: error in mach_port_request_notification err = %s", mach_error_string(res));
274
 
        goto error;
275
 
    }
276
 
 
277
 
    if ((res = mach_port_move_member(task, result, fPortSet)) != KERN_SUCCESS) {
278
 
        jack_error("AddPort: error in mach_port_move_member err = %s", mach_error_string(res));
279
 
        goto error;
280
 
    }
281
 
 
282
 
    return result;
283
 
 
284
 
error:
285
 
    if (result) {
286
 
        if ((res = mach_port_destroy(task, result)) != KERN_SUCCESS) {
287
 
            jack_error("JackMacRPC::DisconnectPort mach_port_destroy err = %s", mach_error_string(res));
288
 
        }
289
 
    }
290
 
    return 0;
291
 
}
292
 
 
293
 
 
294
 
} // end of namespace
295