videoscheduler/SchedulerServer/src/CCseSchedulerPluginStarter.cpp
author Pat Downey <patd@symbian.org>
Wed, 01 Sep 2010 12:20:37 +0100
branchRCL_3
changeset 23 13a33d82ad98
parent 0 822a42b6c3f1
permissions -rw-r--r--
Revert incorrect RCL_3 drop: Revision: 201029 Kit: 201035

/*
* Copyright (c) 2006 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:    Plugin starter, this is run in separate thread from engine*
*/





// INCLUDE FILES
#include "CCseSchedulerPluginStarter.h"
#include "CseDebug.h"                           // Debug macros
#include <ipvideo/CCseScheduledProgram.h>   // Represent one schedule in database
#include <ipvideo/CCseSchedulerPluginIF.h>
#include "CCseSchedulerThreadPacket.h"
#include "CCseSemaphoreController.h"

// EXTERNAL DATA STRUCTURES
// None.

// EXTERNAL FUNCTION PROTOTYPES  
// None.

// CONSTANTS
// None

// MACROS
// None.

// LOCAL CONSTANTS AND MACROS
// None

// MODULE DATA STRUCTURES
// None.

// LOCAL FUNCTION PROTOTYPES
// None.


// ============================ MEMBER FUNCTIONS ===============================

// -----------------------------------------------------------------------------
// CCseSchedulerPluginStarter::CCseSchedulerPluginStarter
// C++ default constructor can NOT contain any code, that might leave.
// -----------------------------------------------------------------------------
//
CCseSchedulerPluginStarter::CCseSchedulerPluginStarter ( CCseSchedulerThreadPacket* aThreadPacket ) :                                
                                iThreadPacket( aThreadPacket ),
                                iPluginRdyToTakedown( EFalse )
    {
    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerPluginStarter::CCseSchedulerPluginStarter");
        
    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerPluginStarter::CCseSchedulerPluginStarter");
    }

// -----------------------------------------------------------------------------
// CCseSchedulerPluginStarter::NewL
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CCseSchedulerPluginStarter* CCseSchedulerPluginStarter::NewL( CCseSchedulerThreadPacket* aThreadPacket )
    {
    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerPluginStarter::NewL");
    
    CCseSchedulerPluginStarter* self = new( ELeave ) CCseSchedulerPluginStarter( aThreadPacket );
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop( self );
    
    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerPluginStarter::NewL");
    return self;
    }

// -----------------------------------------------------------------------------
// CCseSchedulerPluginStarter::ConstructL
// Symbian 2nd phase constructor can leave.
// -----------------------------------------------------------------------------
//
void CCseSchedulerPluginStarter::ConstructL()
    {
    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerPluginStarter::ConstructL");
    
    iCompletitionBreaker = CIdle::NewL( CActive::EPriorityLow );
    // Start completition breaker. This time we do not inform about completition of
    // plugin but we break call chain and start running plugin from RunL
    iCompletitionBreaker->Start(TCallBack( PluginCompleteCallback, this ));
    
    iSemaphoreMonitor = CCseSemaphoreController::NewL( iThreadPacket->ShutdownSemaphore(),
                                                       *this );
           
	CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerPluginStarter::ConstructL");
    }

// -----------------------------------------------------------------------------
// CCseSchedulerEngineBackdoorClient::~CCseSchedulerPluginStarter
// Destructor.
// -----------------------------------------------------------------------------
//
CCseSchedulerPluginStarter::~CCseSchedulerPluginStarter()
    {
    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerPluginStarter::~CCseSchedulerPluginStarter");

    delete iCompletitionBreaker;    
    delete iPlugin;
    iPlugin = NULL;
    REComSession::FinalClose();
        
    delete iSemaphoreMonitor;    
    iSemaphoreMonitor = NULL;
        
    // We DO NOT destroy thread packet, we just null the pointer.
    // Information is still needed on other side after thread dies
    iThreadPacket = NULL;
    		
    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerPluginStarter::~CCseSchedulerPluginStarter");
    }

// -----------------------------------------------------------------------------
// CCseSchedulerPluginStarter::StartThread
//
// -----------------------------------------------------------------------------
//
TInt CCseSchedulerPluginStarter::StartThread( TAny* aParam )
    {
    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerPluginStarter::RunPlugin");
    
    TInt err( KErrNone );
    
    //create cleanupstack
    CTrapCleanup* cleanup = CTrapCleanup::New(); // get clean-up stack
    if (!cleanup)
        {
        err = KErrNoMemory;
        }
    if (!err)
        {
        TRAP(err, DoStartThreadL( aParam ));
        }
    delete cleanup;

    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerPluginStarter::RunPlugin");
    return err;	
    }
    
