Jack2 1.9.6
|
00001 /* 00002 Copyright (C) 2004-2008 Grame 00003 00004 This program is free software; you can redistribute it and/or modify 00005 it under the terms of the GNU Lesser General Public License as published by 00006 the Free Software Foundation; either version 2.1 of the License, or 00007 (at your option) any later version. 00008 00009 This program is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 GNU Lesser General Public License for more details. 00013 00014 You should have received a copy of the GNU Lesser General Public License 00015 along with this program; if not, write to the Free Software 00016 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00017 00018 */ 00019 00020 #include "JackMachPort.h" 00021 #include "JackError.h" 00022 00023 namespace Jack 00024 { 00025 00026 // Server side : port is published to be accessible from other processes (clients) 00027 00028 bool JackMachPort::AllocatePort(const char* name, int queue) 00029 { 00030 mach_port_t task = mach_task_self(); 00031 kern_return_t res; 00032 00033 if ((res = task_get_bootstrap_port(task, &fBootPort)) != KERN_SUCCESS) { 00034 jack_error("AllocatePort: Can't find bootstrap mach port err = %s", mach_error_string(res)); 00035 return false; 00036 } 00037 00038 if ((res = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &fServerPort)) != KERN_SUCCESS) { 00039 jack_error("AllocatePort: can't allocate mach port err = %s", mach_error_string(res)); 00040 return false; 00041 } 00042 00043 if ((res = mach_port_insert_right(task, fServerPort, fServerPort, MACH_MSG_TYPE_MAKE_SEND)) != KERN_SUCCESS) { 00044 jack_error("AllocatePort: error inserting mach rights err = %s", mach_error_string(res)); 00045 return false; 00046 } 00047 00048 if ((res = bootstrap_register(fBootPort, (char*)name, fServerPort)) != KERN_SUCCESS) { 00049 jack_error("Allocate: can't check in mach port name = %s err = %s", name, mach_error_string(res)); 00050 return false; 00051 } 00052 00053 mach_port_limits_t qlimits; 00054 mach_msg_type_number_t info_cnt = MACH_PORT_LIMITS_INFO_COUNT; 00055 if ((res = mach_port_get_attributes(task, fServerPort, MACH_PORT_LIMITS_INFO, (mach_port_info_t) & qlimits, &info_cnt)) != KERN_SUCCESS) { 00056 jack_error("Allocate: mach_port_get_attributes error err = %s", name, mach_error_string(res)); 00057 } 00058 00059 jack_log("AllocatePort: queue limit %ld", qlimits.mpl_qlimit); 00060 00061 if (queue > 0) { 00062 qlimits.mpl_qlimit = queue; 00063 if ((res = mach_port_set_attributes(task, fServerPort, MACH_PORT_LIMITS_INFO, (mach_port_info_t) & qlimits, MACH_PORT_LIMITS_INFO_COUNT)) != KERN_SUCCESS) { 00064 jack_error("Allocate: mach_port_set_attributes error name = %s err = %s", name, mach_error_string(res)); 00065 } 00066 } 00067 00068 return true; 00069 } 00070 00071 // Server side : port is published to be accessible from other processes (clients) 00072 00073 bool JackMachPort::AllocatePort(const char* name) 00074 { 00075 return AllocatePort(name, -1); 00076 } 00077 00078 // Client side : get the published port from server 00079 00080 bool JackMachPort::ConnectPort(const char* name) 00081 { 00082 kern_return_t res; 00083 00084 jack_log("JackMachPort::ConnectPort %s", name); 00085 00086 if ((res = task_get_bootstrap_port(mach_task_self(), &fBootPort)) != KERN_SUCCESS) { 00087 jack_error("ConnectPort: can't find bootstrap port err = %s", mach_error_string(res)); 00088 return false; 00089 } 00090 00091 if ((res = bootstrap_look_up(fBootPort, (char*)name, &fServerPort)) != KERN_SUCCESS) { 00092 jack_error("ConnectPort: can't find mach server port name = %s err = %s", name, mach_error_string(res)); 00093 return false; 00094 } 00095 00096 return true; 00097 } 00098 00099 bool JackMachPort::DisconnectPort() 00100 { 00101 jack_log("JackMacRPC::DisconnectPort"); 00102 kern_return_t res; 00103 mach_port_t task = mach_task_self(); 00104 00105 if (fBootPort != 0) { 00106 if ((res = mach_port_deallocate(task, fBootPort)) != KERN_SUCCESS) { 00107 jack_error("JackMacRPC::DisconnectPort mach_port_deallocate fBootPort err = %s", mach_error_string(res)); 00108 } 00109 } 00110 00111 if (fServerPort != 0) { 00112 if ((res = mach_port_deallocate(task, fServerPort)) != KERN_SUCCESS) { 00113 jack_error("JackMacRPC::DisconnectPort mach_port_deallocate fServerPort err = %s", mach_error_string(res)); 00114 } 00115 } 00116 00117 return true; 00118 } 00119 00120 bool JackMachPort::DestroyPort() 00121 { 00122 jack_log("JackMacRPC::DisconnectPort"); 00123 kern_return_t res; 00124 mach_port_t task = mach_task_self(); 00125 00126 if (fBootPort != 0) { 00127 if ((res = mach_port_deallocate(task, fBootPort)) != KERN_SUCCESS) { 00128 jack_error("JackMacRPC::DisconnectPort mach_port_deallocate fBootPort err = %s", mach_error_string(res)); 00129 } 00130 } 00131 00132 if (fServerPort != 0) { 00133 if ((res = mach_port_destroy(task, fServerPort)) != KERN_SUCCESS) { 00134 jack_error("JackMacRPC::DisconnectPort mach_port_destroy fServerPort err = %s", mach_error_string(res)); 00135 } 00136 } 00137 00138 return true; 00139 } 00140 00141 mach_port_t JackMachPort::GetPort() 00142 { 00143 return fServerPort; 00144 } 00145 00146 bool JackMachPortSet::AllocatePort(const char* name, int queue) 00147 { 00148 kern_return_t res; 00149 mach_port_t task = mach_task_self(); 00150 00151 jack_log("JackMachPortSet::AllocatePort"); 00152 00153 if ((res = task_get_bootstrap_port(task, &fBootPort)) != KERN_SUCCESS) { 00154 jack_error("AllocatePort: Can't find bootstrap mach port err = %s", mach_error_string(res)); 00155 return false; 00156 } 00157 00158 if ((res = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &fServerPort)) != KERN_SUCCESS) { 00159 jack_error("AllocatePort: can't allocate mach port err = %s", mach_error_string(res)); 00160 return false; 00161 } 00162 00163 if ((res = mach_port_insert_right(task, fServerPort, fServerPort, MACH_MSG_TYPE_MAKE_SEND)) != KERN_SUCCESS) { 00164 jack_error("AllocatePort: error inserting mach rights err = %s", mach_error_string(res)); 00165 return false; 00166 } 00167 00168 if ((res = mach_port_allocate(task, MACH_PORT_RIGHT_PORT_SET, &fPortSet)) != KERN_SUCCESS) { 00169 jack_error("AllocatePort: can't allocate mach port err = %s", mach_error_string(res)); 00170 return false; 00171 } 00172 00173 if ((res = mach_port_move_member(task, fServerPort, fPortSet)) != KERN_SUCCESS) { 00174 jack_error("AllocatePort: error in mach_port_move_member err = %s", mach_error_string(res)); 00175 return false; 00176 } 00177 00178 if ((res = bootstrap_register(fBootPort, (char*)name, fServerPort)) != KERN_SUCCESS) { 00179 jack_error("Allocate: can't check in mach port name = %s err = %s", name, mach_error_string(res)); 00180 return false; 00181 } 00182 00183 mach_port_limits_t qlimits; 00184 mach_msg_type_number_t info_cnt = MACH_PORT_LIMITS_INFO_COUNT; 00185 if ((res = mach_port_get_attributes(task, fServerPort, MACH_PORT_LIMITS_INFO, (mach_port_info_t) & qlimits, &info_cnt)) != KERN_SUCCESS) { 00186 jack_error("Allocate: mach_port_get_attributes error name = %s err = %s", name, mach_error_string(res)); 00187 } 00188 00189 jack_log("AllocatePort: queue limit = %ld", qlimits.mpl_qlimit); 00190 00191 if (queue > 0) { 00192 qlimits.mpl_qlimit = queue; 00193 00194 if ((res = mach_port_set_attributes(task, fServerPort, MACH_PORT_LIMITS_INFO, (mach_port_info_t) & qlimits, MACH_PORT_LIMITS_INFO_COUNT)) != KERN_SUCCESS) { 00195 jack_error("Allocate: mach_port_set_attributes error name = %s err = %s", name, mach_error_string(res)); 00196 } 00197 } 00198 00199 return true; 00200 } 00201 00202 // Server side : port is published to be accessible from other processes (clients) 00203 00204 bool JackMachPortSet::AllocatePort(const char* name) 00205 { 00206 return AllocatePort(name, -1); 00207 } 00208 00209 bool JackMachPortSet::DisconnectPort() 00210 { 00211 kern_return_t res; 00212 mach_port_t task = mach_task_self(); 00213 00214 jack_log("JackMachPortSet::DisconnectPort"); 00215 00216 if (fBootPort != 0) { 00217 if ((res = mach_port_deallocate(task, fBootPort)) != KERN_SUCCESS) { 00218 jack_error("JackMachPortSet::DisconnectPort mach_port_deallocate fBootPort err = %s", mach_error_string(res)); 00219 } 00220 } 00221 00222 if (fServerPort != 0) { 00223 if ((res = mach_port_deallocate(task, fServerPort)) != KERN_SUCCESS) { 00224 jack_error("JackMachPortSet::DisconnectPort mach_port_deallocate fServerPort err = %s", mach_error_string(res)); 00225 } 00226 } 00227 00228 return true; 00229 } 00230 00231 bool JackMachPortSet::DestroyPort() 00232 { 00233 kern_return_t res; 00234 mach_port_t task = mach_task_self(); 00235 00236 jack_log("JackMachPortSet::DisconnectPort"); 00237 00238 if (fBootPort != 0) { 00239 if ((res = mach_port_deallocate(task, fBootPort)) != KERN_SUCCESS) { 00240 jack_error("JackMachPortSet::DisconnectPort mach_port_deallocate err = %s", mach_error_string(res)); 00241 } 00242 } 00243 00244 if (fServerPort != 0) { 00245 if ((res = mach_port_destroy(task, fServerPort)) != KERN_SUCCESS) { 00246 jack_error("JackMachPortSet::DisconnectPort mach_port_destroy fServerPort err = %s", mach_error_string(res)); 00247 } 00248 } 00249 00250 return true; 00251 } 00252 00253 mach_port_t JackMachPortSet::GetPortSet() 00254 { 00255 return fPortSet; 00256 } 00257 00258 mach_port_t JackMachPortSet::AddPort() 00259 { 00260 kern_return_t res; 00261 mach_port_t task = mach_task_self(); 00262 mach_port_t old_port, result = 0; 00263 00264 jack_log("JackMachPortSet::AddPort"); 00265 00266 if ((res = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &result)) != KERN_SUCCESS) { 00267 jack_error("AddPort: can't allocate mach port err = %s", mach_error_string(res)); 00268 goto error; 00269 } 00270 00271 if ((res = mach_port_request_notification(task, result, MACH_NOTIFY_NO_SENDERS, 00272 1, result, MACH_MSG_TYPE_MAKE_SEND_ONCE, &old_port)) != KERN_SUCCESS) { 00273 jack_error("AddPort: error in mach_port_request_notification err = %s", mach_error_string(res)); 00274 goto error; 00275 } 00276 00277 if ((res = mach_port_move_member(task, result, fPortSet)) != KERN_SUCCESS) { 00278 jack_error("AddPort: error in mach_port_move_member err = %s", mach_error_string(res)); 00279 goto error; 00280 } 00281 00282 return result; 00283 00284 error: 00285 if (result) { 00286 if ((res = mach_port_destroy(task, result)) != KERN_SUCCESS) { 00287 jack_error("JackMacRPC::DisconnectPort mach_port_destroy err = %s", mach_error_string(res)); 00288 } 00289 } 00290 return 0; 00291 } 00292 00293 00294 } // end of namespace 00295