00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "JackMachServerChannel.h"
00021 #include "JackRPCEngineServer.c"
00022 #include "JackError.h"
00023 #include "JackServer.h"
00024 #include "JackMachThread.h"
00025 #include "JackEngine.h"
00026 #include "JackNotification.h"
00027
00028 using namespace std;
00029
00030 namespace Jack
00031 {
00032
00033 map<mach_port_t, JackMachServerChannel*> JackMachServerChannel::fPortTable;
00034
00035 JackMachServerChannel::JackMachServerChannel()
00036 {
00037 fThread = new JackMachThread(this);
00038 }
00039
00040 JackMachServerChannel::~JackMachServerChannel()
00041 {
00042 delete fThread;
00043 }
00044
00045 int JackMachServerChannel::Open(const char* server_name, JackServer* server)
00046 {
00047 JackLog("JackMachServerChannel::Open\n");
00048 char jack_server_entry_name[512];
00049 snprintf(jack_server_entry_name, sizeof(jack_server_entry_name), "%s_%s", jack_server_entry, server_name);
00050
00051 if (!fServerPort.AllocatePort(jack_server_entry_name, 16)) {
00052 jack_error("Cannot check in Jack server");
00053 return -1;
00054 }
00055
00056 if (fThread->Start() != 0) {
00057 jack_error("Cannot start Jack server listener");
00058 return -1;
00059 }
00060
00061 fServer = server;
00062 fPortTable[fServerPort.GetPort()] = this;
00063 return 0;
00064 }
00065
00066 void JackMachServerChannel::Close()
00067 {
00068 JackLog("JackMachServerChannel::Close\n");
00069 fThread->Kill();
00070 fServerPort.DestroyPort();
00071 }
00072
00073 JackEngine* JackMachServerChannel::GetEngine()
00074 {
00075 return fServer->GetEngine();
00076 }
00077
00078 JackServer* JackMachServerChannel::GetServer()
00079 {
00080 return fServer;
00081 }
00082
00083 void JackMachServerChannel::ClientCheck(char* name, char* name_res, int protocol, int options, int* status, int* result)
00084 {
00085 *result = GetEngine()->ClientCheck(name, name_res, protocol, options, status);
00086 }
00087
00088 void JackMachServerChannel::ClientOpen(char* name, mach_port_t* private_port, int* shared_engine, int* shared_client, int* shared_graph, int* result)
00089 {
00090 int refnum = -1;
00091 *result = GetEngine()->ClientExternalOpen(name, &refnum, shared_engine, shared_client, shared_graph);
00092
00093 if (*result == 0) {
00094 mach_port_t port = fServerPort.AddPort();
00095 if (port != 0) {
00096 fClientTable[port] = refnum;
00097 fPortTable[port] = this;
00098 *private_port = port;
00099 } else {
00100 jack_error("Cannot create private client mach port");
00101 *result = -1;
00102 }
00103 } else {
00104 jack_error("Cannot create new client");
00105 }
00106 }
00107
00108 void JackMachServerChannel::ClientClose(mach_port_t private_port, int refnum)
00109 {
00110 GetEngine()->ClientExternalClose(refnum);
00111 fClientTable.erase(private_port);
00112
00113
00114 kern_return_t res;
00115 if ((res = mach_port_destroy(mach_task_self(), private_port)) != KERN_SUCCESS) {
00116 jack_error("server_rpc_jack_client_close mach_port_destroy %s", mach_error_string(res));
00117 }
00118 }
00119
00120 void JackMachServerChannel::ClientKill(mach_port_t private_port)
00121 {
00122 JackLog("JackMachServerChannel::ClientKill\n");
00123 int refnum = fClientTable[private_port];
00124 assert(refnum > 0);
00125 fServer->Notify(refnum, kDeadClient, 0);
00126 fClientTable.erase(private_port);
00127
00128
00129 kern_return_t res;
00130 if ((res = mach_port_destroy(mach_task_self(), private_port)) != KERN_SUCCESS) {
00131 jack_error("server_rpc_jack_client_close mach_port_destroy %s", mach_error_string(res));
00132 }
00133 }
00134
00135 boolean_t JackMachServerChannel::MessageHandler(mach_msg_header_t* Request, mach_msg_header_t* Reply)
00136 {
00137 if (Request->msgh_id == MACH_NOTIFY_NO_SENDERS) {
00138 JackLog("MACH_NOTIFY_NO_SENDERS %ld\n", Request->msgh_local_port);
00139 JackMachServerChannel* channel = JackMachServerChannel::fPortTable[Request->msgh_local_port];
00140 assert(channel);
00141 channel->ClientKill(Request->msgh_local_port);
00142 } else {
00143 JackRPCEngine_server(Request, Reply);
00144 }
00145 return true;
00146 }
00147
00148 bool JackMachServerChannel::Execute()
00149 {
00150 kern_return_t res;
00151 if ((res = mach_msg_server(MessageHandler, 1024, fServerPort.GetPortSet(), 0)) != KERN_SUCCESS) {
00152 JackLog("JackMachServerChannel::Execute: err = %s\n", mach_error_string(res));
00153 }
00154
00155 return true;
00156 }
00157
00158 }
00159
00160