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