different strategy for mutex in protocol class, fix for sending jitter buffer change message when no connection is established

This commit is contained in:
Volker Fischer 2006-03-08 18:44:21 +00:00
parent 736a7b043a
commit a4610ef287
3 changed files with 145 additions and 121 deletions

View file

@ -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:

View file

@ -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();
}

View file

@ -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