git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@1370 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.62
| @@ -137,7 +137,7 @@ bool JackEngine::Process(jack_time_t callback_usecs) | |||||
| { | { | ||||
| bool res = true; | bool res = true; | ||||
| // Transport | |||||
| // Transport begin | |||||
| fEngineControl->CycleBegin(callback_usecs); | fEngineControl->CycleBegin(callback_usecs); | ||||
| // Timing | // Timing | ||||
| @@ -162,7 +162,7 @@ bool JackEngine::Process(jack_time_t callback_usecs) | |||||
| } | } | ||||
| } | } | ||||
| // Transport | |||||
| // Transport end | |||||
| fEngineControl->CycleEnd(fClientTable); | fEngineControl->CycleEnd(fClientTable); | ||||
| return res; | return res; | ||||
| } | } | ||||
| @@ -257,8 +257,9 @@ void JackEngine::NotifyClient(int refnum, int event, int sync, int value) | |||||
| { | { | ||||
| JackClientInterface* client = fClientTable[refnum]; | JackClientInterface* client = fClientTable[refnum]; | ||||
| // The client may be notified by the RT thread while closing | // The client may be notified by the RT thread while closing | ||||
| if (client && (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, value) < 0)) { | |||||
| jack_error("NotifyClient fails name = %s event = %ld = val = %ld", client->GetClientControl()->fName, event, value); | |||||
| if (client) { | |||||
| if (client->ClientNotify(refnum, client->GetClientControl()->fName, event, sync, value) < 0) | |||||
| jack_error("NotifyClient fails name = %s event = %ld = val = %ld", client->GetClientControl()->fName, event, value); | |||||
| } else { | } else { | ||||
| JackLog("JackEngine::NotifyClient: client not available anymore\n"); | JackLog("JackEngine::NotifyClient: client not available anymore\n"); | ||||
| } | } | ||||
| @@ -280,10 +281,14 @@ int JackEngine::NotifyAddClient(JackClientInterface* new_client, const char* nam | |||||
| for (int i = 0; i < CLIENT_NUM; i++) { | for (int i = 0; i < CLIENT_NUM; i++) { | ||||
| JackClientInterface* old_client = fClientTable[i]; | JackClientInterface* old_client = fClientTable[i]; | ||||
| if (old_client) { | if (old_client) { | ||||
| if (old_client->ClientNotify(refnum, name, JackNotifyChannelInterface::kAddClient, true, 0) < 0) | |||||
| return -1; | |||||
| if (new_client->ClientNotify(i, old_client->GetClientControl()->fName, JackNotifyChannelInterface::kAddClient, true, 0) < 0) | |||||
| return -1; | |||||
| if (old_client->ClientNotify(refnum, name, JackNotifyChannelInterface::kAddClient, true, 0) < 0) { | |||||
| jack_error("NotifyAddClient old_client fails name = %s", old_client->GetClientControl()->fName); | |||||
| return -1; | |||||
| } | |||||
| if (new_client->ClientNotify(i, old_client->GetClientControl()->fName, JackNotifyChannelInterface::kAddClient, true, 0) < 0) { | |||||
| jack_error("NotifyAddClient new_client fails name = %s", name); | |||||
| return -1; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -341,7 +346,7 @@ void JackEngine::NotifyPortRegistation(jack_port_id_t port_index, bool onoff) | |||||
| void JackEngine::NotifyActivate(int refnum) | void JackEngine::NotifyActivate(int refnum) | ||||
| { | { | ||||
| NotifyClient(refnum, JackNotifyChannelInterface::kActivateClient, false, 0); | |||||
| NotifyClient(refnum, JackNotifyChannelInterface::kActivateClient, true, 0); | |||||
| } | } | ||||
| //------------------- | //------------------- | ||||
| @@ -513,8 +518,10 @@ int JackEngine::ClientActivate(int refnum) | |||||
| assert(fClientTable[refnum]); | assert(fClientTable[refnum]); | ||||
| JackLog("JackEngine::ClientActivate ref = %ld name = %s\n", refnum, client->GetClientControl()->fName); | JackLog("JackEngine::ClientActivate ref = %ld name = %s\n", refnum, client->GetClientControl()->fName); | ||||
| fGraphManager->Activate(refnum); | |||||
| // Wait for graph state change to be effective | // Wait for graph state change to be effective | ||||
| if (!fSignal->TimedWait(fEngineControl->fPeriodUsecs * 10)) { | |||||
| if (!fSignal->TimedWait(fEngineControl->fTimeOutUsecs * 10)) { | |||||
| jack_error("JackEngine::ClientActivate wait error ref = %ld name = %s", refnum, client->GetClientControl()->fName); | jack_error("JackEngine::ClientActivate wait error ref = %ld name = %s", refnum, client->GetClientControl()->fName); | ||||
| return -1; | return -1; | ||||
| } else { | } else { | ||||
| @@ -530,10 +537,12 @@ int JackEngine::ClientDeactivate(int refnum) | |||||
| if (client == NULL) | if (client == NULL) | ||||
| return -1; | return -1; | ||||
| JackLog("JackEngine::ClientDeactivate ref = %ld name = %s\n", refnum, client->GetClientControl()->fName); | |||||
| fGraphManager->DisconnectAllPorts(refnum); | |||||
| JackLog("JackEngine::ClientDeactivate ref = %ld name = %s\n", refnum, client->GetClientControl()->fName); | |||||
| fGraphManager->Deactivate(refnum); | |||||
| fLastSwitchUsecs = 0; // Force switch will occur next cycle, even when called with "dead" clients | |||||
| // Wait for graph state change to be effective | // Wait for graph state change to be effective | ||||
| if (!fSignal->TimedWait(fEngineControl->fPeriodUsecs * 10)) { | |||||
| if (!fSignal->TimedWait(fEngineControl->fTimeOutUsecs * 10)) { | |||||
| jack_error("JackEngine::ClientDeactivate wait error ref = %ld name = %s", refnum, client->GetClientControl()->fName); | jack_error("JackEngine::ClientDeactivate wait error ref = %ld name = %s", refnum, client->GetClientControl()->fName); | ||||
| return -1; | return -1; | ||||
| } else { | } else { | ||||
| @@ -193,6 +193,7 @@ void* JackGraphManager::GetBuffer(jack_port_id_t port_index, jack_nframes_t buff | |||||
| } | } | ||||
| } | } | ||||
| // Server | |||||
| int JackGraphManager::RequestMonitor(jack_port_id_t port_index, bool onoff) // Client | int JackGraphManager::RequestMonitor(jack_port_id_t port_index, bool onoff) // Client | ||||
| { | { | ||||
| AssertPort(port_index); | AssertPort(port_index); | ||||
| @@ -221,6 +222,7 @@ int JackGraphManager::RequestMonitor(jack_port_id_t port_index, bool onoff) // C | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| // Server | |||||
| jack_nframes_t JackGraphManager::GetTotalLatencyAux(jack_port_id_t port_index, jack_port_id_t src_port_index, JackConnectionManager* manager, int hop_count) | jack_nframes_t JackGraphManager::GetTotalLatencyAux(jack_port_id_t port_index, jack_port_id_t src_port_index, JackConnectionManager* manager, int hop_count) | ||||
| { | { | ||||
| const jack_int_t* connections = manager->GetConnections(port_index); | const jack_int_t* connections = manager->GetConnections(port_index); | ||||
| @@ -245,6 +247,7 @@ jack_nframes_t JackGraphManager::GetTotalLatencyAux(jack_port_id_t port_index, j | |||||
| return max_latency + latency; | return max_latency + latency; | ||||
| } | } | ||||
| // Server | |||||
| jack_nframes_t JackGraphManager::GetTotalLatency(jack_port_id_t port_index) | jack_nframes_t JackGraphManager::GetTotalLatency(jack_port_id_t port_index) | ||||
| { | { | ||||
| UInt16 cur_index; | UInt16 cur_index; | ||||
| @@ -293,6 +296,7 @@ jack_port_id_t JackGraphManager::AllocatePort(int refnum, const char* port_name, | |||||
| } else { | } else { | ||||
| res = manager->AddInputPort(refnum, port_index); | res = manager->AddInputPort(refnum, port_index); | ||||
| } | } | ||||
| // Insertion failure | |||||
| if (res < 0) { | if (res < 0) { | ||||
| JackPort* port = GetPort(port_index); | JackPort* port = GetPort(port_index); | ||||
| assert(port); | assert(port); | ||||
| @@ -417,6 +421,38 @@ int JackGraphManager::DisconnectAll(jack_port_id_t port_index) | |||||
| return 0; | return 0; | ||||
| } | } | ||||
| // Server | |||||
| void JackGraphManager::Activate(int refnum) | |||||
| { | |||||
| DirectConnect(FREEWHEEL_DRIVER_REFNUM, refnum); | |||||
| DirectConnect(refnum, FREEWHEEL_DRIVER_REFNUM); | |||||
| } | |||||
| /* | |||||
| Disconnection from the FW must be done in last otherwise an intermediate "unconnected" | |||||
| (thus unactivated) state may happen where the client is still checked for its end. | |||||
| */ | |||||
| // Server | |||||
| void JackGraphManager::Deactivate(int refnum) | |||||
| { | |||||
| DisconnectAllPorts(refnum); | |||||
| // Disconnect only when needed | |||||
| if (IsDirectConnection(refnum, FREEWHEEL_DRIVER_REFNUM)) { | |||||
| DirectDisconnect(refnum, FREEWHEEL_DRIVER_REFNUM); | |||||
| } else { | |||||
| JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum); | |||||
| } | |||||
| // Disconnect only when needed | |||||
| if (IsDirectConnection(FREEWHEEL_DRIVER_REFNUM, refnum)) { | |||||
| DirectDisconnect(FREEWHEEL_DRIVER_REFNUM, refnum); | |||||
| } else { | |||||
| JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum); | |||||
| } | |||||
| } | |||||
| // Server | // Server | ||||
| int JackGraphManager::GetInputRefNum(jack_port_id_t port_index) | int JackGraphManager::GetInputRefNum(jack_port_id_t port_index) | ||||
| { | { | ||||
| @@ -633,12 +669,14 @@ void JackGraphManager::GetConnectionsAux(JackConnectionManager* manager, const c | |||||
| res[i] = NULL; | res[i] = NULL; | ||||
| } | } | ||||
| // Client | |||||
| /* | /* | ||||
| Use the state returned by ReadCurrentState and check that the state was not changed during the read operation. | Use the state returned by ReadCurrentState and check that the state was not changed during the read operation. | ||||
| The operation is lock-free since there is no intermediate state in the write operation that could cause the | The operation is lock-free since there is no intermediate state in the write operation that could cause the | ||||
| read to loop forever. | read to loop forever. | ||||
| */ | */ | ||||
| // Client | |||||
| const char** JackGraphManager::GetConnections(jack_port_id_t port_index) | const char** JackGraphManager::GetConnections(jack_port_id_t port_index) | ||||
| { | { | ||||
| const char** res = (const char**)malloc(sizeof(char*) * (CONNECTION_NUM + 1)); | const char** res = (const char**)malloc(sizeof(char*) * (CONNECTION_NUM + 1)); | ||||
| @@ -88,6 +88,9 @@ class JackGraphManager : public JackShmMem, public JackAtomicState<JackConnectio | |||||
| int RemovePort(int refnum, jack_port_id_t port_index); | int RemovePort(int refnum, jack_port_id_t port_index); | ||||
| void RemoveAllPorts(int refnum); | void RemoveAllPorts(int refnum); | ||||
| void DisconnectAllPorts(int refnum); | void DisconnectAllPorts(int refnum); | ||||
| void Activate(int refnum); | |||||
| void Deactivate(int refnum); | |||||
| int GetInputRefNum(jack_port_id_t port_index); | int GetInputRefNum(jack_port_id_t port_index); | ||||
| int GetOutputRefNum(jack_port_id_t port_index); | int GetOutputRefNum(jack_port_id_t port_index); | ||||
| @@ -17,10 +17,10 @@ along with this program; if not, write to the Free Software | |||||
| Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||||
| */ | */ | ||||
| #ifdef WIN32 | |||||
| #pragma warning (disable : 4786) | |||||
| #endif | |||||
| #ifdef WIN32 | |||||
| #pragma warning (disable : 4786) | |||||
| #endif | |||||
| #include "JackInternalClient.h" | #include "JackInternalClient.h" | ||||
| #include "JackEngine.h" | #include "JackEngine.h" | ||||
| @@ -31,7 +31,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
| #include "JackInternalClientChannel.h" | #include "JackInternalClientChannel.h" | ||||
| #include <assert.h> | #include <assert.h> | ||||
| namespace Jack | namespace Jack | ||||
| { | { | ||||
| @@ -54,11 +54,13 @@ class JackInternalClientChannel : public JackClientChannelInterface | |||||
| } | } | ||||
| void ClientActivate(int refnum, int* result) | void ClientActivate(int refnum, int* result) | ||||
| { | { | ||||
| *result = fServer->Activate(refnum); | |||||
| //*result = fServer->Activate(refnum); | |||||
| *result = fEngine->ClientActivate(refnum); | |||||
| } | } | ||||
| void ClientDeactivate(int refnum, int* result) | void ClientDeactivate(int refnum, int* result) | ||||
| { | { | ||||
| *result = fServer->Deactivate(refnum); | |||||
| //*result = fServer->Deactivate(refnum); | |||||
| *result = fEngine->ClientDeactivate(refnum); | |||||
| } | } | ||||
| void PortRegister(int refnum, const char* name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) | void PortRegister(int refnum, const char* name, unsigned int flags, unsigned int buffer_size, jack_port_id_t* port_index, int* result) | ||||
| @@ -188,11 +188,11 @@ int JackServer::Stop() | |||||
| return fAudioDriver->Stop(); | return fAudioDriver->Stop(); | ||||
| } | } | ||||
| /* | |||||
| int JackServer::Activate(int refnum) | int JackServer::Activate(int refnum) | ||||
| { | { | ||||
| int fw_refnum = fFreewheelDriver->GetClientControl()->fRefNum; | |||||
| fGraphManager->DirectConnect(fw_refnum, refnum); | |||||
| fGraphManager->DirectConnect(refnum, fw_refnum); | |||||
| fGraphManager->DirectConnect(FREEWHEEL_DRIVER_REFNUM, refnum); | |||||
| fGraphManager->DirectConnect(refnum, FREEWHEEL_DRIVER_REFNUM); | |||||
| return fEngine->ClientActivate(refnum); | return fEngine->ClientActivate(refnum); | ||||
| } | } | ||||
| @@ -201,18 +201,17 @@ int JackServer::Activate(int refnum) | |||||
| int JackServer::Deactivate(int refnum) | int JackServer::Deactivate(int refnum) | ||||
| { | { | ||||
| int res = fEngine->ClientDeactivate(refnum); | int res = fEngine->ClientDeactivate(refnum); | ||||
| int fw_refnum = fFreewheelDriver->GetClientControl()->fRefNum; | |||||
| // Disconnect only when needed | // Disconnect only when needed | ||||
| if (fGraphManager->IsDirectConnection(refnum, fw_refnum)) { | |||||
| fGraphManager->DirectDisconnect(refnum, fw_refnum); | |||||
| if (fGraphManager->IsDirectConnection(refnum, FREEWHEEL_DRIVER_REFNUM)) { | |||||
| fGraphManager->DirectDisconnect(refnum, FREEWHEEL_DRIVER_REFNUM); | |||||
| } else { | } else { | ||||
| JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum); | JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum); | ||||
| } | } | ||||
| // Disconnect only when needed | // Disconnect only when needed | ||||
| if (fGraphManager->IsDirectConnection(fw_refnum, refnum)) { | |||||
| fGraphManager->DirectDisconnect(fw_refnum, refnum); | |||||
| if (fGraphManager->IsDirectConnection(FREEWHEEL_DRIVER_REFNUM, refnum)) { | |||||
| fGraphManager->DirectDisconnect(FREEWHEEL_DRIVER_REFNUM, refnum); | |||||
| } else { | } else { | ||||
| JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum); | JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum); | ||||
| } | } | ||||
| @@ -220,6 +219,17 @@ int JackServer::Deactivate(int refnum) | |||||
| return res; | return res; | ||||
| } | } | ||||
| int JackServer::Activate(int refnum) | |||||
| { | |||||
| return fEngine->ClientActivate(refnum); | |||||
| } | |||||
| int JackServer::Deactivate(int refnum) | |||||
| { | |||||
| return fEngine->ClientDeactivate(refnum); | |||||
| } | |||||
| */ | |||||
| int JackServer::SetBufferSize(jack_nframes_t buffer_size) | int JackServer::SetBufferSize(jack_nframes_t buffer_size) | ||||
| { | { | ||||
| JackLog("JackServer::SetBufferSize nframes = %ld\n", buffer_size); | JackLog("JackServer::SetBufferSize nframes = %ld\n", buffer_size); | ||||
| @@ -305,8 +315,10 @@ void JackServer::Notify(int refnum, int notify, int value) | |||||
| case JackNotifyChannelInterface::kDeadClient: | case JackNotifyChannelInterface::kDeadClient: | ||||
| JackLog("JackServer: kDeadClient ref = %ld\n", refnum); | JackLog("JackServer: kDeadClient ref = %ld\n", refnum); | ||||
| if (Deactivate(refnum) < 0) | |||||
| jack_error("JackServer: DeadClient ref = %ld cannot be removed from the graph !!\n", refnum); | |||||
| //if (Deactivate(refnum) < 0) | |||||
| // jack_error("JackServer: DeadClient ref = %ld cannot be removed from the graph !!", refnum); | |||||
| if (fEngine->ClientDeactivate(refnum) < 0) | |||||
| jack_error("JackServer: DeadClient ref = %ld cannot be removed from the graph !!", refnum); | |||||
| fEngine->ClientClose(refnum); | fEngine->ClientClose(refnum); | ||||
| break; | break; | ||||
| } | } | ||||
| @@ -72,8 +72,8 @@ class EXPORT JackServer | |||||
| int Start(); | int Start(); | ||||
| int Stop(); | int Stop(); | ||||
| int Activate(int refnum); | |||||
| int Deactivate(int refnum); | |||||
| //int Activate(int refnum); | |||||
| //int Deactivate(int refnum); | |||||
| int SetBufferSize(jack_nframes_t buffer_size); | int SetBufferSize(jack_nframes_t buffer_size); | ||||
| int SetFreewheel(bool onoff); | int SetFreewheel(bool onoff); | ||||
| @@ -176,7 +176,8 @@ int JackSocketServerChannel::HandleRequest(int fd) | |||||
| JackResult res; | JackResult res; | ||||
| JackLog("JackRequest::ActivateClient\n"); | JackLog("JackRequest::ActivateClient\n"); | ||||
| if (req.Read(socket) == 0) | if (req.Read(socket) == 0) | ||||
| res.fResult = fServer->Activate(req.fRefNum); | |||||
| //res.fResult = fServer->Activate(req.fRefNum); | |||||
| res.fResult = fServer->GetEngine()->ClientActivate(req.fRefNum); | |||||
| res.Write(socket); | res.Write(socket); | ||||
| break; | break; | ||||
| } | } | ||||
| @@ -186,7 +187,8 @@ int JackSocketServerChannel::HandleRequest(int fd) | |||||
| JackDeactivateRequest req; | JackDeactivateRequest req; | ||||
| JackResult res; | JackResult res; | ||||
| if (req.Read(socket) == 0) | if (req.Read(socket) == 0) | ||||
| res.fResult = fServer->Deactivate(req.fRefNum); | |||||
| //res.fResult = fServer->Deactivate(req.fRefNum); | |||||
| res.fResult = fServer->GetEngine()->ClientDeactivate(req.fRefNum); | |||||
| res.Write(socket); | res.Write(socket); | ||||
| break; | break; | ||||
| } | } | ||||
| @@ -547,7 +547,7 @@ int main(int argc, char* argv[]) | |||||
| int res = JackStart(sample_sate, buffer_size, chan_in, chan_out, name, audiodevice, sync, timeout, rt); | int res = JackStart(sample_sate, buffer_size, chan_in, chan_out, name, audiodevice, sync, timeout, rt); | ||||
| if (res < 0) { | if (res < 0) { | ||||
| jack_error("Cannot start server... exit\n"); | |||||
| jack_error("Cannot start server... exit"); | |||||
| JackDelete(); | JackDelete(); | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| @@ -55,9 +55,6 @@ typedef uint32_t jack_nframes_t; | |||||
| #ifdef WIN32 | #ifdef WIN32 | ||||
| typedef int64_t jack_time_t; | typedef int64_t jack_time_t; | ||||
| //typedef double jack_time_t; | |||||
| //typedef uint64_t jack_time_t; | |||||
| #else | #else | ||||
| typedef uint64_t jack_time_t; | typedef uint64_t jack_time_t; | ||||
| #endif | #endif | ||||
| @@ -55,7 +55,8 @@ rpc_type server_rpc_jack_client_activate(mach_port_t private_port, int refnum, i | |||||
| JackLog("rpc_jack_client_activate\n"); | JackLog("rpc_jack_client_activate\n"); | ||||
| JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; | JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; | ||||
| assert(channel); | assert(channel); | ||||
| *result = channel->GetServer()->Activate(refnum); | |||||
| //*result = channel->GetServer()->Activate(refnum); | |||||
| *result = channel->GetEngine()->ClientActivate(refnum); | |||||
| return KERN_SUCCESS; | return KERN_SUCCESS; | ||||
| } | } | ||||
| @@ -64,7 +65,8 @@ rpc_type server_rpc_jack_client_deactivate(mach_port_t private_port, int refnum, | |||||
| JackLog("rpc_jack_client_deactivate\n"); | JackLog("rpc_jack_client_deactivate\n"); | ||||
| JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; | JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; | ||||
| assert(channel); | assert(channel); | ||||
| *result = channel->GetServer()->Deactivate(refnum); | |||||
| //*result = channel->GetServer()->Deactivate(refnum); | |||||
| *result = channel->GetEngine()->ClientDeactivate(refnum); | |||||
| return KERN_SUCCESS; | return KERN_SUCCESS; | ||||
| } | } | ||||