srsf/nssvascontacthdlr/src/nssvasccontacthandler.cpp
branchRCL_3
changeset 23 e36f3802f733
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/srsf/nssvascontacthdlr/src/nssvasccontacthandler.cpp	Wed Sep 01 12:29:17 2010 +0100
@@ -0,0 +1,324 @@
+/*
+* Copyright (c) 2004-2008 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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:  Responsible for maintaining synchronization between the contact DB
+*               and the VAS DB
+*
+*/
+
+
+// INCLUDE FILES
+#include "nssvasccontacthandler.h"
+#include "nssvasccontacthandlerimpl.h"
+#include "rubydebug.h"
+
+// CONSTANTS
+// Thread name
+_LIT( KCHThreadName, "NssVasCHThread" );
+// Thread priority
+const TThreadPriority KCHThreadPriority = EPriorityAbsoluteLow;
+// Thread heap min-max
+const TInt KCHHeapMinSize = KMinHeapSize;
+const TInt KCHHeapMaxSize = 0x300000;
+
+/**
+*  Utility class to handle cleanup of ContactHandler thread
+*/
+NONSHARABLE_CLASS( CContactHandlerStopper ) : public CAsyncOneShot
+    {
+    public:
+        static CContactHandlerStopper* NewL( TInt aPriority );
+        virtual ~CContactHandlerStopper();
+        void StopCH();
+    protected:
+        void RunL();
+        void DoCancel();
+    private:
+        CContactHandlerStopper( TInt aPriority );
+    };
+
+// ---------------------------------------------------------
+// CNssContactHandler::CNssContactHandler
+// C++ constructor.
+// ---------------------------------------------------------
+//       
+CNssContactHandler::CNssContactHandler():
+    iStopper( NULL )
+    {
+    // Nothing
+    }
+
+// ---------------------------------------------------------
+// CNssContactHandler::NewL
+// Two-phased constructor.
+// ---------------------------------------------------------
+//
+EXPORT_C CNssContactHandler* CNssContactHandler::NewL()
+    {
+    RUBY_DEBUG_BLOCK("CNssContactHandler::NewL");
+    CNssContactHandler* self = new (ELeave) CNssContactHandler();
+
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+
+    return self;
+    }
+
+// ---------------------------------------------------------
+// CNssContactHandler::ConstructL
+// Second-phase constructor.
+// ---------------------------------------------------------
+//
+void CNssContactHandler::ConstructL()
+    {
+    // Create processing thread
+    RThread chThread;
+
+    iThreadNameBuf.Append( _L( "[" ) );
+    // Add this pointer to the thread name to get it unique
+    iThreadNameBuf.AppendNum( ( TInt ) this );
+    iThreadNameBuf.Append( _L( "]" ) );
+    iThreadNameBuf.Append( KCHThreadName );
+
+    //RUBY_DEBUG1( "CNssContactHandler::ConstructL starting a thread with name: %S", iThreadNameBuf );
+
+    User::LeaveIfError( chThread.Create( iThreadNameBuf, CHThreadFunction, KDefaultStackSize, KCHHeapMinSize, KCHHeapMaxSize, this ) );
+
+    chThread.SetPriority( KCHThreadPriority );
+    chThread.Resume();
+    chThread.Close();    
+    }
+
+// ---------------------------------------------------------
+// CNssContactHandler::~CNssContactHandler
+// Destructor.
+// ---------------------------------------------------------
+//
+EXPORT_C CNssContactHandler::~CNssContactHandler()
+    {
+    RUBY_DEBUG0("CNssContactHandlerImplementation::~CNssContactHandler");
+
+    // Check if Contact Handler thread is still alive
+    RThread chThread;
+
+    _LIT( KProcessThreadDelimeter, "::" );
+    TBuf<256> fullThreadName;
+	RProcess currentProcess;
+    fullThreadName.Append( currentProcess.FullName() );
+    fullThreadName.Append( KProcessThreadDelimeter );
+    fullThreadName.Append( iThreadNameBuf );
+
+    if ( chThread.Open( fullThreadName ) == KErrNone )
+        {
+        // Increase the thread priority to get the cleanup done quickly
+        // Fixes priority inversion problem
+        chThread.SetPriority( RThread().Priority() );
+        RUBY_DEBUG1("CNssContactHandlerImplementation::~CNssContactHandler increased priority to: %d", chThread.Priority() );
+
+        if ( iStopper )
+            {
+            // Start AO which stops the ActiveScheduler in ContactHandler thread
+            // -> ContactHandler thread will clean itself
+            iStopper->StopCH();
+            iStopper = NULL;
+
+            // Wait that cleanup of ContactHandler thread has been done properly
+            TRequestStatus threadCompletion;
+            chThread.Rendezvous( threadCompletion );
+            User::WaitForRequest( threadCompletion );
+            }
+
+        chThread.Kill( KErrNone );
+
+        chThread.Close();
+        }
+    else
+        {
+        //RUBY_ERROR1( "CNssContactHandlerImplementation::~CNssContactHandler failed to open thread: %S", iThreadNameBuf );
+        }
+    }
+
+// ---------------------------------------------------------
+// CNssContactHandler::DisableEventHandling
+// Disables the event handling.
+// ---------------------------------------------------------
+//
+EXPORT_C void CNssContactHandler::DisableEventHandling()
+   {
+   RUBY_DEBUG0( "CNssContactHandler::DisableEventHandling" );
+   }
+
+// ---------------------------------------------------------
+// CNssContactHandler::EnableEventHandling
+// Enables event handling
+//---------------------------------------------------------
+//
+EXPORT_C void CNssContactHandler::EnableEventHandling()
+   {
+   RUBY_DEBUG0( "CNssContactHandler::EnableEventHandling" );
+   }
+
+// ---------------------------------------------------------
+// CNssContactHandler::SetStopperPointer
+// Sets the pointer to stopper object.
+//---------------------------------------------------------
+//
+void CNssContactHandler::SetStopperPointer( CContactHandlerStopper* aStopper )
+    {
+    iStopper = aStopper;
+    }
+
+// ---------------------------------------------------------
+// CNssContactHandler::CHThreadFunction
+// ContactHandler thread function.
+// ---------------------------------------------------------
+//
+TInt CNssContactHandler::CHThreadFunction( TAny* aParams )
+    {
+    TInt result = KErrNone;
+    // CleanupStack creation
+    CTrapCleanup* cleanupStack = CTrapCleanup::New();
+
+    // ActiveScheduler creation
+    CActiveScheduler* scheduler = NULL;
+    TRAPD( error, scheduler = new (ELeave) CActiveScheduler() );
+    if ( error == KErrNone )
+        {
+        // Take created ActiveScheduler into use
+        CActiveScheduler::Install( scheduler );
+
+        // Create utility object which is used when stopping this thread
+        CNssContactHandler* self = ( CNssContactHandler* )aParams;
+        CContactHandlerStopper* stopper = NULL;
+        TRAP( error, stopper  = CContactHandlerStopper::NewL( EPriorityNormal ) );
+        if ( error == KErrNone )
+            {
+            self->SetStopperPointer( stopper );
+
+            // Implementation of VAS ContactHandler
+            CNssContactHandlerImplementation* impl = NULL;
+            TRAP( error, impl = CNssContactHandlerImplementation::NewL() );
+
+            if ( error == KErrNone )
+                {
+                CActiveScheduler::Start();
+
+                delete impl;
+                self->SetStopperPointer( NULL );
+                delete stopper;
+                delete scheduler;
+                delete cleanupStack;
+
+                // Signal that cleanup of ContactHandler thread is now ok
+                RThread().Rendezvous( KErrNone );
+
+                result = KErrNone;                
+                }  // If created implementation
+            else
+                {
+                RUBY_ERROR1( "CNssContactHandler::CHThreadFunction Failed to create CH implementation. Error [%d]",
+                            error );
+                            
+                self->SetStopperPointer( NULL );
+                delete stopper;
+                delete scheduler;
+                result = error;
+                }
+                
+            // Self pointer not needed anymore
+            self = NULL;
+
+            }  // if created stopper
+        else 
+            {
+            RUBY_ERROR1( "CNssContactHandler::CHThreadFunction Failed to create CContactHandlerStopper. Error [%d]", 
+                        error );
+            delete scheduler;
+            result = error;
+            }
+        
+        }  // if created scheduler
+   else 
+        {
+        RUBY_ERROR1( "CNssContactHandler::CHThreadFunction Failed to create the active scheduler. Error [%d]", 
+                    error );
+        result = error;
+        }
+    
+    return result;
+    }
+
+// ---------------------------------------------------------
+// CContactHandlerStopper::NewL
+// Two-phased constructor.
+// ---------------------------------------------------------
+//
+CContactHandlerStopper* CContactHandlerStopper::NewL( TInt aPriority )
+	{
+	CContactHandlerStopper* self = new (ELeave) CContactHandlerStopper( aPriority );
+    return self;
+    }
+
+// ---------------------------------------------------------
+// CContactHandlerStopper::~CContactHandlerStopper
+// Desctructor.
+// ---------------------------------------------------------
+//
+CContactHandlerStopper::~CContactHandlerStopper()
+	{
+    Cancel();
+	}
+
+// ---------------------------------------------------------
+// CContactHandlerStopper::CContactHandlerStopper
+// C++ constructor.
+// ---------------------------------------------------------
+//
+CContactHandlerStopper::CContactHandlerStopper( TInt aPriority ) : 
+    CAsyncOneShot( aPriority )
+	{
+	// Nothing
+	}
+
+// ---------------------------------------------------------
+// CContactHandlerStopper::StopCH
+// Method to request stopping.
+// ---------------------------------------------------------
+//
+void CContactHandlerStopper::StopCH()
+    {
+    Call();
+    }
+
+// ---------------------------------------------------------
+// CContactHandlerStopper::RunL
+// From CActive.
+// ---------------------------------------------------------
+//
+void CContactHandlerStopper::RunL()
+    {
+    CActiveScheduler::Stop();
+    }
+
+// ---------------------------------------------------------
+// CContactHandlerStopper::DoCancel
+// From CActive.
+// ---------------------------------------------------------
+//
+void CContactHandlerStopper::DoCancel()
+    {
+    // Nothing
+    }
+
+// End of file