00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackMachSemaphore.h"
00021 #include "JackConstants.h"
00022 #include "JackTools.h"
00023 #include "JackError.h"
00024 #include <stdio.h>
00025
00026 namespace Jack
00027 {
00028
00029 mach_port_t JackMachSemaphore::fBootPort = 0;
00030
00031 void JackMachSemaphore::BuildName(const char* client_name, const char* server_name, char* res)
00032 {
00033 char ext_client_name[JACK_CLIENT_NAME_SIZE + 1];
00034 JackTools::RewriteName(client_name, ext_client_name);
00035 sprintf(res, "jack_mach_sem.%d_%s_%s", JackTools::GetUID(), server_name, ext_client_name);
00036 }
00037
00038 bool JackMachSemaphore::Signal()
00039 {
00040 if (!fSemaphore) {
00041 jack_error("JackMachSemaphore::Signal name = %s already desallocated!!", fName);
00042 return false;
00043 }
00044
00045 if (fFlush)
00046 return true;
00047
00048 kern_return_t res;
00049 if ((res = semaphore_signal(fSemaphore)) != KERN_SUCCESS) {
00050 jack_error("JackMachSemaphore::Signal name = %s err = %s", fName, mach_error_string(res));
00051 }
00052 return (res == KERN_SUCCESS);
00053 }
00054
00055 bool JackMachSemaphore::SignalAll()
00056 {
00057 if (!fSemaphore) {
00058 jack_error("JackMachSemaphore::SignalAll name = %s already desallocated!!", fName);
00059 return false;
00060 }
00061
00062 if (fFlush)
00063 return true;
00064
00065 kern_return_t res;
00066
00067 if ((res = semaphore_signal_all(fSemaphore)) != KERN_SUCCESS) {
00068 jack_error("JackMachSemaphore::SignalAll name = %s err = %s", fName, mach_error_string(res));
00069 }
00070 return (res == KERN_SUCCESS);
00071 }
00072
00073 bool JackMachSemaphore::Wait()
00074 {
00075 if (!fSemaphore) {
00076 jack_error("JackMachSemaphore::Wait name = %s already desallocated!!", fName);
00077 return false;
00078 }
00079
00080 kern_return_t res;
00081 if ((res = semaphore_wait(fSemaphore)) != KERN_SUCCESS) {
00082 jack_error("JackMachSemaphore::Wait name = %s err = %s", fName, mach_error_string(res));
00083 }
00084 return (res == KERN_SUCCESS);
00085 }
00086
00087 bool JackMachSemaphore::TimedWait(long usec)
00088 {
00089 if (!fSemaphore) {
00090 jack_error("JackMachSemaphore::TimedWait name = %s already desallocated!!", fName);
00091 return false;
00092 }
00093
00094 kern_return_t res;
00095 mach_timespec time;
00096 time.tv_sec = usec / 1000000;
00097 time.tv_nsec = (usec % 1000000) * 1000;
00098
00099 if ((res = semaphore_timedwait(fSemaphore, time)) != KERN_SUCCESS) {
00100 jack_error("JackMachSemaphore::TimedWait name = %s usec = %ld err = %s", fName, usec, mach_error_string(res));
00101 }
00102 return (res == KERN_SUCCESS);
00103 }
00104
00105
00106 bool JackMachSemaphore::Allocate(const char* name, const char* server_name, int value)
00107 {
00108 BuildName(name, server_name, fName);
00109 mach_port_t task = mach_task_self();
00110 kern_return_t res;
00111
00112 if (fBootPort == 0) {
00113 if ((res = task_get_bootstrap_port(task, &fBootPort)) != KERN_SUCCESS) {
00114 jack_error("Allocate: Can't find bootstrap mach port err = %s", mach_error_string(res));
00115 return false;
00116 }
00117 }
00118
00119 if ((res = semaphore_create(task, &fSemaphore, SYNC_POLICY_FIFO, value)) != KERN_SUCCESS) {
00120 jack_error("Allocate: can create semaphore err = %s", mach_error_string(res));
00121 return false;
00122 }
00123
00124 if ((res = bootstrap_register(fBootPort, fName, fSemaphore)) != KERN_SUCCESS) {
00125 jack_error("Allocate: can't check in mach semaphore name = %s err = %s", fName, mach_error_string(res));
00126
00127 switch (res) {
00128 case BOOTSTRAP_SUCCESS :
00129
00130 break;
00131 case BOOTSTRAP_NOT_PRIVILEGED :
00132 jack_log("bootstrap_register(): bootstrap not privileged");
00133 break;
00134 case BOOTSTRAP_SERVICE_ACTIVE :
00135 jack_log("bootstrap_register(): bootstrap service active");
00136 break;
00137 default :
00138 jack_log("bootstrap_register() err = %s", mach_error_string(res));
00139 break;
00140 }
00141
00142 return false;
00143 }
00144
00145 jack_log("JackMachSemaphore::Allocate name = %s", fName);
00146 return true;
00147 }
00148
00149
00150 bool JackMachSemaphore::ConnectInput(const char* name, const char* server_name)
00151 {
00152 BuildName(name, server_name, fName);
00153 kern_return_t res;
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163 if (fBootPort == 0) {
00164 if ((res = task_get_bootstrap_port(mach_task_self(), &fBootPort)) != KERN_SUCCESS) {
00165 jack_error("Connect: can't find bootstrap port err = %s", mach_error_string(res));
00166 return false;
00167 }
00168 }
00169
00170 if ((res = bootstrap_look_up(fBootPort, fName, &fSemaphore)) != KERN_SUCCESS) {
00171 jack_error("Connect: can't find mach semaphore name = %s err = %s", fName, mach_error_string(res));
00172 return false;
00173 }
00174
00175 jack_log("JackMachSemaphore::Connect name = %s ", fName);
00176 return true;
00177 }
00178
00179 bool JackMachSemaphore::Connect(const char* name, const char* server_name)
00180 {
00181 return ConnectInput(name, server_name);
00182 }
00183
00184 bool JackMachSemaphore::ConnectOutput(const char* name, const char* server_name)
00185 {
00186 return ConnectInput(name, server_name);
00187 }
00188
00189 bool JackMachSemaphore::Disconnect()
00190 {
00191 if (fSemaphore > 0) {
00192 jack_log("JackMachSemaphore::Disconnect name = %s", fName);
00193 fSemaphore = 0;
00194 }
00195
00196 return true;
00197 }
00198
00199
00200 void JackMachSemaphore::Destroy()
00201 {
00202 kern_return_t res;
00203
00204 if (fSemaphore > 0) {
00205 jack_log("JackMachSemaphore::Destroy");
00206 if ((res = semaphore_destroy(mach_task_self(), fSemaphore)) != KERN_SUCCESS) {
00207 jack_error("JackMachSemaphore::Destroy can't destroy semaphore err = %s", mach_error_string(res));
00208 }
00209 fSemaphore = 0;
00210 } else {
00211 jack_error("JackMachSemaphore::Destroy semaphore < 0");
00212 }
00213 }
00214
00215 }
00216