git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@1507 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.64
| @@ -48,7 +48,7 @@ class JackClientChannelInterface | |||||
| {} | {} | ||||
| // Open the Server/Client connection | // Open the Server/Client connection | ||||
| virtual int Open(const char* name, JackClient* obj, jack_options_t options, jack_status_t* status) | |||||
| virtual int Open(const char* name, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status) | |||||
| { | { | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -352,6 +352,62 @@ void JackEngine::NotifyActivate(int refnum) | |||||
| // Client management | // Client management | ||||
| //------------------- | //------------------- | ||||
| int JackEngine::ClientCheck(const char* name, char* name_res, int options, int* status) | |||||
| { | |||||
| strcpy(name_res, name); | |||||
| if (ClientCheckName(name)) { | |||||
| *status |= JackNameNotUnique; | |||||
| if (options & JackUseExactName) { | |||||
| jack_error("cannot create new client; %s already exists", name); | |||||
| *status |= JackFailure; | |||||
| return -1; | |||||
| } | |||||
| if (GenerateUniqueName(name_res)) { | |||||
| *status |= JackFailure; | |||||
| return -1; | |||||
| } | |||||
| } | |||||
| return 0; | |||||
| } | |||||
| bool JackEngine::GenerateUniqueName(char* name) | |||||
| { | |||||
| int tens, ones; | |||||
| int length = strlen(name); | |||||
| if (length > JACK_CLIENT_NAME_SIZE - 4) { | |||||
| jack_error("%s exists and is too long to make unique", name); | |||||
| return true; /* failure */ | |||||
| } | |||||
| /* generate a unique name by appending "-01".."-99" */ | |||||
| name[length++] = '-'; | |||||
| tens = length++; | |||||
| ones = length++; | |||||
| name[tens] = '0'; | |||||
| name[ones] = '1'; | |||||
| name[length] = '\0'; | |||||
| while (ClientCheckName(name)) { | |||||
| if (name[ones] == '9') { | |||||
| if (name[tens] == '9') { | |||||
| jack_error("client %s has 99 extra instances already", name); | |||||
| return true; /* give up */ | |||||
| } | |||||
| name[tens]++; | |||||
| name[ones] = '0'; | |||||
| } else { | |||||
| name[ones]++; | |||||
| } | |||||
| } | |||||
| return false; | |||||
| } | |||||
| bool JackEngine::ClientCheckName(const char* name) | bool JackEngine::ClientCheckName(const char* name) | ||||
| { | { | ||||
| for (int i = 0; i < CLIENT_NUM; i++) { | for (int i = 0; i < CLIENT_NUM; i++) { | ||||
| @@ -368,11 +424,6 @@ int JackEngine::ClientExternalOpen(const char* name, int* ref, int* shared_engin | |||||
| { | { | ||||
| JackLog("JackEngine::ClientOpen: name = %s \n", name); | JackLog("JackEngine::ClientOpen: name = %s \n", name); | ||||
| if (ClientCheckName(name)) { | |||||
| jack_error("client %s already registered", name); | |||||
| return -1; | |||||
| } | |||||
| int refnum = Allocate(); | int refnum = Allocate(); | ||||
| if (refnum < 0) { | if (refnum < 0) { | ||||
| jack_error("No more refnum available"); | jack_error("No more refnum available"); | ||||
| @@ -422,11 +473,6 @@ int JackEngine::ClientInternalOpen(const char* name, int* ref, JackEngineControl | |||||
| { | { | ||||
| JackLog("JackEngine::ClientInternalNew: name = %s\n", name); | JackLog("JackEngine::ClientInternalNew: name = %s\n", name); | ||||
| if (ClientCheckName(name)) { | |||||
| jack_error("client %s already registered", name); | |||||
| return -1; | |||||
| } | |||||
| int refnum = Allocate(); | int refnum = Allocate(); | ||||
| if (refnum < 0) { | if (refnum < 0) { | ||||
| jack_error("No more refnum available"); | jack_error("No more refnum available"); | ||||
| @@ -62,6 +62,7 @@ class JackEngine | |||||
| void ProcessNext(jack_time_t callback_usecs); | void ProcessNext(jack_time_t callback_usecs); | ||||
| void ProcessCurrent(jack_time_t callback_usecs); | void ProcessCurrent(jack_time_t callback_usecs); | ||||
| bool ClientCheckName(const char* name); | bool ClientCheckName(const char* name); | ||||
| bool GenerateUniqueName(char* name); | |||||
| int Allocate(); | int Allocate(); | ||||
| public: | public: | ||||
| @@ -74,6 +75,7 @@ class JackEngine | |||||
| // Client management | // Client management | ||||
| int ClientCheck(const char* name, char* name_res, int options, int* status); | |||||
| int ClientExternalOpen(const char* name, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager); | int ClientExternalOpen(const char* name, int* ref, int* shared_engine, int* shared_client, int* shared_graph_manager); | ||||
| int ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client); | int ClientInternalOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client); | ||||
| @@ -68,16 +68,21 @@ JackInternalClient::~JackInternalClient() | |||||
| int JackInternalClient::Open(const char* name, jack_options_t options, jack_status_t* status) | int JackInternalClient::Open(const char* name, jack_options_t options, jack_status_t* status) | ||||
| { | { | ||||
| int result; | int result; | ||||
| char name_res[JACK_CLIENT_NAME_SIZE]; | |||||
| JackLog("JackInternalClient::Open name = %s\n", name); | JackLog("JackInternalClient::Open name = %s\n", name); | ||||
| strcpy(fClientControl->fName, name); | |||||
| fChannel->ClientCheck(name, name_res, (int)options, (int*)status, &result); | |||||
| if (result < 0) { | |||||
| jack_error("Client name = %s conflits with another running client", name); | |||||
| goto error; | |||||
| } | |||||
| // TODO | |||||
| // check client name | |||||
| strcpy(fClientControl->fName, name_res); | |||||
| // Require new client | // Require new client | ||||
| fChannel->ClientOpen(name, &fClientControl->fRefNum, &fEngineControl, &fGraphManager, this, &result); | |||||
| fChannel->ClientOpen(name_res, &fClientControl->fRefNum, &fEngineControl, &fGraphManager, this, &result); | |||||
| if (result < 0) { | if (result < 0) { | ||||
| jack_error("Cannot open client name = %s", name); | |||||
| jack_error("Cannot open client name = %s", name_res); | |||||
| goto error; | goto error; | ||||
| } | } | ||||
| @@ -43,7 +43,17 @@ class JackInternalClientChannel : public JackClientChannelInterface | |||||
| {} | {} | ||||
| virtual ~JackInternalClientChannel() | virtual ~JackInternalClientChannel() | ||||
| {} | {} | ||||
| // Open the Server/Client connection | |||||
| virtual int Open(const char* name, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status) | |||||
| { | |||||
| return 0; | |||||
| } | |||||
| void ClientCheck(const char* name, char* name_res, int options, int* status, int* result) | |||||
| { | |||||
| *result = fEngine->ClientCheck(name, name_res, options, status); | |||||
| } | |||||
| void ClientOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result) | void ClientOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result) | ||||
| { | { | ||||
| *result = fEngine->ClientInternalOpen(name, ref, shared_engine, shared_manager, client); | *result = fEngine->ClientInternalOpen(name, ref, shared_engine, shared_manager, client); | ||||
| @@ -99,7 +99,6 @@ static jack_client_t* jack_client_open_aux(const char* client_name, jack_options | |||||
| JackLibGlobals::Destroy(); // jack library destruction | JackLibGlobals::Destroy(); // jack library destruction | ||||
| return NULL; | return NULL; | ||||
| } else { | } else { | ||||
| *status = (jack_status_t)0; // TO REMOVE | |||||
| return (jack_client_t*)client; | return (jack_client_t*)client; | ||||
| } | } | ||||
| } | } | ||||
| @@ -65,9 +65,10 @@ int JackLibClient::Open(const char* name, jack_options_t options, jack_status_t* | |||||
| { | { | ||||
| int shared_engine, shared_client, shared_graph, result; | int shared_engine, shared_client, shared_graph, result; | ||||
| JackLog("JackLibClient::Open %s\n", name); | JackLog("JackLibClient::Open %s\n", name); | ||||
| // Open server/client channel | // Open server/client channel | ||||
| if (fChannel->Open(name, this, options, status) < 0) { | |||||
| char name_res[JACK_CLIENT_NAME_SIZE]; | |||||
| if (fChannel->Open(name, name_res, this, options, status) < 0) { | |||||
| jack_error("Cannot connect to the server"); | jack_error("Cannot connect to the server"); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| @@ -79,9 +80,9 @@ int JackLibClient::Open(const char* name, jack_options_t options, jack_status_t* | |||||
| } | } | ||||
| // Require new client | // Require new client | ||||
| fChannel->ClientOpen(name, &shared_engine, &shared_client, &shared_graph, &result); | |||||
| fChannel->ClientOpen(name_res, &shared_engine, &shared_client, &shared_graph, &result); | |||||
| if (result < 0) { | if (result < 0) { | ||||
| jack_error("Cannot open %s client", name); | |||||
| jack_error("Cannot open %s client", name_res); | |||||
| goto error; | goto error; | ||||
| } | } | ||||
| @@ -57,12 +57,13 @@ struct JackRequest | |||||
| kSetBufferSize = 20, | kSetBufferSize = 20, | ||||
| kSetFreeWheel = 21, | kSetFreeWheel = 21, | ||||
| kClientOpen = 22, | |||||
| kClientClose = 23, | |||||
| kConnectNamePorts = 24, | |||||
| kDisconnectNamePorts = 25, | |||||
| kClientCheck = 22, | |||||
| kClientOpen = 23, | |||||
| kClientClose = 24, | |||||
| kConnectNamePorts = 25, | |||||
| kDisconnectNamePorts = 26, | |||||
| kNotification = 26 | |||||
| kNotification = 27 | |||||
| }; | }; | ||||
| RequestType fType; | RequestType fType; | ||||
| @@ -99,7 +100,7 @@ struct JackResult | |||||
| JackResult(): fResult( -1) | JackResult(): fResult( -1) | ||||
| {} | {} | ||||
| JackResult(int status): fResult(status) | |||||
| JackResult(int result): fResult(result) | |||||
| {} | {} | ||||
| virtual ~JackResult() | virtual ~JackResult() | ||||
| {} | {} | ||||
| @@ -115,6 +116,74 @@ struct JackResult | |||||
| } | } | ||||
| }; | }; | ||||
| /*! | |||||
| \brief CheckClient request. | |||||
| */ | |||||
| struct JackClientCheckRequest : public JackRequest | |||||
| { | |||||
| char fName[JACK_CLIENT_NAME_SIZE + 1]; | |||||
| int fOptions; | |||||
| JackClientCheckRequest() | |||||
| {} | |||||
| JackClientCheckRequest(const char* name, int options): JackRequest(JackRequest::kClientCheck),fOptions(options) | |||||
| { | |||||
| snprintf(fName, sizeof(fName), "%s", name); | |||||
| } | |||||
| int Read(JackChannelTransaction* trans) | |||||
| { | |||||
| CheckRes(trans->Read(&fName, JACK_PORT_NAME_SIZE + 1)); | |||||
| return trans->Read(&fOptions, sizeof(int)); | |||||
| } | |||||
| int Write(JackChannelTransaction* trans) | |||||
| { | |||||
| CheckRes(JackRequest::Write(trans)); | |||||
| CheckRes(trans->Write(&fName, JACK_PORT_NAME_SIZE + 1)); | |||||
| return trans->Write(&fOptions, sizeof(int)); | |||||
| } | |||||
| }; | |||||
| /*! | |||||
| \brief CheckClient result. | |||||
| */ | |||||
| struct JackClientCheckResult : public JackResult | |||||
| { | |||||
| char fName[JACK_CLIENT_NAME_SIZE + 1]; | |||||
| int fStatus; | |||||
| JackClientCheckResult():fStatus(0) | |||||
| {} | |||||
| JackClientCheckResult(int32_t result, const char* name, int status) | |||||
| : JackResult(result), fStatus(status) | |||||
| { | |||||
| snprintf(fName, sizeof(fName), "%s", name); | |||||
| } | |||||
| int Read(JackChannelTransaction* trans) | |||||
| { | |||||
| CheckRes(JackResult::Read(trans)); | |||||
| CheckRes(trans->Read(&fName, JACK_PORT_NAME_SIZE + 1)); | |||||
| CheckRes(trans->Read(&fStatus, sizeof(int))); | |||||
| return 0; | |||||
| } | |||||
| int Write(JackChannelTransaction* trans) | |||||
| { | |||||
| CheckRes(JackResult::Write(trans)); | |||||
| CheckRes(trans->Write(&fName, JACK_PORT_NAME_SIZE + 1)); | |||||
| CheckRes(trans->Write(&fStatus, sizeof(int))); | |||||
| return 0; | |||||
| } | |||||
| }; | |||||
| /*! | /*! | ||||
| \brief NewClient request. | \brief NewClient request. | ||||
| */ | */ | ||||
| @@ -158,8 +227,8 @@ struct JackClientOpenResult : public JackResult | |||||
| JackClientOpenResult() | JackClientOpenResult() | ||||
| :fSharedEngine(-1), fSharedClient(-1), fSharedGraph(-1), fProtocolVersion(0) | :fSharedEngine(-1), fSharedClient(-1), fSharedGraph(-1), fProtocolVersion(0) | ||||
| {} | {} | ||||
| JackClientOpenResult(int32_t status, int index1, int index2, int index3) | |||||
| : JackResult(status), fSharedEngine(index1), fSharedClient(index2), fSharedGraph(index3), fProtocolVersion(0) | |||||
| JackClientOpenResult(int32_t result, int index1, int index2, int index3) | |||||
| : JackResult(result), fSharedEngine(index1), fSharedClient(index2), fSharedGraph(index3), fProtocolVersion(0) | |||||
| {} | {} | ||||
| int Read(JackChannelTransaction* trans) | int Read(JackChannelTransaction* trans) | ||||
| @@ -38,16 +38,24 @@ JackSocketClientChannel::~JackSocketClientChannel() | |||||
| delete fNotificationSocket; | delete fNotificationSocket; | ||||
| } | } | ||||
| int JackSocketClientChannel::Open(const char* name, JackClient* obj, jack_options_t options, jack_status_t* status) | |||||
| int JackSocketClientChannel::Open(const char* name, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status) | |||||
| { | { | ||||
| int result = 0; | |||||
| JackLog("JackSocketClientChannel::Open name = %s\n", name); | JackLog("JackSocketClientChannel::Open name = %s\n", name); | ||||
| if (fRequestSocket.Connect(jack_server_dir, 0) < 0) { | if (fRequestSocket.Connect(jack_server_dir, 0) < 0) { | ||||
| jack_error("Cannot connect to server socket"); | jack_error("Cannot connect to server socket"); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| // Check name in server | |||||
| ClientCheck(name, name_res, (int)options, (int*)status, &result); | |||||
| if (result < 0) { | |||||
| jack_error("Client name = %s conflits with another running client", name); | |||||
| goto error; | |||||
| } | |||||
| if (fNotificationListenSocket.Bind(jack_client_dir, name, 0) < 0) { | |||||
| if (fNotificationListenSocket.Bind(jack_client_dir, name_res, 0) < 0) { | |||||
| jack_error("Cannot bind socket"); | jack_error("Cannot bind socket"); | ||||
| goto error; | goto error; | ||||
| } | } | ||||
| @@ -113,9 +121,13 @@ void JackSocketClientChannel::ServerAsyncCall(JackRequest* req, JackResult* res, | |||||
| } | } | ||||
| } | } | ||||
| void JackSocketClientChannel::ClientCheck(const char* name, char* name_res, int options, int* status, int* result) | |||||
| void JackSocketClientChannel::ClientCheck(const char* name, char* name_res, int options, int* status, int* result) | |||||
| { | { | ||||
| JackClientCheckRequest req(name, options); | |||||
| JackClientCheckResult res; | |||||
| ServerSyncCall(&req, &res, result); | |||||
| *status = res.fStatus; | |||||
| strcpy(name_res, res.fName); | |||||
| } | } | ||||
| void JackSocketClientChannel::ClientOpen(const char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result) | void JackSocketClientChannel::ClientOpen(const char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result) | ||||
| @@ -51,7 +51,7 @@ class JackSocketClientChannel : public JackClientChannelInterface, public JackRu | |||||
| JackSocketClientChannel(); | JackSocketClientChannel(); | ||||
| virtual ~JackSocketClientChannel(); | virtual ~JackSocketClientChannel(); | ||||
| int Open(const char* name, JackClient* obj, jack_options_t options, jack_status_t* status); | |||||
| int Open(const char* name, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status); | |||||
| void Close(); | void Close(); | ||||
| int Start(); | int Start(); | ||||
| @@ -89,9 +89,9 @@ void JackSocketServerChannel::CreateClient() | |||||
| } | } | ||||
| } | } | ||||
| void JackSocketServerChannel::AddClient(int fd, char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result) | |||||
| void JackSocketServerChannel::ClientAdd(int fd, char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result) | |||||
| { | { | ||||
| JackLog("JackSocketServerChannel::AddClient\n"); | |||||
| JackLog("JackSocketServerChannel::ClientAdd\n"); | |||||
| int refnum = -1; | int refnum = -1; | ||||
| *result = fServer->GetEngine()->ClientExternalOpen(name, &refnum, shared_engine, shared_client, shared_graph); | *result = fServer->GetEngine()->ClientExternalOpen(name, &refnum, shared_engine, shared_client, shared_graph); | ||||
| if (*result == 0) { | if (*result == 0) { | ||||
| @@ -102,26 +102,26 @@ void JackSocketServerChannel::AddClient(int fd, char* name, int* shared_engine, | |||||
| } | } | ||||
| } | } | ||||
| void JackSocketServerChannel::RemoveClient(int fd, int refnum) | |||||
| void JackSocketServerChannel::ClientRemove(int fd, int refnum) | |||||
| { | { | ||||
| pair<int, JackClientSocket*> elem = fSocketTable[fd]; | pair<int, JackClientSocket*> elem = fSocketTable[fd]; | ||||
| JackClientSocket* socket = elem.second; | JackClientSocket* socket = elem.second; | ||||
| assert(socket); | assert(socket); | ||||
| JackLog("JackSocketServerChannel::RemoveClient ref = %d\n", refnum); | |||||
| JackLog("JackSocketServerChannel::ClientRemove ref = %d\n", refnum); | |||||
| fSocketTable.erase(fd); | fSocketTable.erase(fd); | ||||
| socket->Close(); | socket->Close(); | ||||
| delete socket; | delete socket; | ||||
| fRebuild = true; | fRebuild = true; | ||||
| } | } | ||||
| void JackSocketServerChannel::KillClient(int fd) | |||||
| void JackSocketServerChannel::ClientKill(int fd) | |||||
| { | { | ||||
| pair<int, JackClientSocket*> elem = fSocketTable[fd]; | pair<int, JackClientSocket*> elem = fSocketTable[fd]; | ||||
| JackClientSocket* socket = elem.second; | JackClientSocket* socket = elem.second; | ||||
| int refnum = elem.first; | int refnum = elem.first; | ||||
| assert(socket); | assert(socket); | ||||
| JackLog("JackSocketServerChannel::KillClient ref = %d\n", refnum); | |||||
| JackLog("JackSocketServerChannel::ClientKill ref = %d\n", refnum); | |||||
| if (refnum == -1) { // Should never happen... correspond to a client that started the socket but never opened... | if (refnum == -1) { // Should never happen... correspond to a client that started the socket but never opened... | ||||
| jack_error("Client not opened"); | jack_error("Client not opened"); | ||||
| @@ -150,13 +150,23 @@ int JackSocketServerChannel::HandleRequest(int fd) | |||||
| // Read data | // Read data | ||||
| switch (header.fType) { | switch (header.fType) { | ||||
| case JackRequest::kClientCheck: { | |||||
| JackLog("JackRequest::kClientCheck\n"); | |||||
| JackClientCheckRequest req; | |||||
| JackClientCheckResult res; | |||||
| if (req.Read(socket) == 0) | |||||
| res.fResult = fServer->GetEngine()->ClientCheck(req.fName, res.fName, req.fOptions, &res.fStatus); | |||||
| res.Write(socket); | |||||
| break; | |||||
| } | |||||
| case JackRequest::kClientOpen: { | case JackRequest::kClientOpen: { | ||||
| JackLog("JackRequest::ClientOpen\n"); | JackLog("JackRequest::ClientOpen\n"); | ||||
| JackClientOpenRequest req; | JackClientOpenRequest req; | ||||
| JackClientOpenResult res; | JackClientOpenResult res; | ||||
| if (req.Read(socket) == 0) | if (req.Read(socket) == 0) | ||||
| AddClient(fd, req.fName, &res.fSharedEngine, &res.fSharedClient, &res.fSharedGraph, &res.fResult); | |||||
| ClientAdd(fd, req.fName, &res.fSharedEngine, &res.fSharedClient, &res.fSharedGraph, &res.fResult); | |||||
| res.Write(socket); | res.Write(socket); | ||||
| break; | break; | ||||
| } | } | ||||
| @@ -168,7 +178,7 @@ int JackSocketServerChannel::HandleRequest(int fd) | |||||
| if (req.Read(socket) == 0) | if (req.Read(socket) == 0) | ||||
| res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum); | res.fResult = fServer->GetEngine()->ClientExternalClose(req.fRefNum); | ||||
| res.Write(socket); | res.Write(socket); | ||||
| RemoveClient(fd, req.fRefNum); | |||||
| ClientRemove(fd, req.fRefNum); | |||||
| break; | break; | ||||
| } | } | ||||
| @@ -347,11 +357,11 @@ bool JackSocketServerChannel::Execute() | |||||
| JackLog("fPollTable i = %ld fd = %ld\n", i, fd); | JackLog("fPollTable i = %ld fd = %ld\n", i, fd); | ||||
| if (fPollTable[i].revents & ~POLLIN) { | if (fPollTable[i].revents & ~POLLIN) { | ||||
| jack_error("Poll client error err = %s", strerror(errno)); | jack_error("Poll client error err = %s", strerror(errno)); | ||||
| KillClient(fd); | |||||
| ClientKill(fd); | |||||
| } else if (fPollTable[i].revents & POLLIN) { | } else if (fPollTable[i].revents & POLLIN) { | ||||
| if (HandleRequest(fd) < 0) { | if (HandleRequest(fd) < 0) { | ||||
| jack_error("Could not handle external client request"); | jack_error("Could not handle external client request"); | ||||
| //RemoveClient(fd); TO CHECK | |||||
| //ClientRemove(fd); TO CHECK | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -47,9 +47,9 @@ class JackSocketServerChannel : public JackServerChannelInterface, public JackRu | |||||
| int HandleRequest(int fd); | int HandleRequest(int fd); | ||||
| void CreateClient(); | void CreateClient(); | ||||
| void AddClient(int fd, char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result); | |||||
| void RemoveClient(int fd, int refnum); | |||||
| void KillClient(int fd); | |||||
| void ClientAdd(int fd, char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result); | |||||
| void ClientRemove(int fd, int refnum); | |||||
| void ClientKill(int fd); | |||||
| void BuildPoolTable(); | void BuildPoolTable(); | ||||
| public: | public: | ||||
| @@ -34,8 +34,9 @@ using namespace Jack; | |||||
| rpc_type server_rpc_jack_client_check(mach_port_t private_port, client_name_t name, client_name_t name_res, int options, int* status, int* result) | rpc_type server_rpc_jack_client_check(mach_port_t private_port, client_name_t name, client_name_t name_res, int options, int* status, int* result) | ||||
| { | { | ||||
| JackLog("rpc_jack_client_check\n"); | JackLog("rpc_jack_client_check\n"); | ||||
| // TODO | |||||
| *result = 0; | |||||
| JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; | |||||
| assert(channel); | |||||
| channel->ClientCheck((char*)name, (char*)name_res, options, status, result); | |||||
| return KERN_SUCCESS; | return KERN_SUCCESS; | ||||
| } | } | ||||
| @@ -44,7 +45,7 @@ rpc_type server_rpc_jack_client_open(mach_port_t server_port, client_name_t name | |||||
| JackLog("rpc_jack_client_new %s\n", name); | JackLog("rpc_jack_client_new %s\n", name); | ||||
| JackMachServerChannel* channel = JackMachServerChannel::fPortTable[server_port]; | JackMachServerChannel* channel = JackMachServerChannel::fPortTable[server_port]; | ||||
| assert(channel); | assert(channel); | ||||
| channel->AddClient((char*)name, private_port, shared_engine, shared_client, shared_graph, result); | |||||
| channel->ClientOpen((char*)name, private_port, shared_engine, shared_client, shared_graph, result); | |||||
| return KERN_SUCCESS; | return KERN_SUCCESS; | ||||
| } | } | ||||
| @@ -53,7 +54,7 @@ rpc_type server_rpc_jack_client_close(mach_port_t private_port, int refnum, int* | |||||
| JackLog("rpc_jack_client_close\n"); | JackLog("rpc_jack_client_close\n"); | ||||
| JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; | JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; | ||||
| assert(channel); | assert(channel); | ||||
| channel->RemoveClient(private_port, refnum); | |||||
| channel->ClientClose(private_port, refnum); | |||||
| *result = 0; | *result = 0; | ||||
| return KERN_SUCCESS; | return KERN_SUCCESS; | ||||
| } | } | ||||
| @@ -41,7 +41,7 @@ JackMachClientChannel::~JackMachClientChannel() | |||||
| // Server <===> client | // Server <===> client | ||||
| int JackMachClientChannel::Open(const char* name, JackClient* client, jack_options_t options, jack_status_t* status) | |||||
| int JackMachClientChannel::Open(const char* name, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status) | |||||
| { | { | ||||
| JackLog("JackMachClientChannel::Open name = %s\n", name); | JackLog("JackMachClientChannel::Open name = %s\n", name); | ||||
| @@ -53,16 +53,15 @@ int JackMachClientChannel::Open(const char* name, JackClient* client, jack_optio | |||||
| // Check name in server | // Check name in server | ||||
| int result = 0; | int result = 0; | ||||
| char name_res[JACK_CLIENT_NAME_SIZE]; | |||||
| ClientCheck(name, name_res, (int)options, (int*)status, &result); | ClientCheck(name, name_res, (int)options, (int*)status, &result); | ||||
| if (result < 0) { | if (result < 0) { | ||||
| jack_error("Cannot check clientname"); | |||||
| jack_error("Client name = %s conflits with another running client", name); | |||||
| return -1; | return -1; | ||||
| } | } | ||||
| // Prepare local port using client name | // Prepare local port using client name | ||||
| char buf[JACK_CLIENT_NAME_SIZE]; | char buf[JACK_CLIENT_NAME_SIZE]; | ||||
| snprintf(buf, sizeof(buf) - 1, "%s:%s", jack_client_entry, name); | |||||
| snprintf(buf, sizeof(buf) - 1, "%s:%s", jack_client_entry, name_res); | |||||
| if (!fClientPort.AllocatePort(buf, 16)) { | if (!fClientPort.AllocatePort(buf, 16)) { | ||||
| jack_error("Cannot allocate client Mach port"); | jack_error("Cannot allocate client Mach port"); | ||||
| @@ -106,7 +105,7 @@ void JackMachClientChannel::Stop() | |||||
| void JackMachClientChannel::ClientCheck(const char* name, char* name_res, int options, int* status, int* result) | void JackMachClientChannel::ClientCheck(const char* name, char* name_res, int options, int* status, int* result) | ||||
| { | { | ||||
| kern_return_t res = rpc_jack_client_check(fPrivatePort, (char*)name, name_res, options, status, result); | |||||
| kern_return_t res = rpc_jack_client_check(fServerPort.GetPort(), (char*)name, name_res, options, status, result); | |||||
| if (res != KERN_SUCCESS) { | if (res != KERN_SUCCESS) { | ||||
| *result = -1; | *result = -1; | ||||
| jack_error("JackMachClientChannel::ClientCheck err = %s", mach_error_string(res)); | jack_error("JackMachClientChannel::ClientCheck err = %s", mach_error_string(res)); | ||||
| @@ -48,13 +48,13 @@ class JackMachClientChannel : public JackClientChannelInterface, public JackRunn | |||||
| JackMachClientChannel(); | JackMachClientChannel(); | ||||
| virtual ~JackMachClientChannel(); | virtual ~JackMachClientChannel(); | ||||
| int Open(const char* name, JackClient* client, jack_options_t options, jack_status_t* status); | |||||
| int Open(const char* name, char* name_res, JackClient* client, jack_options_t options, jack_status_t* status); | |||||
| void Close(); | void Close(); | ||||
| int Start(); | int Start(); | ||||
| void Stop(); | void Stop(); | ||||
| void ClientCheck(const char* name, char* name_res, int options, int* status, int* result); | |||||
| void ClientCheck(const char* name, char* name_res, int options, int* status, int* result); | |||||
| void ClientOpen(const char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result); | void ClientOpen(const char* name, int* shared_engine, int* shared_client, int* shared_graph, int* result); | ||||
| void ClientClose(int refnum, int* result); | void ClientClose(int refnum, int* result); | ||||
| @@ -78,7 +78,12 @@ JackServer* JackMachServerChannel::GetServer() | |||||
| return fServer; | return fServer; | ||||
| } | } | ||||
| void JackMachServerChannel::AddClient(char* name, mach_port_t* private_port, int* shared_engine, int* shared_client, int* shared_graph, int* result) | |||||
| void JackMachServerChannel::ClientCheck(char* name, char* name_res, int options, int* status, int* result) | |||||
| { | |||||
| *result = GetEngine()->ClientCheck(name, name_res, options, status); | |||||
| } | |||||
| void JackMachServerChannel::ClientOpen(char* name, mach_port_t* private_port, int* shared_engine, int* shared_client, int* shared_graph, int* result) | |||||
| { | { | ||||
| int refnum = -1; | int refnum = -1; | ||||
| *result = GetEngine()->ClientExternalOpen(name, &refnum, shared_engine, shared_client, shared_graph); | *result = GetEngine()->ClientExternalOpen(name, &refnum, shared_engine, shared_client, shared_graph); | ||||
| @@ -98,7 +103,7 @@ void JackMachServerChannel::AddClient(char* name, mach_port_t* private_port, int | |||||
| } | } | ||||
| } | } | ||||
| void JackMachServerChannel::RemoveClient(mach_port_t private_port, int refnum) | |||||
| void JackMachServerChannel::ClientClose(mach_port_t private_port, int refnum) | |||||
| { | { | ||||
| GetEngine()->ClientExternalClose(refnum); | GetEngine()->ClientExternalClose(refnum); | ||||
| fClientTable.erase(private_port); | fClientTable.erase(private_port); | ||||
| @@ -110,9 +115,9 @@ void JackMachServerChannel::RemoveClient(mach_port_t private_port, int refnum) | |||||
| } | } | ||||
| } | } | ||||
| void JackMachServerChannel::KillClient(mach_port_t private_port) | |||||
| void JackMachServerChannel::ClientKill(mach_port_t private_port) | |||||
| { | { | ||||
| JackLog("JackMachServerChannel::KillClient\n"); | |||||
| JackLog("JackMachServerChannel::ClientKill\n"); | |||||
| int refnum = fClientTable[private_port]; | int refnum = fClientTable[private_port]; | ||||
| assert(refnum > 0); | assert(refnum > 0); | ||||
| fServer->Notify(refnum, kDeadClient, 0); | fServer->Notify(refnum, kDeadClient, 0); | ||||
| @@ -131,7 +136,7 @@ boolean_t JackMachServerChannel::MessageHandler(mach_msg_header_t* Request, mach | |||||
| JackLog("MACH_NOTIFY_NO_SENDERS %ld\n", Request->msgh_local_port); | JackLog("MACH_NOTIFY_NO_SENDERS %ld\n", Request->msgh_local_port); | ||||
| JackMachServerChannel* channel = JackMachServerChannel::fPortTable[Request->msgh_local_port]; | JackMachServerChannel* channel = JackMachServerChannel::fPortTable[Request->msgh_local_port]; | ||||
| assert(channel); | assert(channel); | ||||
| channel->KillClient(Request->msgh_local_port); | |||||
| channel->ClientKill(Request->msgh_local_port); | |||||
| } else { | } else { | ||||
| JackRPCEngine_server(Request, Reply); | JackRPCEngine_server(Request, Reply); | ||||
| } | } | ||||
| @@ -58,9 +58,10 @@ class JackMachServerChannel : public JackServerChannelInterface, public JackRunn | |||||
| JackEngine* GetEngine(); | JackEngine* GetEngine(); | ||||
| JackServer* GetServer(); | JackServer* GetServer(); | ||||
| void AddClient(char* name, mach_port_t* private_port, int* shared_engine, int* shared_client, int* shared_graph, int* result); | |||||
| void RemoveClient(mach_port_t private_port, int refnum); | |||||
| void KillClient(mach_port_t private_port); | |||||
| void ClientCheck(char* name, char* name_res, int options, int* status, int* result); | |||||
| void ClientOpen(char* name, mach_port_t* private_port, int* shared_engine, int* shared_client, int* shared_graph, int* result); | |||||
| void ClientClose(mach_port_t private_port, int refnum); | |||||
| void ClientKill(mach_port_t private_port); | |||||
| bool Execute(); | bool Execute(); | ||||
| @@ -447,7 +447,7 @@ | |||||
| 4B56881008B5C8620022B32D /* JackFifo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackFifo.h; path = ../common/JackFifo.h; sourceTree = SOURCE_ROOT; }; | 4B56881008B5C8620022B32D /* JackFifo.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackFifo.h; path = ../common/JackFifo.h; sourceTree = SOURCE_ROOT; }; | ||||
| 4B60CE480AAABA31004956AA /* connect.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = connect.c; path = "../example-clients/connect.c"; sourceTree = SOURCE_ROOT; }; | 4B60CE480AAABA31004956AA /* connect.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; name = connect.c; path = "../example-clients/connect.c"; sourceTree = SOURCE_ROOT; }; | ||||
| 4B66A8580934964500A89560 /* JackConstants.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackConstants.h; path = ../common/JackConstants.h; sourceTree = SOURCE_ROOT; }; | 4B66A8580934964500A89560 /* JackConstants.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = JackConstants.h; path = ../common/JackConstants.h; sourceTree = SOURCE_ROOT; }; | ||||
| 4B699BB1097D421600A18468 /* jackdmp */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = jackdmp; sourceTree = BUILT_PRODUCTS_DIR; }; | |||||
| 4B699BB1097D421600A18468 /* jackdmp */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jackdmp; sourceTree = BUILT_PRODUCTS_DIR; }; | |||||
| 4B699C47097D421600A18468 /* Jackmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | 4B699C47097D421600A18468 /* Jackmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | ||||
| 4B699CAC097D421600A18468 /* Jackdmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackdmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | 4B699CAC097D421600A18468 /* Jackdmp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Jackdmp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | ||||
| 4B699CBB097D421600A18468 /* jack_metro */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_metro; sourceTree = BUILT_PRODUCTS_DIR; }; | 4B699CBB097D421600A18468 /* jack_metro */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = jack_metro; sourceTree = BUILT_PRODUCTS_DIR; }; | ||||
| @@ -574,6 +574,7 @@ int main (int argc, char *argv[]) | |||||
| if (status & JackServerStarted) { | if (status & JackServerStarted) { | ||||
| fprintf(stderr, "JACK server started\n"); | fprintf(stderr, "JACK server started\n"); | ||||
| } | } | ||||
| /** | /** | ||||
| * try to register another one with the same name... | * try to register another one with the same name... | ||||
| * | * | ||||
| @@ -586,6 +587,19 @@ int main (int argc, char *argv[]) | |||||
| printf("!!! ERROR !!! Jackd server has accepted multiples client with the same name !"); | printf("!!! ERROR !!! Jackd server has accepted multiples client with the same name !"); | ||||
| jack_client_close(client2); | jack_client_close(client2); | ||||
| } | } | ||||
| /** | |||||
| * try to register another one with the same name using jack_client_open ==> since JackUseExactName is not used, an new client should be opened... | |||||
| * | |||||
| */ | |||||
| Log("trying to register a new jackd client with name %s using jack_client_open()...\n", client_name1); | |||||
| client2 = jack_client_open(client_name1, jack_options, &status, server_name); | |||||
| if (client2 != NULL) { | |||||
| Log ("valid : a second client with the same name can be registered (client automatic renaming)\n"); | |||||
| } else { | |||||
| printf("!!! ERROR !!! Jackd server automatic renaming feature does not work!"); | |||||
| jack_client_close(client2); | |||||
| } | |||||
| /** | /** | ||||
| * testing client name... | * testing client name... | ||||