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
00027 using namespace std;
00028
00029 namespace Jack
00030 {
00031
00032 map<mach_port_t, JackMachServerChannel*> JackMachServerChannel::fPortTable;
00033
00034 JackMachServerChannel::JackMachServerChannel()
00035 {
00036 fThread = new JackMachThread(this);
00037 }
00038
00039 JackMachServerChannel::~JackMachServerChannel()
00040 {
00041 delete fThread;
00042 }
00043
00044 int JackMachServerChannel::Open(JackServer* server)
00045 {
00046 JackLog("JackMachServerChannel::Open\n");
00047
00048 if (!fServerPort.AllocatePort(jack_server_entry, 16)) {
00049 jack_error("Cannot check in Jack server");
00050 return -1;
00051 }
00052
00053 if (fThread->Start() != 0) {
00054 jack_error("Cannot start Jack server listener");
00055 return -1;
00056 }
00057
00058 fServer = server;
00059 fPortTable[fServerPort.GetPort()] = this;
00060 return 0;
00061 }
00062
00063 void JackMachServerChannel::Close()
00064 {
00065 JackLog("JackMachServerChannel::Close\n");
00066 fThread->Kill();
00067 fServerPort.DestroyPort();
00068 }
00069
00070 JackEngine* JackMachServerChannel::GetEngine()
00071 {
00072 return fServer->GetEngine();
00073 }
00074
00075 JackServer* JackMachServerChannel::GetServer()
00076 {
00077 return fServer;
00078 }
00079
00080 void JackMachServerChannel::AddClient(char* name, mach_port_t* private_port, int* shared_engine, int* shared_client, int* shared_graph, int* result)
00081 {
00082 int refnum = -1;
00083 *result = GetEngine()->ClientNew(name, &refnum, shared_engine, shared_client, shared_graph);
00084
00085 if (*result == 0) {
00086 mach_port_t port = fServerPort.AddPort();
00087 if (port != 0) {
00088 fClientTable[port] = refnum;
00089 fPortTable[port] = this;
00090 *private_port = port;
00091 } else {
00092 jack_error("Cannot create private client mach port");
00093 *result = -1;
00094 }
00095 } else {
00096 jack_error("Cannot create new client");
00097 }
00098 }
00099
00100 void JackMachServerChannel::RemoveClient(mach_port_t private_port, int refnum)
00101 {
00102 GetEngine()->ClientClose(refnum);
00103 fClientTable.erase(private_port);
00104
00105
00106 kern_return_t res;
00107 if ((res = mach_port_destroy(mach_task_self(), private_port)) != KERN_SUCCESS) {
00108 jack_error("server_rpc_jack_client_close mach_port_destroy %s", mach_error_string(res));
00109 }
00110 }
00111
00112 void JackMachServerChannel::KillClient(mach_port_t private_port)
00113 {
00114 JackLog("JackMachServerChannel::KillClient\n");
00115 int refnum = fClientTable[private_port];
00116 assert(refnum > 0);
00117 fServer->Notify(refnum, JackNotifyChannelInterface::kDeadClient, 0);
00118 fClientTable.erase(private_port);
00119
00120
00121 kern_return_t res;
00122 if ((res = mach_port_destroy(mach_task_self(), private_port)) != KERN_SUCCESS) {
00123 jack_error("server_rpc_jack_client_close mach_port_destroy %s", mach_error_string(res));
00124 }
00125 }
00126
00127 boolean_t JackMachServerChannel::MessageHandler(mach_msg_header_t* Request, mach_msg_header_t* Reply)
00128 {
00129 if (Request->msgh_id == MACH_NOTIFY_NO_SENDERS) {
00130 JackLog("MACH_NOTIFY_NO_SENDERS %ld\n", Request->msgh_local_port);
00131 JackMachServerChannel* channel = JackMachServerChannel::fPortTable[Request->msgh_local_port];
00132 assert(channel);
00133 channel->KillClient(Request->msgh_local_port);
00134 } else {
00135 JackRPCEngine_server(Request, Reply);
00136 }
00137 return true;
00138 }
00139
00140 bool JackMachServerChannel::Execute()
00141 {
00142 kern_return_t res;
00143 if ((res = mach_msg_server(MessageHandler, 1024, fServerPort.GetPortSet(), 0)) != KERN_SUCCESS) {
00144 JackLog("JackMachServerChannel::Execute: err = %s\n", mach_error_string(res));
00145 }
00146
00147 return true;
00148 }
00149
00150 }
00151
00152