diff -r 000000000000 -r 6a9f87576119 filemanager/Engine/src/CFileManagerThreadWrapper.cpp --- /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