00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackMachPort.h"
00021 #include "JackError.h"
00022
00023 namespace Jack
00024 {
00025
00026
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
00072
00073 bool JackMachPort::AllocatePort(const char* name)
00074 {
00075 return AllocatePort(name, -1);
00076 }
00077
00078
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
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 }
00279