connectivitylayer/isce/p2prouter_dll/src/msgqueue.cpp
author <dalarub>
Fri, 06 Nov 2009 17:28:23 +0000
changeset 0 63b37f68c1ce
permissions -rw-r--r--
First Contribution. Vanilla as it came from Nokia

/*
* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of the License "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
* 
* Description: 
*
*/



#include "msgqueue.h"           // For DMsgQueue
#include "p2proutertrace.h"     // For C_TRACE..

// Fault identifiers
enum TDMsgQueueFaults
    {
    EDMsgQueueMemAllocFail = 0x00,
    EDMsgQueueMemAllocFail2,
    EDMsgQueueInvalidQueueSize,
    EDMsgQueueNotEmpty,
    EDMsgQueueNotInSync,
    EDMsgQueueNotInSync2,
    EDMsgQueueNotInSync3,
    EDMsgQueueNotInSync4,
    EDMsgQueueNotInSync5,
    };

DMsgQueue::DMsgQueue(
        const TUint16 aSize
        )
    {

    C_TRACE( ( _T( "DMsgQueue::DMsgQueue 0x%x %d>" ), this, aSize ) );
    iQueueMutex = new NFastMutex();
    ASSERT_RESET_ALWAYS( iQueueMutex, ( EDMsgQueueMemAllocFail | EDMsgQueueTraceId << KClassIdentifierShift ) );
    iSize = aSize;
    ASSERT_RESET_ALWAYS( ( iSize > 0 ), ( EDMsgQueueInvalidQueueSize | EDMsgQueueTraceId << KClassIdentifierShift ) );
    iShInputIndex = 0;
    iShOutputIndex = 0;
    iShCount = 0;
    // Reserve memory for the buffer.
    iShRingBuffer = new TDes8*[ aSize ];
    C_TRACE( ( _T( "DMsgQueue::DMsgQueue 0x%x" ), iShRingBuffer ) );
    ASSERT_RESET_ALWAYS( iShRingBuffer, ( EDMsgQueueMemAllocFail2 | EDMsgQueueTraceId << KClassIdentifierShift ) );
    for( TInt i( 0 ); i < iSize; ++i )
        {
        iShRingBuffer[ i ] = NULL;
        }
    C_TRACE( ( _T( "DMsgQueue::DMsgQueue 0x%x<" ), this ) );

    }

DMsgQueue::~DMsgQueue(
        // None
        )
    {
    
    C_TRACE( ( _T( "DMsgQueue::~DMsgQueue 0x%x %d>" ), this, iShCount ) );
    ASSERT_RESET_ALWAYS( iShCount == 0, ( EDMsgQueueNotEmpty | EDMsgQueueTraceId << KClassIdentifierShift ) );
    // NOTE! This does not deallocate the blocks from the allocated memory just the pointers!
    for( TInt i( 0 ); i < iSize; ++i )
        {
        TDes8* temp = iShRingBuffer[ i ];
        if( temp )
            {
            C_TRACE( ( _T( "DMsgQueue::~DMsgQueue ptr 0x%x" ), temp ) );
            delete temp;
            temp = NULL;
            }
        }
    if( iShRingBuffer )
        {
        C_TRACE( ( _T( "DMsgQueue::~DMsgQueue iShRingBuffer 0x%x iShRingBuffer[0] 0x%x" ), iShRingBuffer, iShRingBuffer[0] ) );
        delete [] iShRingBuffer;
        iShRingBuffer = NULL;
        }

    iSize = 0;
    iShInputIndex = 0;
    iShOutputIndex = 0;
    iShCount = 0;

    C_TRACE( ( _T( "DMsgQueue::~DMsgQueue iQueueMutex" ) ) );
    // Only modified in constructor if allocated failed, already reseted.
    delete iQueueMutex;
    iQueueMutex = NULL;
    C_TRACE( ( _T( "DMsgQueue::~DMsgQueue 0x%x<" ), this ) );

    }

