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 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
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 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
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 }
00295