From f11b32159bfec42ed25c60102301d51eed2e081d Mon Sep 17 00:00:00 2001 From: sletz Date: Thu, 19 Jan 2012 14:17:16 +0000 Subject: [PATCH] Better time-out management in NetJack2. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4706 0c269be4-1314-0410-8aa9-9f06e86f4224 --- ChangeLog | 1 + common/JackGraphManager.cpp | 2 +- common/JackNetInterface.cpp | 51 ++++++++++++++++++++++++++---------- common/JackNetInterface.h | 12 ++++++--- common/JackNetManager.cpp | 15 +++++++---- posix/JackNetUnixSocket.cpp | 12 +++------ windows/JackNetWinSocket.cpp | 8 ++---- 7 files changed, 63 insertions(+), 38 deletions(-) diff --git a/ChangeLog b/ChangeLog index ad9c9f3c..6b227b05 100644 --- a/ChangeLog +++ b/ChangeLog @@ -39,6 +39,7 @@ John Emmas 2012-01-19 Stephane Letz * Implement shutdown for in server clients. + * Better time-out management in NetJack2. 2012-01-13 Stephane Letz diff --git a/common/JackGraphManager.cpp b/common/JackGraphManager.cpp index 16688e4b..f89acf17 100644 --- a/common/JackGraphManager.cpp +++ b/common/JackGraphManager.cpp @@ -344,7 +344,7 @@ void JackGraphManager::RecalculateLatency(jack_port_id_t port_index, jack_latenc next_index = GetCurrentIndex(); } while (cur_index != next_index); // Until a coherent state has been read - jack_log("JackGraphManager::RecalculateLatency port_index = %ld", port_index); + //jack_log("JackGraphManager::RecalculateLatency port_index = %ld", port_index); } // Server diff --git a/common/JackNetInterface.cpp b/common/JackNetInterface.cpp index 6f819e64..6b21d457 100644 --- a/common/JackNetInterface.cpp +++ b/common/JackNetInterface.cpp @@ -54,6 +54,7 @@ namespace Jack void JackNetInterface::Initialize() { + fSetTimeOut = false; fTxBuffer = NULL; fRxBuffer = NULL; fNetAudioCaptureBuffer = NULL; @@ -244,6 +245,17 @@ namespace Jack } return NULL; } + + void JackNetInterface::SetRcvTimeOut() + { + if (!fSetTimeOut) { + if (fSocket.SetTimeOut(PACKET_TIMEOUT) == SOCKET_ERROR) { + jack_error("Can't set rx timeout : %s", StrError(NET_ERROR_CODE)); + return; + } + fSetTimeOut = true; + } + } // JackNetMasterInterface ************************************************************************************ @@ -262,8 +274,9 @@ namespace Jack } // timeout on receive (for init) - if (fSocket.SetTimeOut(MASTER_INIT_TIMEOUT) < 0) - jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE)); + if (fSocket.SetTimeOut(MASTER_INIT_TIMEOUT) < 0) { + jack_error("Can't set init timeout : %s", StrError(NET_ERROR_CODE)); + } // connect if (fSocket.Connect() == SOCKET_ERROR) { @@ -301,13 +314,6 @@ namespace Jack return true; } - int JackNetMasterInterface::SetRxTimeout() - { - jack_log("JackNetMasterInterface::SetRxTimeout"); - float time = 3 * 1000000.f * (static_cast(fParams.fPeriodSize) / static_cast(fParams.fSampleRate)); - return fSocket.SetTimeOut(static_cast(time)); - } - bool JackNetMasterInterface::SetParams() { jack_log("JackNetMasterInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d", @@ -349,8 +355,10 @@ namespace Jack } // set the new timeout for the socket + //float time = 3 * 1000000.f * (float(fParams.fPeriodSize) / float(fParams.fSampleRate)); + /* - if (SetRxTimeout() == SOCKET_ERROR) { + if (fSocket.SetTimeOut(PACKET_TIMEOUT) == SOCKET_ERROR) { jack_error("Can't set rx timeout : %s", StrError(NET_ERROR_CODE)); goto error; } @@ -468,6 +476,8 @@ namespace Jack int JackNetMasterInterface::SyncSend() { + SetRcvTimeOut(); + fTxHeader.fCycle++; fTxHeader.fSubCycle = 0; fTxHeader.fDataType = 's'; @@ -718,13 +728,15 @@ namespace Jack } } - // timeout on receive - if (fSocket.SetTimeOut(SLAVE_INIT_TIMEOUT) == SOCKET_ERROR) - jack_error("Can't set timeout : %s", StrError(NET_ERROR_CODE)); + // timeout on receive (for init) + if (fSocket.SetTimeOut(SLAVE_INIT_TIMEOUT) == SOCKET_ERROR) { + jack_error("Can't set init timeout : %s", StrError(NET_ERROR_CODE)); + } // disable local loop - if (fSocket.SetLocalLoop() == SOCKET_ERROR) + if (fSocket.SetLocalLoop() == SOCKET_ERROR) { jack_error("Can't disable multicast loop : %s", StrError(NET_ERROR_CODE)); + } // send 'AVAILABLE' until 'SLAVE_SETUP' received jack_info("Waiting for a master..."); @@ -817,6 +829,14 @@ namespace Jack jack_error("NetAudioBuffer allocation error..."); return false; } + + /* + if (fSocket.SetTimeOut(PACKET_TIMEOUT) == SOCKET_ERROR) { + jack_error("Can't set rx timeout : %s", StrError(NET_ERROR_CODE)); + goto error; + } + */ + // set the new buffer sizes if (SetNetBufferSize() == SOCKET_ERROR) { @@ -894,6 +914,7 @@ namespace Jack { int rx_bytes = 0; packet_header_t* rx_head = reinterpret_cast(fRxBuffer); + // receive sync (launch the cycle) do { @@ -906,6 +927,8 @@ namespace Jack while ((strcmp(rx_head->fPacketType, "header") != 0) && (rx_head->fDataType != 's')); fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; + + SetRcvTimeOut(); return rx_bytes; } diff --git a/common/JackNetInterface.h b/common/JackNetInterface.h index b42f72c9..c40e737a 100644 --- a/common/JackNetInterface.h +++ b/common/JackNetInterface.h @@ -32,9 +32,10 @@ namespace Jack #define SLAVE_SETUP_RETRY 5 -#define MANAGER_INIT_TIMEOUT 2000000 // in usec -#define MASTER_INIT_TIMEOUT 1000000 // in usec -#define SLAVE_INIT_TIMEOUT 1000000 // in usec +#define MANAGER_INIT_TIMEOUT 2000000 // in usec +#define MASTER_INIT_TIMEOUT 1000000 * 10 // in usec +#define SLAVE_INIT_TIMEOUT 1000000 * 10 // in usec +#define PACKET_TIMEOUT 500000 // in usec #define NETWORK_MAX_LATENCY 20 @@ -46,6 +47,8 @@ namespace Jack { protected: + + bool fSetTimeOut; void Initialize(); @@ -107,6 +110,8 @@ namespace Jack int AudioRecv(packet_header_t* rx_head, NetAudioBuffer* buffer); int FinishRecv(NetAudioBuffer* buffer); + + void SetRcvTimeOut(); NetAudioBuffer* AudioBufferFactory(int nports, char* buffer); @@ -136,7 +141,6 @@ namespace Jack int fLastfCycleOffset; bool Init(); - int SetRxTimeout(); bool SetParams(); void Exit(); diff --git a/common/JackNetManager.cpp b/common/JackNetManager.cpp index 379649a2..a3cb6e0a 100644 --- a/common/JackNetManager.cpp +++ b/common/JackNetManager.cpp @@ -614,8 +614,10 @@ namespace Jack { jack_log("JackNetMasterManager::~JackNetMasterManager"); jack_info("Exiting NetManager..."); - fRunning = false; - //jack_client_kill_thread(fClient, fThread); + if (fRunning) { + jack_client_kill_thread(fClient, fThread); + fRunning = false; + } master_list_t::iterator it; for (it = fMasterList.begin(); it != fMasterList.end(); it++) { delete(*it); @@ -646,7 +648,10 @@ namespace Jack { jack_log("JackNetMasterManager::ShutDown"); JackNetMasterManager* manager = (JackNetMasterManager*)arg; - jack_client_kill_thread(manager->fClient, manager->fThread); + if (manager->fRunning) { + jack_client_kill_thread(manager->fClient, manager->fThread); + manager->fRunning = false; + } } int JackNetMasterManager::SetSyncCallback(jack_transport_state_t state, jack_position_t* pos, void* arg) @@ -737,7 +742,7 @@ namespace Jack } if (rx_bytes == sizeof(session_params_t)) { - switch (GetPacketType (&host_params)) + switch (GetPacketType(&host_params)) { case SLAVE_AVAILABLE: if ((net_master = InitMaster(host_params))) { @@ -884,7 +889,7 @@ extern "C" SERVER_EXPORT void jack_finish(void* arg) { if (master_manager) { - jack_log ("Unloading Master Manager"); + jack_log("Unloading Master Manager"); delete master_manager; master_manager = NULL; } diff --git a/posix/JackNetUnixSocket.cpp b/posix/JackNetUnixSocket.cpp index d97fba8a..f4a1b942 100644 --- a/posix/JackNetUnixSocket.cpp +++ b/posix/JackNetUnixSocket.cpp @@ -333,10 +333,6 @@ namespace Jack int JackNetUnixSocket::SetTimeOut(int us) { jack_log("JackNetUnixSocket::SetTimeout %d usecs", us); - - //negative timeout, or exceding 10s, return - if ((us < 0) ||(us > 10000000)) - return SOCKET_ERROR; struct timeval timeout; //less than 1sec @@ -345,10 +341,10 @@ namespace Jack timeout.tv_usec = us; } else { //more than 1sec - float sec = static_cast(us) / 1000000.f; - timeout.tv_sec =(int) sec; - float usec = (sec - static_cast(timeout.tv_sec)) * 1000000; - timeout.tv_usec =(int) usec; + float sec = float(us) / 1000000.f; + timeout.tv_sec = (int)sec; + float usec = (sec - float(timeout.tv_sec)) * 1000000; + timeout.tv_usec =(int)usec; } return SetOption(SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); } diff --git a/windows/JackNetWinSocket.cpp b/windows/JackNetWinSocket.cpp index 912df24e..de7580c2 100644 --- a/windows/JackNetWinSocket.cpp +++ b/windows/JackNetWinSocket.cpp @@ -296,12 +296,8 @@ namespace Jack int JackNetWinSocket::SetTimeOut(int usec) { jack_log("JackNetWinSocket::SetTimeout %d usec", usec); - - //negative timeout, or exceeding 10s, return - if (( usec < 0) || (usec > 10000000)) - return SOCKET_ERROR; - int time = usec / 1000; - return SetOption(SOL_SOCKET, SO_RCVTIMEO, &time, sizeof(time)); + int millisec = usec / 1000; + return SetOption(SOL_SOCKET, SO_RCVTIMEO, &millisec, sizeof(millisec)); } //local loop*********************************************************************************************************