different strategy for mutex in protocol class, fix for sending jitter buffer change message when no connection is established
This commit is contained in:
parent
736a7b043a
commit
a4610ef287
3 changed files with 145 additions and 121 deletions
|
@ -87,7 +87,14 @@ public:
|
|||
int GetSockBufSize() { return SockBuf.GetSize(); }
|
||||
|
||||
// network protocol interface
|
||||
void CreateJitBufMes ( const int iJitBufSize ) { Protocol.CreateJitBufMes ( iJitBufSize ); }
|
||||
void CreateJitBufMes ( const int iJitBufSize )
|
||||
{
|
||||
if ( IsConnected() )
|
||||
{
|
||||
Protocol.CreateJitBufMes ( iJitBufSize );
|
||||
}
|
||||
}
|
||||
|
||||
void CreateReqJitBufMes() { Protocol.CreateReqJitBufMes(); }
|
||||
|
||||
protected:
|
||||
|
|
|
@ -46,7 +46,8 @@ MESSAGES
|
|||
+--------------------------+
|
||||
|
||||
- Request jitter buffer size: PROTMESSID_REQ_JITT_BUF_SIZE
|
||||
no data
|
||||
|
||||
note: does not have any data -> n = 0
|
||||
|
||||
|
||||
|
||||
|
@ -95,8 +96,12 @@ void CProtocol::EnqueueMessage ( CVector<uint8_t>& vecMessage,
|
|||
// create send message object for the queue
|
||||
CSendMessage SendMessageObj ( vecMessage, iCnt, iID );
|
||||
|
||||
Mutex.lock();
|
||||
{
|
||||
// we want to have a FIFO: we add at the end and take from the beginning
|
||||
SendMessQueue.push_back ( SendMessageObj );
|
||||
}
|
||||
Mutex.unlock();
|
||||
|
||||
// if list was empty, initiate send process
|
||||
if ( bListWasEmpty )
|
||||
|
@ -107,12 +112,27 @@ void CProtocol::EnqueueMessage ( CVector<uint8_t>& vecMessage,
|
|||
|
||||
void CProtocol::SendMessage()
|
||||
{
|
||||
CVector<uint8_t> vecMessage;
|
||||
bool bSendMess = false;
|
||||
|
||||
Mutex.lock();
|
||||
{
|
||||
// we have to check that list is not empty, since in another thread the
|
||||
// last element of the list might have been erased
|
||||
if ( !SendMessQueue.empty() )
|
||||
{
|
||||
vecMessage.Init ( SendMessQueue.front().vecMessage.Size() );
|
||||
vecMessage = SendMessQueue.front().vecMessage;
|
||||
|
||||
bSendMess = true;
|
||||
}
|
||||
}
|
||||
Mutex.unlock();
|
||||
|
||||
if ( bSendMess )
|
||||
{
|
||||
// send message
|
||||
emit MessReadyForSending ( SendMessQueue.front().vecMessage );
|
||||
emit MessReadyForSending ( vecMessage );
|
||||
|
||||
// start time-out timer if not active
|
||||
if ( !TimerSendMess.isActive() )
|
||||
|
@ -144,27 +164,11 @@ void CProtocol::CreateAndSendAcknMess ( const int& iID, const int& iCnt )
|
|||
}
|
||||
|
||||
void CProtocol::DeleteSendMessQueue()
|
||||
{
|
||||
/*
|
||||
Actually, this function must be secured by a mutex, too. The problem is that
|
||||
this function is called from OnSendProtMessage in client which is called
|
||||
from a mutexed function of this object. In this case, we will get a dead
|
||||
lock.
|
||||
*/
|
||||
// delete complete "send message queue"
|
||||
SendMessQueue.clear();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
The following functions are access functions from different threads. These
|
||||
functions have to be secured by a mutex to avoid data corruption
|
||||
*/
|
||||
void CProtocol::OnTimerSendMess()
|
||||
{
|
||||
Mutex.lock();
|
||||
{
|
||||
SendMessage();
|
||||
// delete complete "send message queue"
|
||||
SendMessQueue.clear();
|
||||
}
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
@ -176,18 +180,16 @@ bool CProtocol::ParseMessage ( const CVector<unsigned char>& vecbyData,
|
|||
return code: true -> ok; false -> error
|
||||
*/
|
||||
bool bRet;
|
||||
|
||||
Mutex.lock();
|
||||
{
|
||||
int iRecCounter, iRecID, iData;
|
||||
unsigned int iPos;
|
||||
CVector<uint8_t> vecData;
|
||||
bool bSendNextMess;
|
||||
|
||||
|
||||
// convert unsigned char in uint8_t, TODO convert all buffers in uint8_t
|
||||
CVector<uint8_t> vecbyDataConv ( iNumBytes );
|
||||
for ( int i = 0; i < iNumBytes; i++ ) {
|
||||
vecbyDataConv[i] = static_cast<uint8_t> ( vecbyData[i] );
|
||||
vecbyDataConv[i] = static_cast<uint8_t> ( vecbyData[i] );
|
||||
}
|
||||
|
||||
|
||||
|
@ -218,6 +220,8 @@ for ( int i = 0; i < iNumBytes; i++ ) {
|
|||
iPos = 0;
|
||||
iData = static_cast<int> ( GetValFromStream ( vecData, iPos, 2 ) );
|
||||
|
||||
Mutex.lock();
|
||||
{
|
||||
// check if this is the correct acknowledgment
|
||||
if ( ( SendMessQueue.front().iCnt == iRecCounter ) &&
|
||||
( SendMessQueue.front().iID == iData ) )
|
||||
|
@ -226,6 +230,17 @@ for ( int i = 0; i < iNumBytes; i++ ) {
|
|||
SendMessQueue.pop_front();
|
||||
|
||||
// send next message in queue
|
||||
bSendNextMess = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bSendNextMess = false;
|
||||
}
|
||||
}
|
||||
Mutex.unlock();
|
||||
|
||||
if ( bSendNextMess )
|
||||
{
|
||||
SendMessage();
|
||||
}
|
||||
|
||||
|
@ -267,25 +282,26 @@ for ( int i = 0; i < iNumBytes; i++ ) {
|
|||
{
|
||||
bRet = false; // return error code
|
||||
}
|
||||
}
|
||||
Mutex.unlock();
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
void CProtocol::CreateJitBufMes ( const int iJitBufSize )
|
||||
{
|
||||
Mutex.lock();
|
||||
{
|
||||
CVector<uint8_t> vecNewMessage;
|
||||
CVector<uint8_t> vecData ( 2 ); // 2 bytes of data
|
||||
int iCurCounter;
|
||||
unsigned int iPos = 0; // init position pointer
|
||||
|
||||
Mutex.lock();
|
||||
{
|
||||
// store current counter value
|
||||
const int iCurCounter = iCounter;
|
||||
iCurCounter = iCounter;
|
||||
|
||||
// increase counter (wraps around automatically)
|
||||
iCounter++;
|
||||
}
|
||||
Mutex.unlock();
|
||||
|
||||
// build data vector
|
||||
PutValOnStream ( vecData, iPos, static_cast<uint32_t> ( iJitBufSize ), 2 );
|
||||
|
@ -295,29 +311,28 @@ void CProtocol::CreateJitBufMes ( const int iJitBufSize )
|
|||
|
||||
// enqueue message
|
||||
EnqueueMessage ( vecNewMessage, iCurCounter, PROTMESSID_JITT_BUF_SIZE );
|
||||
}
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
void CProtocol::CreateReqJitBufMes()
|
||||
{
|
||||
CVector<uint8_t> vecNewMessage;
|
||||
int iCurCounter;
|
||||
|
||||
Mutex.lock();
|
||||
{
|
||||
CVector<uint8_t> vecNewMessage;
|
||||
|
||||
// store current counter value
|
||||
const int iCurCounter = iCounter;
|
||||
iCurCounter = iCounter;
|
||||
|
||||
// increase counter (wraps around automatically)
|
||||
iCounter++;
|
||||
}
|
||||
Mutex.unlock();
|
||||
|
||||
// build complete message
|
||||
GenMessageFrame ( vecNewMessage, iCurCounter, PROTMESSID_REQ_JITT_BUF_SIZE, CVector<uint8_t> ( 0 ) );
|
||||
|
||||
// enqueue message
|
||||
EnqueueMessage ( vecNewMessage, iCurCounter, PROTMESSID_REQ_JITT_BUF_SIZE );
|
||||
}
|
||||
Mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -117,15 +117,17 @@ protected:
|
|||
|
||||
void SendMessage();
|
||||
|
||||
uint8_t iCounter;
|
||||
int iOldRecID, iOldRecCnt;
|
||||
|
||||
// these two objects must be sequred by a mutex
|
||||
uint8_t iCounter;
|
||||
std::list<CSendMessage> SendMessQueue;
|
||||
|
||||
QTimer TimerSendMess;
|
||||
QMutex Mutex;
|
||||
|
||||
public slots:
|
||||
void OnTimerSendMess();
|
||||
void OnTimerSendMess() { SendMessage(); }
|
||||
|
||||
signals:
|
||||
// transmitting
|
||||
|
|
Loading…
Reference in a new issue