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