// -----------------------------------------------------------------------------
// CCseSchedulerPluginStarter::DoStartThreadL
//
// -----------------------------------------------------------------------------
//
void CCseSchedulerPluginStarter::DoStartThreadL( TAny* aParam )
    {
    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerPluginStarter::DoStartThreadL");
    
    CCseSchedulerThreadPacket* threadPacket = static_cast<CCseSchedulerThreadPacket*>(aParam);
    
    CActiveScheduler* scheduler = new ( ELeave ) CActiveScheduler;
    
    // If schedule doesn't exist there is really nothing we can do
    if( scheduler )
        {            
        CleanupStack::PushL( scheduler );          //   |->1
        CActiveScheduler::Install( scheduler );

        // Create the starter
        CCseSchedulerPluginStarter* starter = CCseSchedulerPluginStarter::NewL( threadPacket );
        CleanupStack::PushL(starter);              //   |->2
            
        // Ready to run
        CActiveScheduler::Start();
        
        CSELOGSTRING_HIGH_LEVEL("CCseSchedulerPluginStarter::DoStartThreadL - Out from CActiveScheduler::Start!");
        
        // Cleanup the server and scheduler
        CleanupStack::PopAndDestroy( starter );   // 2<-|
        CleanupStack::PopAndDestroy( scheduler ); // 1<-|
        
        threadPacket->ShutdownCompleteSemaphore().Signal();  
        }
    else
        {
        CSELOGSTRING_HIGH_LEVEL("CCseSchedulerPluginStarter::DoStartThreadL - No schedule available, GTFO");
        }
        
	CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerPluginStarter::DoStartThreadL");
    }
    
// -----------------------------------------------------------------------------
// CCseSchedulerPluginStarter::RunPluginL
//
// -----------------------------------------------------------------------------
//
void CCseSchedulerPluginStarter::RunPluginL( )
	{	
	CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerPluginStarter::RunPluginL");
    
    // Create plugin
    TUid pluginUid = TUid::Uid( iThreadPacket->Schedule()->PluginUid() );
    
    iPlugin = CCseSchedulerPluginIF::NewL( pluginUid );

    iPlugin->RunTaskL( *iThreadPacket->Schedule(), this );

    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerPluginStarter::RunPluginL");
	}

// -----------------------------------------------------------------------------
// CCseSchedulerPluginStarter::PluginCompleted
//
// -----------------------------------------------------------------------------
//
void CCseSchedulerPluginStarter::PluginCompleted( TInt aCompletitionCode )
	{	
	CSELOGSTRING2_HIGH_LEVEL(
	    ">>>CCseSchedulerPluginStarter::PluginCompleted - Code: %d", aCompletitionCode);
	
    // Start taking down The Thread    
    // Start Completition breaker if not already active to break call chain.
    // Set plugin completition value
    iThreadPacket->SetResultCode( aCompletitionCode );

    iPluginRdyToTakedown = ETrue;
    
    if( !iCompletitionBreaker->IsActive() )
        {                    
        iCompletitionBreaker->Start(TCallBack( PluginCompleteCallback, this ));
        }
    else
        {
        CSELOGSTRING_HIGH_LEVEL(
            "CCseSchedulerPluginStarter::PluginCompleted:Breaker already running!");
        }
        
    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerPluginStarter::PluginCompleted");
	}	
	
// -----------------------------------------------------------------------------
// CCseSchedulerPluginStarter::PluginCompleteCallback
// -----------------------------------------------------------------------------
//
TInt CCseSchedulerPluginStarter::PluginCompleteCallback( TAny* aPtr )
	{
	CSELOGSTRING_HIGH_LEVEL(">>>PluginCompleteCallback::ScheduleCompleteCallback");
	CSELOGSTRING_HIGH_LEVEL("<<<PluginCompleteCallback::ScheduleCompleteCallback");
	return static_cast<CCseSchedulerPluginStarter*>( aPtr )->HandlePluginCompleteCallback();
	}
	
// -----------------------------------------------------------------------------
// CCseSchedulerUserInformer::HandlePluginCompleteCallback
// -----------------------------------------------------------------------------
//
TInt CCseSchedulerPluginStarter::HandlePluginCompleteCallback() 
	{
	CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerPluginStarter::HandleScheduleCompleteCallback ");
	
	if( iPluginRdyToTakedown )
	    {
	    // First clear flag
	    iPluginRdyToTakedown = EFalse;    	
    	// Takedown thread
    	CActiveScheduler::Stop();
	    }
    else
	    {
	    // First start monitor
	    iSemaphoreMonitor->Start();
	    // Plugin ready to be run	    
	    TRAPD( err, RunPluginL() );
	    if ( err != KErrNone )
	        {
	        // Run plugin leaved for some reason. Set error code and get outta here!
	        iThreadPacket->SetResultCode( err );
            iPluginRdyToTakedown = ETrue;
            iCompletitionBreaker->Start(TCallBack( PluginCompleteCallback, this ));	        
	        }
	    }

	CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerPluginStarter::HandleScheduleCompleteCallback ");
	return EFalse;
	}

// -----------------------------------------------------------------------------
// CCseSchedulerUserInformer::SemaphoreSignalled
// -----------------------------------------------------------------------------
//
void CCseSchedulerPluginStarter::SemaphoreSignalled()
    {
    CSELOGSTRING_HIGH_LEVEL(">>>CCseSchedulerPluginStarter::SemaphoreSignalled");

    delete iPlugin;
    iPlugin = NULL;

    CActiveScheduler::Stop();
    
    CSELOGSTRING_HIGH_LEVEL("<<<CCseSchedulerPluginStarter::SemaphoreSignalled");
    }

// End of file.