Memory allocation error checking in server for RPC.
[jack2.git] / macosx / JackMachPort.cpp
blobd0d236b7f653cec4af80a45c38c6662606c9c096
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 "JackMachPort.h"
21 #include "JackError.h"
23 namespace Jack
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();
31 kern_return_t res;
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;
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;
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;
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;
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);
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));
68 return true;
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)
82 kern_return_t res;
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));
88 return false;
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;
96 return true;
99 bool JackMachPort::DisconnectPort()
101 jack_log("JackMacRPC::DisconnectPort");
102 kern_return_t res;
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));
117 return true;
120 bool JackMachPort::DestroyPort()
122 jack_log("JackMacRPC::DisconnectPort");
123 kern_return_t res;
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));
138 return true;
141 mach_port_t JackMachPort::GetPort()
143 return fServerPort;
146 bool JackMachPortSet::AllocatePort(const char* name, int queue)
148 kern_return_t res;
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));
155 return false;
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;
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;
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;
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;
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;
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);
191 if (queue > 0) {
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));
199 return true;
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()
211 kern_return_t res;
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));
228 return true;
231 bool JackMachPortSet::DestroyPort()
233 kern_return_t res;
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));
250 return true;
253 mach_port_t JackMachPortSet::GetPortSet()
255 return fPortSet;
258 mach_port_t JackMachPortSet::AddPort()
260 kern_return_t res;
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));
268 goto error;
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;
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;
282 return result;
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));
290 return 0;
294 } // end of namespace