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 void JackMachSemaphore::BuildName(const char* client_name, const char* server_name, char* res, int size)
00030 {
00031 char ext_client_name[JACK_CLIENT_NAME_SIZE + 1];
00032 JackTools::RewriteName(client_name, ext_client_name);
00033 snprintf(res, size, "jack_mach_sem.%d_%s_%s", JackTools::GetUID(), server_name, ext_client_name);
00034 }
00035
00036 bool JackMachSemaphore::Signal()
00037 {
00038 if (!fSemaphore) {
00039 jack_error("JackMachSemaphore::Signal name = %s already deallocated!!", fName);
00040 return false;
00041 }
00042
00043 if (fFlush) {
00044 return true;
00045 }
00046
00047 kern_return_t res;
00048 if ((res = semaphore_signal(fSemaphore)) != KERN_SUCCESS) {
00049 jack_error("JackMachSemaphore::Signal name = %s err = %s", fName, mach_error_string(res));
00050 }
00051 return (res == KERN_SUCCESS);
00052 }
00053
00054 bool JackMachSemaphore::SignalAll()
00055 {
00056 if (!fSemaphore) {
00057 jack_error("JackMachSemaphore::SignalAll name = %s already deallocated!!", fName);
00058 return false;
00059 }
00060
00061 if (fFlush) {
00062 return true;
00063 }
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 deallocated!!", 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 deallocated!!", 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, sizeof(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, sizeof(fName));
00153 kern_return_t res;
00154
00155 if (fBootPort == 0) {
00156 if ((res = task_get_bootstrap_port(mach_task_self(), &fBootPort)) != KERN_SUCCESS) {
00157 jack_error("Connect: can't find bootstrap port err = %s", mach_error_string(res));
00158 return false;
00159 }
00160 }
00161
00162 if ((res = bootstrap_look_up(fBootPort, fName, &fSemaphore)) != KERN_SUCCESS) {
00163 jack_error("Connect: can't find mach semaphore name = %s err = %s", fName, mach_error_string(res));
00164 return false;
00165 }
00166
00167 jack_log("JackMachSemaphore::Connect name = %s ", fName);
00168 return true;
00169 }
00170
00171 bool JackMachSemaphore::Connect(const char* name, const char* server_name)
00172 {
00173 return ConnectInput(name, server_name);
00174 }
00175
00176 bool JackMachSemaphore::ConnectOutput(const char* name, const char* server_name)
00177 {
00178 return ConnectInput(name, server_name);
00179 }
00180
00181 bool JackMachSemaphore::Disconnect()
00182 {
00183 if (fSemaphore > 0) {
00184 jack_log("JackMachSemaphore::Disconnect name = %s", fName);
00185 fSemaphore = 0;
00186 }
00187
00188 return true;
00189 }
00190
00191
00192 void JackMachSemaphore::Destroy()
00193 {
00194 kern_return_t res;
00195
00196 if (fSemaphore > 0) {
00197 jack_log("JackMachSemaphore::Destroy name = %s", fName);
00198 if ((res = semaphore_destroy(mach_task_self(), fSemaphore)) != KERN_SUCCESS) {
00199 jack_error("JackMachSemaphore::Destroy can't destroy semaphore err = %s", mach_error_string(res));
00200 }
00201 fSemaphore = 0;
00202 } else {
00203 jack_error("JackMachSemaphore::Destroy semaphore < 0");
00204 }
00205 }
00206
00207 }
00208