git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4706 0c269be4-1314-0410-8aa9-9f06e86f4224tags/1.9.9.5
@@ -39,6 +39,7 @@ John Emmas | |||||
2012-01-19 Stephane Letz <letz@grame.fr> | 2012-01-19 Stephane Letz <letz@grame.fr> | ||||
* Implement shutdown for in server clients. | * Implement shutdown for in server clients. | ||||
* Better time-out management in NetJack2. | |||||
2012-01-13 Stephane Letz <letz@grame.fr> | 2012-01-13 Stephane Letz <letz@grame.fr> | ||||
@@ -344,7 +344,7 @@ void JackGraphManager::RecalculateLatency(jack_port_id_t port_index, jack_latenc | |||||
next_index = GetCurrentIndex(); | next_index = GetCurrentIndex(); | ||||
} while (cur_index != next_index); // Until a coherent state has been read | } 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 | // Server | ||||
@@ -54,6 +54,7 @@ namespace Jack | |||||
void JackNetInterface::Initialize() | void JackNetInterface::Initialize() | ||||
{ | { | ||||
fSetTimeOut = false; | |||||
fTxBuffer = NULL; | fTxBuffer = NULL; | ||||
fRxBuffer = NULL; | fRxBuffer = NULL; | ||||
fNetAudioCaptureBuffer = NULL; | fNetAudioCaptureBuffer = NULL; | ||||
@@ -244,6 +245,17 @@ namespace Jack | |||||
} | } | ||||
return NULL; | 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 ************************************************************************************ | // JackNetMasterInterface ************************************************************************************ | ||||
@@ -262,8 +274,9 @@ namespace Jack | |||||
} | } | ||||
// timeout on receive (for init) | // 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 | // connect | ||||
if (fSocket.Connect() == SOCKET_ERROR) { | if (fSocket.Connect() == SOCKET_ERROR) { | ||||
@@ -301,13 +314,6 @@ namespace Jack | |||||
return true; | return true; | ||||
} | } | ||||
int JackNetMasterInterface::SetRxTimeout() | |||||
{ | |||||
jack_log("JackNetMasterInterface::SetRxTimeout"); | |||||
float time = 3 * 1000000.f * (static_cast<float>(fParams.fPeriodSize) / static_cast<float>(fParams.fSampleRate)); | |||||
return fSocket.SetTimeOut(static_cast<int>(time)); | |||||
} | |||||
bool JackNetMasterInterface::SetParams() | bool JackNetMasterInterface::SetParams() | ||||
{ | { | ||||
jack_log("JackNetMasterInterface::SetParams audio in = %d audio out = %d MIDI in = %d MIDI out = %d", | 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 | // 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)); | jack_error("Can't set rx timeout : %s", StrError(NET_ERROR_CODE)); | ||||
goto error; | goto error; | ||||
} | } | ||||
@@ -468,6 +476,8 @@ namespace Jack | |||||
int JackNetMasterInterface::SyncSend() | int JackNetMasterInterface::SyncSend() | ||||
{ | { | ||||
SetRcvTimeOut(); | |||||
fTxHeader.fCycle++; | fTxHeader.fCycle++; | ||||
fTxHeader.fSubCycle = 0; | fTxHeader.fSubCycle = 0; | ||||
fTxHeader.fDataType = 's'; | 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 | // 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)); | jack_error("Can't disable multicast loop : %s", StrError(NET_ERROR_CODE)); | ||||
} | |||||
// send 'AVAILABLE' until 'SLAVE_SETUP' received | // send 'AVAILABLE' until 'SLAVE_SETUP' received | ||||
jack_info("Waiting for a master..."); | jack_info("Waiting for a master..."); | ||||
@@ -817,6 +829,14 @@ namespace Jack | |||||
jack_error("NetAudioBuffer allocation error..."); | jack_error("NetAudioBuffer allocation error..."); | ||||
return false; | 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 | // set the new buffer sizes | ||||
if (SetNetBufferSize() == SOCKET_ERROR) { | if (SetNetBufferSize() == SOCKET_ERROR) { | ||||
@@ -894,6 +914,7 @@ namespace Jack | |||||
{ | { | ||||
int rx_bytes = 0; | int rx_bytes = 0; | ||||
packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer); | packet_header_t* rx_head = reinterpret_cast<packet_header_t*>(fRxBuffer); | ||||
// receive sync (launch the cycle) | // receive sync (launch the cycle) | ||||
do { | do { | ||||
@@ -906,6 +927,8 @@ namespace Jack | |||||
while ((strcmp(rx_head->fPacketType, "header") != 0) && (rx_head->fDataType != 's')); | while ((strcmp(rx_head->fPacketType, "header") != 0) && (rx_head->fDataType != 's')); | ||||
fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; | fRxHeader.fIsLastPckt = rx_head->fIsLastPckt; | ||||
SetRcvTimeOut(); | |||||
return rx_bytes; | return rx_bytes; | ||||
} | } | ||||
@@ -32,9 +32,10 @@ namespace Jack | |||||
#define SLAVE_SETUP_RETRY 5 | #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 | #define NETWORK_MAX_LATENCY 20 | ||||
@@ -46,6 +47,8 @@ namespace Jack | |||||
{ | { | ||||
protected: | protected: | ||||
bool fSetTimeOut; | |||||
void Initialize(); | void Initialize(); | ||||
@@ -107,6 +110,8 @@ namespace Jack | |||||
int AudioRecv(packet_header_t* rx_head, NetAudioBuffer* buffer); | int AudioRecv(packet_header_t* rx_head, NetAudioBuffer* buffer); | ||||
int FinishRecv(NetAudioBuffer* buffer); | int FinishRecv(NetAudioBuffer* buffer); | ||||
void SetRcvTimeOut(); | |||||
NetAudioBuffer* AudioBufferFactory(int nports, char* buffer); | NetAudioBuffer* AudioBufferFactory(int nports, char* buffer); | ||||
@@ -136,7 +141,6 @@ namespace Jack | |||||
int fLastfCycleOffset; | int fLastfCycleOffset; | ||||
bool Init(); | bool Init(); | ||||
int SetRxTimeout(); | |||||
bool SetParams(); | bool SetParams(); | ||||
void Exit(); | void Exit(); | ||||
@@ -614,8 +614,10 @@ namespace Jack | |||||
{ | { | ||||
jack_log("JackNetMasterManager::~JackNetMasterManager"); | jack_log("JackNetMasterManager::~JackNetMasterManager"); | ||||
jack_info("Exiting NetManager..."); | 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; | master_list_t::iterator it; | ||||
for (it = fMasterList.begin(); it != fMasterList.end(); it++) { | for (it = fMasterList.begin(); it != fMasterList.end(); it++) { | ||||
delete(*it); | delete(*it); | ||||
@@ -646,7 +648,10 @@ namespace Jack | |||||
{ | { | ||||
jack_log("JackNetMasterManager::ShutDown"); | jack_log("JackNetMasterManager::ShutDown"); | ||||
JackNetMasterManager* manager = (JackNetMasterManager*)arg; | 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) | 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)) { | if (rx_bytes == sizeof(session_params_t)) { | ||||
switch (GetPacketType (&host_params)) | |||||
switch (GetPacketType(&host_params)) | |||||
{ | { | ||||
case SLAVE_AVAILABLE: | case SLAVE_AVAILABLE: | ||||
if ((net_master = InitMaster(host_params))) { | if ((net_master = InitMaster(host_params))) { | ||||
@@ -884,7 +889,7 @@ extern "C" | |||||
SERVER_EXPORT void jack_finish(void* arg) | SERVER_EXPORT void jack_finish(void* arg) | ||||
{ | { | ||||
if (master_manager) { | if (master_manager) { | ||||
jack_log ("Unloading Master Manager"); | |||||
jack_log("Unloading Master Manager"); | |||||
delete master_manager; | delete master_manager; | ||||
master_manager = NULL; | master_manager = NULL; | ||||
} | } | ||||
@@ -333,10 +333,6 @@ namespace Jack | |||||
int JackNetUnixSocket::SetTimeOut(int us) | int JackNetUnixSocket::SetTimeOut(int us) | ||||
{ | { | ||||
jack_log("JackNetUnixSocket::SetTimeout %d usecs", 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; | struct timeval timeout; | ||||
//less than 1sec | //less than 1sec | ||||
@@ -345,10 +341,10 @@ namespace Jack | |||||
timeout.tv_usec = us; | timeout.tv_usec = us; | ||||
} else { | } else { | ||||
//more than 1sec | //more than 1sec | ||||
float sec = static_cast<float>(us) / 1000000.f; | |||||
timeout.tv_sec =(int) sec; | |||||
float usec = (sec - static_cast<float>(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)); | return SetOption(SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); | ||||
} | } | ||||
@@ -296,12 +296,8 @@ namespace Jack | |||||
int JackNetWinSocket::SetTimeOut(int usec) | int JackNetWinSocket::SetTimeOut(int usec) | ||||
{ | { | ||||
jack_log("JackNetWinSocket::SetTimeout %d usec", 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********************************************************************************************************* | //local loop********************************************************************************************************* | ||||