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 "JackMachPort.h"
21 #include "JackError.h"
26 // Server side : port is published to be accessible from other processes (clients)
28 bool JackMachPort::AllocatePort(const char* name
, int queue
)
30 mach_port_t task
= mach_task_self();
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
));
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
));
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
));
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
));
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
));
59 jack_log("AllocatePort: queue limit %ld", qlimits
.mpl_qlimit
);
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
));
71 // Server side : port is published to be accessible from other processes (clients)
73 bool JackMachPort::AllocatePort(const char* name
)
75 return AllocatePort(name
, -1);
78 // Client side : get the published port from server
80 bool JackMachPort::ConnectPort(const char* name
)
84 jack_log("JackMachPort::ConnectPort %s", name
);
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
));
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
));
99 bool JackMachPort::DisconnectPort()
101 jack_log("JackMacRPC::DisconnectPort");
103 mach_port_t task
= mach_task_self();
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
));
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
));
120 bool JackMachPort::DestroyPort()
122 jack_log("JackMacRPC::DisconnectPort");
124 mach_port_t task
= mach_task_self();
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
));
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
));
141 mach_port_t
JackMachPort::GetPort()
146 bool JackMachPortSet::AllocatePort(const char* name
, int queue
)
149 mach_port_t task
= mach_task_self();
151 jack_log("JackMachPortSet::AllocatePort");
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
));
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
));
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
));
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
));
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
));
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
));
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
));
189 jack_log("AllocatePort: queue limit = %ld", qlimits
.mpl_qlimit
);
192 qlimits
.mpl_qlimit
= queue
;
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
));
202 // Server side : port is published to be accessible from other processes (clients)
204 bool JackMachPortSet::AllocatePort(const char* name
)
206 return AllocatePort(name
, -1);
209 bool JackMachPortSet::DisconnectPort()
212 mach_port_t task
= mach_task_self();
214 jack_log("JackMachPortSet::DisconnectPort");
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
));
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
));
231 bool JackMachPortSet::DestroyPort()
234 mach_port_t task
= mach_task_self();
236 jack_log("JackMachPortSet::DisconnectPort");
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
));
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
));
253 mach_port_t
JackMachPortSet::GetPortSet()
258 mach_port_t
JackMachPortSet::AddPort()
261 mach_port_t task
= mach_task_self();
262 mach_port_t old_port
, result
= 0;
264 jack_log("JackMachPortSet::AddPort");
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
));
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
));
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
));
286 if ((res
= mach_port_destroy(task
, result
)) != KERN_SUCCESS
) {
287 jack_error("JackMacRPC::DisconnectPort mach_port_destroy err = %s", mach_error_string(res
));
294 } // end of namespace