From 3a64d55ac43023be68a1387c63ffa5a4fe989087 Mon Sep 17 00:00:00 2001 From: sletz Date: Sat, 27 Jan 2007 11:56:21 +0000 Subject: [PATCH] Restructure activation/deactivation code git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@1370 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackEngine.cpp | 35 ++++++++++++++++---------- common/JackGraphManager.cpp | 40 +++++++++++++++++++++++++++++- common/JackGraphManager.h | 3 +++ common/JackInternalClient.cpp | 9 +++---- common/JackInternalClientChannel.h | 6 +++-- common/JackServer.cpp | 34 +++++++++++++++++-------- common/JackServer.h | 4 +-- common/JackSocketServerChannel.cpp | 6 +++-- common/Jackdmp.cpp | 2 +- common/types.h | 3 --- macosx/JackMacEngineRPC.cpp | 6 +++-- 11 files changed, 106 insertions(+), 42 deletions(-) diff --git a/common/JackEngine.cpp b/common/JackEngine.cpp index ac64e49e..b1cc791d 100644 --- a/common/JackEngine.cpp +++ b/common/JackEngine.cpp @@ -137,7 +137,7 @@ bool JackEngine::Process(jack_time_t callback_usecs) { bool res = true; - // Transport + // Transport begin fEngineControl->CycleBegin(callback_usecs); // Timing @@ -162,7 +162,7 @@ bool JackEngine::Process(jack_time_t callback_usecs) } } - // Transport + // Transport end fEngineControl->CycleEnd(fClientTable); return res; } @@ -257,8 +257,9 @@ void JackEngine::NotifyClient(int refnum, int event, int sync, int value) { JackClientInterface* client = fClientTable[refnum]; // 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 { 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++) { JackClientInterface* old_client = fClientTable[i]; 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) { - NotifyClient(refnum, JackNotifyChannelInterface::kActivateClient, false, 0); + NotifyClient(refnum, JackNotifyChannelInterface::kActivateClient, true, 0); } //------------------- @@ -513,8 +518,10 @@ int JackEngine::ClientActivate(int refnum) assert(fClientTable[refnum]); JackLog("JackEngine::ClientActivate ref = %ld name = %s\n", refnum, client->GetClientControl()->fName); + fGraphManager->Activate(refnum); + // 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); return -1; } else { @@ -530,10 +537,12 @@ int JackEngine::ClientDeactivate(int refnum) if (client == NULL) 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 - 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); return -1; } else { diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index a807292d..7124d134 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -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 { AssertPort(port_index); @@ -221,6 +222,7 @@ int JackGraphManager::RequestMonitor(jack_port_id_t port_index, bool onoff) // C 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) { 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; } +// Server jack_nframes_t JackGraphManager::GetTotalLatency(jack_port_id_t port_index) { UInt16 cur_index; @@ -293,6 +296,7 @@ jack_port_id_t JackGraphManager::AllocatePort(int refnum, const char* port_name, } else { res = manager->AddInputPort(refnum, port_index); } + // Insertion failure if (res < 0) { JackPort* port = GetPort(port_index); assert(port); @@ -417,6 +421,38 @@ int JackGraphManager::DisconnectAll(jack_port_id_t port_index) 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 int JackGraphManager::GetInputRefNum(jack_port_id_t port_index) { @@ -633,12 +669,14 @@ void JackGraphManager::GetConnectionsAux(JackConnectionManager* manager, const c res[i] = NULL; } -// Client + /* 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 read to loop forever. */ + +// Client const char** JackGraphManager::GetConnections(jack_port_id_t port_index) { const char** res = (const char**)malloc(sizeof(char*) * (CONNECTION_NUM + 1)); diff --git a/common/JackGraphManager.h b/common/JackGraphManager.h index 8057af87..646e0267 100644 --- a/common/JackGraphManager.h +++ b/common/JackGraphManager.h @@ -88,6 +88,9 @@ class JackGraphManager : public JackShmMem, public JackAtomicState - namespace Jack { diff --git a/common/JackInternalClientChannel.h b/common/JackInternalClientChannel.h index 64123068..1000ca8f 100644 --- a/common/JackInternalClientChannel.h +++ b/common/JackInternalClientChannel.h @@ -54,11 +54,13 @@ class JackInternalClientChannel : public JackClientChannelInterface } void ClientActivate(int refnum, int* result) { - *result = fServer->Activate(refnum); + //*result = fServer->Activate(refnum); + *result = fEngine->ClientActivate(refnum); } 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) diff --git a/common/JackServer.cpp b/common/JackServer.cpp index 22f6f9bb..a41b6f6a 100644 --- a/common/JackServer.cpp +++ b/common/JackServer.cpp @@ -188,11 +188,11 @@ int JackServer::Stop() return fAudioDriver->Stop(); } +/* 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); } @@ -201,18 +201,17 @@ int JackServer::Activate(int refnum) int JackServer::Deactivate(int refnum) { int res = fEngine->ClientDeactivate(refnum); - int fw_refnum = fFreewheelDriver->GetClientControl()->fRefNum; - + // 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 { JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum); } // 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 { JackLog("JackServer::Deactivate: client = %ld was not activated \n", refnum); } @@ -220,6 +219,17 @@ int JackServer::Deactivate(int refnum) 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) { JackLog("JackServer::SetBufferSize nframes = %ld\n", buffer_size); @@ -305,8 +315,10 @@ void JackServer::Notify(int refnum, int notify, int value) case JackNotifyChannelInterface::kDeadClient: 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); break; } diff --git a/common/JackServer.h b/common/JackServer.h index 7c4ce030..d6becc85 100644 --- a/common/JackServer.h +++ b/common/JackServer.h @@ -72,8 +72,8 @@ class EXPORT JackServer int Start(); 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 SetFreewheel(bool onoff); diff --git a/common/JackSocketServerChannel.cpp b/common/JackSocketServerChannel.cpp index 5fc60747..85d38da3 100644 --- a/common/JackSocketServerChannel.cpp +++ b/common/JackSocketServerChannel.cpp @@ -176,7 +176,8 @@ int JackSocketServerChannel::HandleRequest(int fd) JackResult res; JackLog("JackRequest::ActivateClient\n"); 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); break; } @@ -186,7 +187,8 @@ int JackSocketServerChannel::HandleRequest(int fd) JackDeactivateRequest req; JackResult res; 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); break; } diff --git a/common/Jackdmp.cpp b/common/Jackdmp.cpp index fc7c6604..3630b810 100644 --- a/common/Jackdmp.cpp +++ b/common/Jackdmp.cpp @@ -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); if (res < 0) { - jack_error("Cannot start server... exit\n"); + jack_error("Cannot start server... exit"); JackDelete(); return 0; } diff --git a/common/types.h b/common/types.h index ec294348..bbc18589 100644 --- a/common/types.h +++ b/common/types.h @@ -55,9 +55,6 @@ typedef uint32_t jack_nframes_t; #ifdef WIN32 typedef int64_t jack_time_t; -//typedef double jack_time_t; -//typedef uint64_t jack_time_t; - #else typedef uint64_t jack_time_t; #endif diff --git a/macosx/JackMacEngineRPC.cpp b/macosx/JackMacEngineRPC.cpp index be789917..2e415df2 100644 --- a/macosx/JackMacEngineRPC.cpp +++ b/macosx/JackMacEngineRPC.cpp @@ -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"); JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; assert(channel); - *result = channel->GetServer()->Activate(refnum); + //*result = channel->GetServer()->Activate(refnum); + *result = channel->GetEngine()->ClientActivate(refnum); 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"); JackMachServerChannel* channel = JackMachServerChannel::fPortTable[private_port]; assert(channel); - *result = channel->GetServer()->Deactivate(refnum); + //*result = channel->GetServer()->Deactivate(refnum); + *result = channel->GetEngine()->ClientDeactivate(refnum); return KERN_SUCCESS; }