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