filemanager/Engine/src/CFileManagerThreadWrapper.cpp
changeset 0 6a9f87576119
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/filemanager/Engine/src/CFileManagerThreadWrapper.cpp	Mon Jan 18 20:09:41 2010 +0200
@@ -0,0 +1,408 @@
+/*
+* Copyright (c) 2006-2007 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:  Background thread functionality wrapper
+*
+*/
+
+
+
+// INCLUDE FILES
+#include "CFileManagerThreadWrapper.h"
+#include "FileManagerDebug.h"
+
+
+// ============================= MEMBER FUNCTIONS =============================
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::CFileManagerThreadWrapper()
+//
+// ----------------------------------------------------------------------------
+CFileManagerThreadWrapper::CFileManagerThreadWrapper() :
+    CActive( CActive::EPriorityStandard )
+    {
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::~CFileManagerThreadWrapper()
+//
+// ----------------------------------------------------------------------------
+CFileManagerThreadWrapper::~CFileManagerThreadWrapper()
+    {
+    Cancel();
+    delete iNotifyObserver;
+    iSemaphore.Close();
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::NewL()
+//
+// ----------------------------------------------------------------------------
+CFileManagerThreadWrapper* CFileManagerThreadWrapper::NewL()
+    {
+    CFileManagerThreadWrapper* self =
+        new (ELeave) CFileManagerThreadWrapper();
+
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop( self );
+    return self;
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::ConstructL()
+//
+// ----------------------------------------------------------------------------
+void CFileManagerThreadWrapper::ConstructL()
+    {
+    CActiveScheduler::Add( this );
+    User::LeaveIfError( iSemaphore.CreateLocal( 0 ) );
+    iNotifyObserver = CNotifyObserver::NewL( *this );
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::RunL()
+//
+// ----------------------------------------------------------------------------
+void CFileManagerThreadWrapper::RunL()
+    {
+    iNotifyObserver->Cancel();
+
+    TInt err( iStatus.Int() );
+    LOG_IF_ERROR1( err, "CFileManagerThreadWrapper::RunL()-err=%d", err )
+
+    if ( iNotify & MFileManagerThreadFunction::ENotifyFinished )
+        {
+        TRAP_IGNORE( iFunction->NotifyThreadClientL(
+            MFileManagerThreadFunction::ENotifyFinished, err ) );
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::DoNotifyL()
+//
+// ----------------------------------------------------------------------------
+
+void CFileManagerThreadWrapper::DoNotifyL( TInt aErr )
+    {
+    LOG_IF_ERROR1( aErr, "CFileManagerThreadWrapper::DoNotifyL()-aErr=%d", aErr )
+
+    iResumePending = ETrue;
+
+    if ( aErr != KErrNone &&
+        ( iNotify & MFileManagerThreadFunction::ENotifyError ) )
+        {
+        iFunction->NotifyThreadClientL(
+            MFileManagerThreadFunction::ENotifyError, aErr );
+        }
+    else if ( iNotify & MFileManagerThreadFunction::ENotifyStepFinished )
+        {
+        iFunction->NotifyThreadClientL(
+            MFileManagerThreadFunction::ENotifyStepFinished, aErr );
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::RunError()
+//
+// ----------------------------------------------------------------------------
+TInt CFileManagerThreadWrapper::RunError( TInt aErr )
+    {
+    if ( aErr != KErrNone )
+        {
+        ERROR_LOG1( "CFileManagerThreadWrapper::RunError()-err=%d", aErr )
+        iCancel = ETrue;
+        ResumeThread();
+        }
+    return aErr;
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::DoCancel()
+//
+// ----------------------------------------------------------------------------
+void CFileManagerThreadWrapper::DoCancel()
+    {
+    FUNC_LOG
+
+    CancelThread();
+    iSemaphore.Signal(); // To avoid deadlock
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::StartThread()
+//
+// ----------------------------------------------------------------------------
+TInt CFileManagerThreadWrapper::StartThread(
+        MFileManagerThreadFunction& aFunction,
+        TUint aNotify,
+        TThreadPriority aPriority )
+    {
+    FUNC_LOG
+
+    TInt err( KErrAlreadyExists );
+
+    if ( !IsActive() )
+        {
+        RThread thread;
+        err = thread.Create(
+            KNullDesC, ThreadFunction, KDefaultStackSize, NULL, this );
+        if ( err == KErrNone )
+            {
+            thread.SetPriority( aPriority );
+            thread.Logon( iStatus );
+
+            iClientId = RThread().Id();
+            iFunction = &aFunction;
+            iNotify = aNotify;
+            iCancel = EFalse;
+
+            iNotifyObserver->Activate();
+            SetActive();
+
+            thread.Resume();
+            thread.Close();
+            }
+        }
+
+    LOG_IF_ERROR1( err, "CFileManagerThreadWrapper::StartThread()-err=%d",
+        err )
+
+    return err;
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::ThreadFunction()
+//
+// ----------------------------------------------------------------------------
+TInt CFileManagerThreadWrapper::ThreadFunction( TAny* ptr )
+    {
+    FUNC_LOG
+
+    CFileManagerThreadWrapper* self =
+        static_cast< CFileManagerThreadWrapper* >( ptr );
+
+    CTrapCleanup* cleanupStack = CTrapCleanup::New();
+    if ( !cleanupStack )
+        {
+        return KErrNoMemory;
+        }
+
+    TRAPD( err, self->ThreadFunctionL() );
+
+    self->iFunction->ReleaseThread();
+
+    delete cleanupStack;
+
+    return err;
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::ThreadFunctionL()
+//
+// ----------------------------------------------------------------------------
+void CFileManagerThreadWrapper::ThreadFunctionL()
+    {
+    FUNC_LOG
+
+    iFunction->InitThreadL();
+
+    while ( !iCancel )
+        {
+        TRAPD( err, iFunction->ThreadStepL() );
+
+        if ( !iCancel )
+            {
+            if ( err != KErrNone &&
+                ( iNotify & MFileManagerThreadFunction::ENotifyError ) )
+                {
+                User::LeaveIfError( NotifyClientAndWaitConfirm( err ) );
+                }
+            else if ( iNotify &
+                MFileManagerThreadFunction::ENotifyStepFinished )
+                {
+                User::LeaveIfError( NotifyClientAndWaitConfirm( err ) );
+                }
+            else
+                {
+                User::LeaveIfError( err );
+                }
+            }
+        if ( iFunction->IsThreadDone() )
+            {
+            break;
+            }
+        }
+
+    if ( iCancel )
+        {
+        User::LeaveIfError( KErrCancel );
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::CancelThread()
+//
+// ----------------------------------------------------------------------------
+void CFileManagerThreadWrapper::CancelThread()
+    {
+    FUNC_LOG
+
+    iCancel = ETrue;
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::IsThreadCanceled()
+//
+// ----------------------------------------------------------------------------
+TBool CFileManagerThreadWrapper::IsThreadCanceled() const
+    {
+    return iCancel;
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::NotifyClientAndWaitConfirm()
+//
+// ----------------------------------------------------------------------------
+TInt CFileManagerThreadWrapper::NotifyClientAndWaitConfirm( TInt aErr )
+    {
+    FUNC_LOG
+
+    RThread client;
+    TInt err( client.Open( iClientId ) );
+
+    if ( err == KErrNone )
+        {
+        iNotifyObserver->Complete( client, aErr );
+        client.Close();
+        iSemaphore.Wait(); // Wait resume from client
+        }
+    return err;
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::ResumeThread()
+//
+// ----------------------------------------------------------------------------
+void CFileManagerThreadWrapper::ResumeThread()
+    {
+    FUNC_LOG
+
+    if ( !iNotifyObserver->IsActive() && iResumePending )
+        {
+        iResumePending = EFalse;
+        iNotifyObserver->Activate();
+        iSemaphore.Signal(); // Resume thread stepping
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::IsThreadStarted()
+//
+// ----------------------------------------------------------------------------
+TBool CFileManagerThreadWrapper::IsThreadStarted() const
+    {
+    return IsActive();
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::CNotifyObserver::CNotifyObserver()
+//
+// ----------------------------------------------------------------------------
+CFileManagerThreadWrapper::CNotifyObserver::CNotifyObserver(
+    CFileManagerThreadWrapper& aWrapper ) :
+        CActive( CActive::EPriorityStandard ),
+        iWrapper( aWrapper )
+    {
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::CNotifyObserver::NewL()
+//
+// ----------------------------------------------------------------------------
+CFileManagerThreadWrapper::CNotifyObserver*
+    CFileManagerThreadWrapper::CNotifyObserver::NewL(
+        CFileManagerThreadWrapper& aWrapper )
+    {
+    CNotifyObserver* self = new (ELeave) CNotifyObserver( aWrapper );
+    CActiveScheduler::Add( self );
+    return self;
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::CNotifyObserver::~CNotifyObserver()
+//
+// ----------------------------------------------------------------------------
+CFileManagerThreadWrapper::CNotifyObserver::~CNotifyObserver()
+    {
+    Cancel();
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::CNotifyObserver::RunL()
+//
+// ----------------------------------------------------------------------------
+void CFileManagerThreadWrapper::CNotifyObserver::RunL()
+    {
+    iWrapper.DoNotifyL( iStatus.Int() );
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::CNotifyObserver::RunError()
+//
+// ----------------------------------------------------------------------------
+TInt CFileManagerThreadWrapper::CNotifyObserver::RunError( TInt aErr )
+    {
+    return iWrapper.RunError( aErr );
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::CNotifyObserver::DoCancel()
+//
+// ----------------------------------------------------------------------------
+void CFileManagerThreadWrapper::CNotifyObserver::DoCancel()
+    {
+    // Just complete status immediately since
+    // background thread does not complete status anymore
+    TRequestStatus* status = &iStatus;
+    User::RequestComplete( status, KErrCancel );
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::CNotifyObserver::Activate()
+//
+// ----------------------------------------------------------------------------
+void CFileManagerThreadWrapper::CNotifyObserver::Activate()
+    {
+    if ( !IsActive() )
+        {
+        iStatus = KRequestPending;
+        SetActive();
+        }
+    }
+
+// ----------------------------------------------------------------------------
+// CFileManagerThreadWrapper::CNotifyObserver::Complete()
+//
+// ----------------------------------------------------------------------------
+void CFileManagerThreadWrapper::CNotifyObserver::Complete(
+    RThread& aThread, TInt aResult )
+    {
+    if ( IsActive() )
+        {
+        TRequestStatus* status = &iStatus;
+        aThread.RequestComplete( status, aResult );
+        }
+    }
+
+// End of File