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(); }
|
int GetSockBufSize() { return SockBuf.GetSize(); }
|
||||||
|
|
||||||
// network protocol interface
|
// 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(); }
|
void CreateReqJitBufMes() { Protocol.CreateReqJitBufMes(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
|
@ -46,7 +46,8 @@ MESSAGES
|
||||||
+--------------------------+
|
+--------------------------+
|
||||||
|
|
||||||
- Request jitter buffer size: PROTMESSID_REQ_JITT_BUF_SIZE
|
- 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
|
// create send message object for the queue
|
||||||
CSendMessage SendMessageObj ( vecMessage, iCnt, iID );
|
CSendMessage SendMessageObj ( vecMessage, iCnt, iID );
|
||||||
|
|
||||||
|
Mutex.lock();
|
||||||
|
{
|
||||||
// we want to have a FIFO: we add at the end and take from the beginning
|
// we want to have a FIFO: we add at the end and take from the beginning
|
||||||
SendMessQueue.push_back ( SendMessageObj );
|
SendMessQueue.push_back ( SendMessageObj );
|
||||||
|
}
|
||||||
|
Mutex.unlock();
|
||||||
|
|
||||||
// if list was empty, initiate send process
|
// if list was empty, initiate send process
|
||||||
if ( bListWasEmpty )
|
if ( bListWasEmpty )
|
||||||
|
@ -107,12 +112,27 @@ void CProtocol::EnqueueMessage ( CVector<uint8_t>& vecMessage,
|
||||||
|
|
||||||
void CProtocol::SendMessage()
|
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
|
// we have to check that list is not empty, since in another thread the
|
||||||
// last element of the list might have been erased
|
// last element of the list might have been erased
|
||||||
if ( !SendMessQueue.empty() )
|
if ( !SendMessQueue.empty() )
|
||||||
|
{
|
||||||
|
vecMessage.Init ( SendMessQueue.front().vecMessage.Size() );
|
||||||
|
vecMessage = SendMessQueue.front().vecMessage;
|
||||||
|
|
||||||
|
bSendMess = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Mutex.unlock();
|
||||||
|
|
||||||
|
if ( bSendMess )
|
||||||
{
|
{
|
||||||
// send message
|
// send message
|
||||||
emit MessReadyForSending ( SendMessQueue.front().vecMessage );
|
emit MessReadyForSending ( vecMessage );
|
||||||
|
|
||||||
// start time-out timer if not active
|
// start time-out timer if not active
|
||||||
if ( !TimerSendMess.isActive() )
|
if ( !TimerSendMess.isActive() )
|
||||||
|
@ -144,27 +164,11 @@ void CProtocol::CreateAndSendAcknMess ( const int& iID, const int& iCnt )
|
||||||
}
|
}
|
||||||
|
|
||||||
void CProtocol::DeleteSendMessQueue()
|
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();
|
Mutex.lock();
|
||||||
{
|
{
|
||||||
SendMessage();
|
// delete complete "send message queue"
|
||||||
|
SendMessQueue.clear();
|
||||||
}
|
}
|
||||||
Mutex.unlock();
|
Mutex.unlock();
|
||||||
}
|
}
|
||||||
|
@ -176,18 +180,16 @@ bool CProtocol::ParseMessage ( const CVector<unsigned char>& vecbyData,
|
||||||
return code: true -> ok; false -> error
|
return code: true -> ok; false -> error
|
||||||
*/
|
*/
|
||||||
bool bRet;
|
bool bRet;
|
||||||
|
|
||||||
Mutex.lock();
|
|
||||||
{
|
|
||||||
int iRecCounter, iRecID, iData;
|
int iRecCounter, iRecID, iData;
|
||||||
unsigned int iPos;
|
unsigned int iPos;
|
||||||
CVector<uint8_t> vecData;
|
CVector<uint8_t> vecData;
|
||||||
|
bool bSendNextMess;
|
||||||
|
|
||||||
|
|
||||||
// convert unsigned char in uint8_t, TODO convert all buffers in uint8_t
|
// convert unsigned char in uint8_t, TODO convert all buffers in uint8_t
|
||||||
CVector<uint8_t> vecbyDataConv ( iNumBytes );
|
CVector<uint8_t> vecbyDataConv ( iNumBytes );
|
||||||
for ( int i = 0; i < iNumBytes; i++ ) {
|
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;
|
iPos = 0;
|
||||||
iData = static_cast<int> ( GetValFromStream ( vecData, iPos, 2 ) );
|
iData = static_cast<int> ( GetValFromStream ( vecData, iPos, 2 ) );
|
||||||
|
|
||||||
|
Mutex.lock();
|
||||||
|
{
|
||||||
// check if this is the correct acknowledgment
|
// check if this is the correct acknowledgment
|
||||||
if ( ( SendMessQueue.front().iCnt == iRecCounter ) &&
|
if ( ( SendMessQueue.front().iCnt == iRecCounter ) &&
|
||||||
( SendMessQueue.front().iID == iData ) )
|
( SendMessQueue.front().iID == iData ) )
|
||||||
|
@ -226,6 +230,17 @@ for ( int i = 0; i < iNumBytes; i++ ) {
|
||||||
SendMessQueue.pop_front();
|
SendMessQueue.pop_front();
|
||||||
|
|
||||||
// send next message in queue
|
// send next message in queue
|
||||||
|
bSendNextMess = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bSendNextMess = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Mutex.unlock();
|
||||||
|
|
||||||
|
if ( bSendNextMess )
|
||||||
|
{
|
||||||
SendMessage();
|
SendMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,25 +282,26 @@ for ( int i = 0; i < iNumBytes; i++ ) {
|
||||||
{
|
{
|
||||||
bRet = false; // return error code
|
bRet = false; // return error code
|
||||||
}
|
}
|
||||||
}
|
|
||||||
Mutex.unlock();
|
|
||||||
|
|
||||||
return bRet;
|
return bRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CProtocol::CreateJitBufMes ( const int iJitBufSize )
|
void CProtocol::CreateJitBufMes ( const int iJitBufSize )
|
||||||
{
|
{
|
||||||
Mutex.lock();
|
|
||||||
{
|
|
||||||
CVector<uint8_t> vecNewMessage;
|
CVector<uint8_t> vecNewMessage;
|
||||||
CVector<uint8_t> vecData ( 2 ); // 2 bytes of data
|
CVector<uint8_t> vecData ( 2 ); // 2 bytes of data
|
||||||
|
int iCurCounter;
|
||||||
unsigned int iPos = 0; // init position pointer
|
unsigned int iPos = 0; // init position pointer
|
||||||
|
|
||||||
|
Mutex.lock();
|
||||||
|
{
|
||||||
// store current counter value
|
// store current counter value
|
||||||
const int iCurCounter = iCounter;
|
iCurCounter = iCounter;
|
||||||
|
|
||||||
// increase counter (wraps around automatically)
|
// increase counter (wraps around automatically)
|
||||||
iCounter++;
|
iCounter++;
|
||||||
|
}
|
||||||
|
Mutex.unlock();
|
||||||
|
|
||||||
// build data vector
|
// build data vector
|
||||||
PutValOnStream ( vecData, iPos, static_cast<uint32_t> ( iJitBufSize ), 2 );
|
PutValOnStream ( vecData, iPos, static_cast<uint32_t> ( iJitBufSize ), 2 );
|
||||||
|
@ -295,29 +311,28 @@ void CProtocol::CreateJitBufMes ( const int iJitBufSize )
|
||||||
|
|
||||||
// enqueue message
|
// enqueue message
|
||||||
EnqueueMessage ( vecNewMessage, iCurCounter, PROTMESSID_JITT_BUF_SIZE );
|
EnqueueMessage ( vecNewMessage, iCurCounter, PROTMESSID_JITT_BUF_SIZE );
|
||||||
}
|
|
||||||
Mutex.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CProtocol::CreateReqJitBufMes()
|
void CProtocol::CreateReqJitBufMes()
|
||||||
{
|
{
|
||||||
|
CVector<uint8_t> vecNewMessage;
|
||||||
|
int iCurCounter;
|
||||||
|
|
||||||
Mutex.lock();
|
Mutex.lock();
|
||||||
{
|
{
|
||||||
CVector<uint8_t> vecNewMessage;
|
|
||||||
|
|
||||||
// store current counter value
|
// store current counter value
|
||||||
const int iCurCounter = iCounter;
|
iCurCounter = iCounter;
|
||||||
|
|
||||||
// increase counter (wraps around automatically)
|
// increase counter (wraps around automatically)
|
||||||
iCounter++;
|
iCounter++;
|
||||||
|
}
|
||||||
|
Mutex.unlock();
|
||||||
|
|
||||||
// build complete message
|
// build complete message
|
||||||
GenMessageFrame ( vecNewMessage, iCurCounter, PROTMESSID_REQ_JITT_BUF_SIZE, CVector<uint8_t> ( 0 ) );
|
GenMessageFrame ( vecNewMessage, iCurCounter, PROTMESSID_REQ_JITT_BUF_SIZE, CVector<uint8_t> ( 0 ) );
|
||||||
|
|
||||||
// enqueue message
|
// enqueue message
|
||||||
EnqueueMessage ( vecNewMessage, iCurCounter, PROTMESSID_REQ_JITT_BUF_SIZE );
|
EnqueueMessage ( vecNewMessage, iCurCounter, PROTMESSID_REQ_JITT_BUF_SIZE );
|
||||||
}
|
|
||||||
Mutex.unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -117,15 +117,17 @@ protected:
|
||||||
|
|
||||||
void SendMessage();
|
void SendMessage();
|
||||||
|
|
||||||
uint8_t iCounter;
|
|
||||||
int iOldRecID, iOldRecCnt;
|
int iOldRecID, iOldRecCnt;
|
||||||
|
|
||||||
|
// these two objects must be sequred by a mutex
|
||||||
|
uint8_t iCounter;
|
||||||
std::list<CSendMessage> SendMessQueue;
|
std::list<CSendMessage> SendMessQueue;
|
||||||
|
|
||||||
QTimer TimerSendMess;
|
QTimer TimerSendMess;
|
||||||
QMutex Mutex;
|
QMutex Mutex;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void OnTimerSendMess();
|
void OnTimerSendMess() { SendMessage(); }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
// transmitting
|
// transmitting
|
||||||
|
|
Loading…
Reference in a new issue