void DMsgQueue::Add(
        const TDesC8& aMessage
        )
    {

    C_TRACE( ( _T( "DMsgQueue::Add 0x%x %d %d %d %d 0x%x>" ), this, iSize, iShCount, iShInputIndex, iShOutputIndex, &aMessage ) );
    NKern::FMWait( iQueueMutex );
    // If queue get's overfilled throw kernel fault.
    ASSERT_RESET_ALWAYS( ( iShCount < iSize ), ( EDMsgQueueNotInSync | EDMsgQueueTraceId << KClassIdentifierShift ) );
    // Place the buffer into the queue.
    iShRingBuffer[ iShInputIndex ] = static_cast<TDes8*>( &const_cast<TDesC8&>( aMessage ) );
    // Adjust input pointer.
    iShInputIndex = ( ( iShInputIndex + 1 ) % iSize );
    // Remember the amount of the requests in the queue.
    iShCount++;
    NKern::FMSignal( iQueueMutex );
    C_TRACE( ( _T( "DMsgQueue::Add 0x%x %d %d %d %d 0x%x<" ), this, iSize, iShCount, iShInputIndex, iShOutputIndex, &aMessage ) );

    }

TUint16 DMsgQueue::Count(
        // None
        )
    {

    C_TRACE( ( _T( "DMsgQueue::Count 0x%x %d>" ), this, iShCount ) );
    TUint16 count( KErrNone );
    NKern::FMWait( iQueueMutex );
    // If count is too big.
    ASSERT_RESET_ALWAYS( ( iShCount <= iSize ), ( EDMsgQueueNotInSync2 | EDMsgQueueTraceId << KClassIdentifierShift ) );
    count = iShCount;
    NKern::FMSignal( iQueueMutex );
    C_TRACE( ( _T( "DMsgQueue::Count 0x%x %d %d<" ), this, iShCount, count ) );
    return count;

    }

TDes8& DMsgQueue::Get(
        // None
        )
    {

    C_TRACE( ( _T( "DMsgQueue::Get 0x%x %d %d %d %d>" ), this, iSize, iShCount, iShInputIndex, iShOutputIndex ) );
    NKern::FMWait( iQueueMutex );
    // If queue is empty.
    ASSERT_RESET_ALWAYS( ( iShCount > 0 ), ( EDMsgQueueNotInSync3 | EDMsgQueueTraceId << KClassIdentifierShift ) );
    // Get the buffer from the queue.
    TDes8* temp = iShRingBuffer[ iShOutputIndex ];
    // Set buffer location to NULL.
    iShRingBuffer[ iShOutputIndex ] = NULL;
    // Adjust output pointer.
    iShOutputIndex = ( ( iShOutputIndex + 1 ) % iSize );
    // Remember the amount of the requests in the queue.
    iShCount--;
    NKern::FMSignal( iQueueMutex );
    ASSERT_RESET_ALWAYS( temp, ( EDMsgQueueNotInSync4 | EDMsgQueueTraceId << KClassIdentifierShift ) );
    C_TRACE( ( _T( "DMsgQueue::Get 0x%x %d %d %d %d 0x%x<" ), this, iSize, iShCount, iShInputIndex, iShOutputIndex, temp ) );
    return *temp;

    }

void DMsgQueue::RollBack(
        const TDesC8& aMsgToRoll
        )
    {

    C_TRACE( ( _T( "DMsgQueue::RollBack 0x%x %d %d %d %d 0x%x>" ), this, iSize, iShCount, iShInputIndex, iShOutputIndex, &aMsgToRoll ) );
    NKern::FMWait( iQueueMutex );
    ASSERT_RESET_ALWAYS( ( iShCount < iSize ), ( EDMsgQueueNotInSync5 | EDMsgQueueTraceId << KClassIdentifierShift ) );
    // If needs to rollback from 0 to iSize -1 index.
    iShOutputIndex = ( iShOutputIndex == 0 ) ? iSize : iShOutputIndex; 
    // Adjust output pointer.
    iShOutputIndex = ( ( iShOutputIndex - 1 ) % iSize );
    // Get the descriptor from queue where the rollback is made.
    iShRingBuffer[ iShOutputIndex ] = static_cast<TDes8*>( &const_cast<TDesC8&>( aMsgToRoll ) );
    // Remember the amount of the requests in the queue.
    iShCount++;    
    NKern::FMSignal( iQueueMutex );
    C_TRACE( ( _T( "DMsgQueue::RollBack 0x%x %d %d %d %d 0x%x<" ), this, iSize, iShCount, iShInputIndex, iShOutputIndex, &aMsgToRoll ) );

    }

// End of file.