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