From df0ec35d050343d3af03425181ab820d985e4c18 Mon Sep 17 00:00:00 2001 From: Volker Fischer Date: Fri, 31 Jul 2020 19:21:31 +0200 Subject: [PATCH] added more mutex in the server (may fix #480) --- ChangeLog | 2 + src/server.cpp | 133 +++++++++++++++++++++++++------------------------ src/server.h | 4 +- 3 files changed, 70 insertions(+), 69 deletions(-) diff --git a/ChangeLog b/ChangeLog index cccb8a54..ebaad6f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,8 @@ - support MIDI control faders in headless build (#483) +- added more mutex in the server (may fix #480) + - bug fix: --showallservers ping column sort is alphabetic (#201) diff --git a/src/server.cpp b/src/server.cpp index 188d0093..fe9b50a8 100755 --- a/src/server.cpp +++ b/src/server.cpp @@ -599,6 +599,8 @@ void CServer::SendProtMessage ( int iChID, CVector vecMessage ) void CServer::OnNewConnection ( int iChID, CHostAddress RecHostAddr ) { + QMutexLocker locker ( &Mutex ); + // inform the client about its own ID at the server (note that this // must be the first message to be sent for a new connection) vecChannels[iChID].CreateClientIDMes ( iChID ); @@ -669,6 +671,8 @@ void CServer::OnNewConnection ( int iChID, void CServer::OnServerFull ( CHostAddress RecHostAddr ) { + // note: no mutex required here + // inform the calling client that no channel is free ConnLessProtocol.CreateCLServerFullMes ( RecHostAddr ); } @@ -681,16 +685,6 @@ void CServer::OnSendCLProtMessage ( CHostAddress InetAddr, Socket.SendPacket ( vecMessage, InetAddr ); } -void CServer::OnProtcolCLMessageReceived ( int iRecID, - CVector vecbyMesBodyData, - CHostAddress RecHostAddr ) -{ - // connection less messages are always processed - ConnLessProtocol.ParseConnectionLessMessageBody ( vecbyMesBodyData, - iRecID, - RecHostAddr ); -} - void CServer::OnCLDisconnection ( CHostAddress InetAddr ) { // check if the given address is actually a client which is connected to @@ -743,7 +737,6 @@ void CServer::OnHandledSignal ( int sigNum ) #else switch ( sigNum ) { - case SIGUSR1: RequestNewRecording(); break; @@ -1442,26 +1435,36 @@ int CServer::FindChannel ( const CHostAddress& CheckAddr ) return INVALID_CHANNEL_ID; } +void CServer::OnProtcolCLMessageReceived ( int iRecID, + CVector vecbyMesBodyData, + CHostAddress RecHostAddr ) +{ + QMutexLocker locker ( &Mutex ); + + // connection less messages are always processed + ConnLessProtocol.ParseConnectionLessMessageBody ( vecbyMesBodyData, + iRecID, + RecHostAddr ); +} + void CServer::OnProtcolMessageReceived ( int iRecCounter, int iRecID, CVector vecbyMesBodyData, CHostAddress RecHostAddr ) { - Mutex.lock(); - { - // find the channel with the received address - const int iCurChanID = FindChannel ( RecHostAddr ); + QMutexLocker locker ( &Mutex ); - // if the channel exists, apply the protocol message to the channel - if ( iCurChanID != INVALID_CHANNEL_ID ) - { - vecChannels[iCurChanID].PutProtcolData ( iRecCounter, - iRecID, - vecbyMesBodyData, - RecHostAddr ); - } + // find the channel with the received address + const int iCurChanID = FindChannel ( RecHostAddr ); + + // if the channel exists, apply the protocol message to the channel + if ( iCurChanID != INVALID_CHANNEL_ID ) + { + vecChannels[iCurChanID].PutProtcolData ( iRecCounter, + iRecID, + vecbyMesBodyData, + RecHostAddr ); } - Mutex.unlock(); } bool CServer::PutAudioData ( const CVector& vecbyRecBuf, @@ -1469,62 +1472,60 @@ bool CServer::PutAudioData ( const CVector& vecbyRecBuf, const CHostAddress& HostAdr, int& iCurChanID ) { + QMutexLocker locker ( &Mutex ); + bool bNewConnection = false; // init return value bool bChanOK = true; // init with ok, might be overwritten - Mutex.lock(); + // Get channel ID ------------------------------------------------------ + // check address + iCurChanID = FindChannel ( HostAdr ); + + if ( iCurChanID == INVALID_CHANNEL_ID ) { - // Get channel ID ------------------------------------------------------ - // check address - iCurChanID = FindChannel ( HostAdr ); + // a new client is calling, look for free channel + iCurChanID = GetFreeChan(); - if ( iCurChanID == INVALID_CHANNEL_ID ) + if ( iCurChanID != INVALID_CHANNEL_ID ) { - // a new client is calling, look for free channel - iCurChanID = GetFreeChan(); + // initialize current channel by storing the calling host + // address + vecChannels[iCurChanID].SetAddress ( HostAdr ); - if ( iCurChanID != INVALID_CHANNEL_ID ) + // reset channel info + vecChannels[iCurChanID].ResetInfo(); + + // reset the channel gains of current channel, at the same + // time reset gains of this channel ID for all other channels + for ( int i = 0; i < iMaxNumChannels; i++ ) { - // initialize current channel by storing the calling host - // address - vecChannels[iCurChanID].SetAddress ( HostAdr ); + vecChannels[iCurChanID].SetGain ( i, 1.0 ); - // reset channel info - vecChannels[iCurChanID].ResetInfo(); - - // reset the channel gains of current channel, at the same - // time reset gains of this channel ID for all other channels - for ( int i = 0; i < iMaxNumChannels; i++ ) - { - vecChannels[iCurChanID].SetGain ( i, 1.0 ); - - // other channels (we do not distinguish the case if - // i == iCurChanID for simplicity) - vecChannels[i].SetGain ( iCurChanID, 1.0 ); - } - } - else - { - // no free channel available - bChanOK = false; + // other channels (we do not distinguish the case if + // i == iCurChanID for simplicity) + vecChannels[i].SetGain ( iCurChanID, 1.0 ); } } - - - // Put received audio data in jitter buffer ---------------------------- - if ( bChanOK ) + else { - // put packet in socket buffer - if ( vecChannels[iCurChanID].PutAudioData ( vecbyRecBuf, - iNumBytesRead, - HostAdr ) == PS_NEW_CONNECTION ) - { - // in case we have a new connection return this information - bNewConnection = true; - } + // no free channel available + bChanOK = false; + } + } + + + // Put received audio data in jitter buffer ---------------------------- + if ( bChanOK ) + { + // put packet in socket buffer + if ( vecChannels[iCurChanID].PutAudioData ( vecbyRecBuf, + iNumBytesRead, + HostAdr ) == PS_NEW_CONNECTION ) + { + // in case we have a new connection return this information + bNewConnection = true; } } - Mutex.unlock(); // return the state if a new connection was happening return bNewConnection; diff --git a/src/server.h b/src/server.h index 37c0b21c..2b75cf78 100755 --- a/src/server.h +++ b/src/server.h @@ -458,10 +458,8 @@ public slots: void OnCLReqVersionAndOS ( CHostAddress InetAddr ) { ConnLessProtocol.CreateCLVersionAndOSMes ( InetAddr ); } - // the CreateChannelList() function access vecChannels which as to be mutexed - // since the normal server thread my change that at a random time void OnCLReqConnClientsList ( CHostAddress InetAddr ) - { QMutexLocker locker ( &Mutex ); ConnLessProtocol.CreateCLConnClientsListMes ( InetAddr, CreateChannelList() ); } + { ConnLessProtocol.CreateCLConnClientsListMes ( InetAddr, CreateChannelList() ); } void OnCLRegisterServerReceived ( CHostAddress InetAddr, CHostAddress LInetAddr,