JackMachPort.cpp

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 General Public License as published by
00006   the Free Software Foundation; either version 2 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 General Public License for more details.
00013 
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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     JackLog("AllocatePort: queue limit %ld\n", 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     JackLog("JackMachPort::ConnectPort %s\n", 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     JackLog("JackMacRPC::DisconnectPort\n");
00102     kern_return_t res;
00103     mach_port_t task = mach_task_self();
00104 
00105     if ((res = mach_port_deallocate(task, fBootPort)) != KERN_SUCCESS) {
00106         jack_error("JackMacRPC::DisconnectPort mach_port_deallocate fBootPort err = %s", mach_error_string(res));
00107     }
00108 
00109     if ((res = mach_port_deallocate(task, fServerPort)) != KERN_SUCCESS) {
00110         jack_error("JackMacRPC::DisconnectPort mach_port_deallocate fServerPort err = %s", mach_error_string(res));
00111     }
00112 
00113     return true;
00114 }
00115 
00116 bool JackMachPort::DestroyPort()
00117 {
00118     JackLog("JackMacRPC::DisconnectPort\n");
00119     kern_return_t res;
00120     mach_port_t task = mach_task_self();
00121 
00122     if ((res = mach_port_deallocate(task, fBootPort)) != KERN_SUCCESS) {
00123         jack_error("JackMacRPC::DisconnectPort mach_port_deallocate fBootPort err = %s", mach_error_string(res));
00124     }
00125 
00126     if ((res = mach_port_destroy(task, fServerPort)) != KERN_SUCCESS) {
00127         jack_error("JackMacRPC::DisconnectPort mach_port_destroy fServerPort err = %s", mach_error_string(res));
00128     }
00129 
00130     return true;
00131 }
00132 
00133 mach_port_t JackMachPort::GetPort()
00134 {
00135     return fServerPort;
00136 }
00137 
00138 bool JackMachPortSet::AllocatePort(const char* name, int queue)
00139 {
00140     kern_return_t res;
00141     mach_port_t task = mach_task_self();
00142 
00143     JackLog("JackMachPortSet::AllocatePort\n");
00144 
00145     if ((res = task_get_bootstrap_port(task, &fBootPort)) != KERN_SUCCESS) {
00146         jack_error("AllocatePort: Can't find bootstrap mach port err = %s", mach_error_string(res));
00147         return false;
00148     }
00149 
00150     if ((res = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &fServerPort)) != KERN_SUCCESS) {
00151         jack_error("AllocatePort: can't allocate mach port err = %s", mach_error_string(res));
00152         return false;
00153     }
00154 
00155     if ((res = mach_port_insert_right(task, fServerPort, fServerPort, MACH_MSG_TYPE_MAKE_SEND)) != KERN_SUCCESS) {
00156         jack_error("AllocatePort: error inserting mach rights err = %s", mach_error_string(res));
00157         return false;
00158     }
00159 
00160     if ((res = mach_port_allocate(task, MACH_PORT_RIGHT_PORT_SET, &fPortSet)) != KERN_SUCCESS) {
00161         jack_error("AllocatePort: can't allocate mach port err = %s", mach_error_string(res));
00162         return false;
00163     }
00164 
00165     if ((res = mach_port_move_member(task, fServerPort, fPortSet)) != KERN_SUCCESS) {
00166         jack_error("AllocatePort: error in mach_port_move_member err = %s", mach_error_string(res));
00167         return false;
00168     }
00169 
00170     if ((res = bootstrap_register(fBootPort, (char*)name, fServerPort)) != KERN_SUCCESS) {
00171         jack_error("Allocate: can't check in mach port name = %s err = %s", name, mach_error_string(res));
00172         return false;
00173     }
00174 
00175     mach_port_limits_t qlimits;
00176     mach_msg_type_number_t info_cnt = MACH_PORT_LIMITS_INFO_COUNT;
00177     if ((res = mach_port_get_attributes(task, fServerPort, MACH_PORT_LIMITS_INFO, (mach_port_info_t) & qlimits, &info_cnt)) != KERN_SUCCESS) {
00178         jack_error("Allocate: mach_port_get_attributes error name = %s err = %s", name, mach_error_string(res));
00179     }
00180 
00181     JackLog("AllocatePort: queue limit = %ld\n", qlimits.mpl_qlimit);
00182 
00183     if (queue > 0 ) {
00184         qlimits.mpl_qlimit = queue;
00185 
00186         if ((res = mach_port_set_attributes(task, fServerPort, MACH_PORT_LIMITS_INFO, (mach_port_info_t) & qlimits, MACH_PORT_LIMITS_INFO_COUNT)) != KERN_SUCCESS) {
00187             jack_error("Allocate: mach_port_set_attributes error name = %s err = %s", name, mach_error_string(res));
00188         }
00189     }
00190 
00191     return true;
00192 }
00193 
00194 // Server side : port is published to be accessible from other processes (clients)
00195 
00196 bool JackMachPortSet::AllocatePort(const char* name)
00197 {
00198     return AllocatePort(name, -1);
00199 }
00200 
00201 bool JackMachPortSet::DisconnectPort()
00202 {
00203     kern_return_t res;
00204     mach_port_t task = mach_task_self();
00205 
00206     JackLog("JackMachPortSet::DisconnectPort\n");
00207 
00208     if ((res = mach_port_deallocate(task, fBootPort)) != KERN_SUCCESS) {
00209         jack_error("JackMachPortSet::DisconnectPort mach_port_deallocate fBootPort err = %s", mach_error_string(res));
00210     }
00211 
00212     if ((res = mach_port_deallocate(task, fServerPort)) != KERN_SUCCESS) {
00213         jack_error("JackMachPortSet::DisconnectPort mach_port_deallocate fServerPort err = %s", mach_error_string(res));
00214     }
00215 
00216     return true;
00217 }
00218 
00219 bool JackMachPortSet::DestroyPort()
00220 {
00221     kern_return_t res;
00222     mach_port_t task = mach_task_self();
00223 
00224     JackLog("JackMachPortSet::DisconnectPort\n");
00225 
00226     if ((res = mach_port_deallocate(task, fBootPort)) != KERN_SUCCESS) {
00227         jack_error("JackMachPortSet::DisconnectPort mach_port_deallocate err = %s", mach_error_string(res));
00228     }
00229 
00230     if ((res = mach_port_destroy(task, fServerPort)) != KERN_SUCCESS) {
00231         jack_error("JackMachPortSet::DisconnectPort mach_port_destroy fServerPort err = %s", mach_error_string(res));
00232     }
00233 
00234     return true;
00235 }
00236 
00237 mach_port_t JackMachPortSet::GetPortSet()
00238 {
00239     return fPortSet;
00240 }
00241 
00242 mach_port_t JackMachPortSet::AddPort()
00243 {
00244     kern_return_t res;
00245     mach_port_t task = mach_task_self();
00246     mach_port_t old_port, result = 0;
00247 
00248     JackLog("JackMachPortSet::AddPort\n");
00249 
00250     if ((res = mach_port_allocate(task, MACH_PORT_RIGHT_RECEIVE, &result)) != KERN_SUCCESS) {
00251         jack_error("AddPort: can't allocate mach port err = %s", mach_error_string(res));
00252         goto error;
00253     }
00254 
00255     if ((res = mach_port_request_notification(task, result, MACH_NOTIFY_NO_SENDERS,
00256                1, result, MACH_MSG_TYPE_MAKE_SEND_ONCE, &old_port)) != KERN_SUCCESS) {
00257         jack_error("AddPort: error in mach_port_request_notification err = %s", mach_error_string(res));
00258         goto error;
00259     }
00260 
00261     if ((res = mach_port_move_member(task, result, fPortSet)) != KERN_SUCCESS) {
00262         jack_error("AddPort: error in mach_port_move_member err = %s", mach_error_string(res));
00263         goto error;
00264     }
00265 
00266     return result;
00267 
00268 error:
00269     if (result) {
00270         if ((res = mach_port_destroy(task, result)) != KERN_SUCCESS) {
00271             jack_error("JackMacRPC::DisconnectPort mach_port_destroy err = %s", mach_error_string(res));
00272         }
00273     }
00274     return 0;
00275 }
00276 
00277 
00278 } // end of namespace
00279 

Generated on Thu Feb 14 11:16:02 2008 for Jackdmp by  doxygen 1.5.1