filemanager/Engine/src/CFileManagerThreadWrapper.cpp
branchRCL_3
changeset 20 491b3ed49290
parent 19 95243422089a
child 21 65326cf895ed
equal deleted inserted replaced
19:95243422089a 20:491b3ed49290
     1 /*
       
     2 * Copyright (c) 2006-2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0""
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Background thread functionality wrapper
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // INCLUDE FILES
       
    21 #include "CFileManagerThreadWrapper.h"
       
    22 #include "FileManagerDebug.h"
       
    23 
       
    24 
       
    25 // ============================= MEMBER FUNCTIONS =============================
       
    26 
       
    27 // ----------------------------------------------------------------------------
       
    28 // CFileManagerThreadWrapper::CFileManagerThreadWrapper()
       
    29 //
       
    30 // ----------------------------------------------------------------------------
       
    31 CFileManagerThreadWrapper::CFileManagerThreadWrapper() :
       
    32     CActive( CActive::EPriorityStandard )
       
    33     {
       
    34     }
       
    35 
       
    36 // ----------------------------------------------------------------------------
       
    37 // CFileManagerThreadWrapper::~CFileManagerThreadWrapper()
       
    38 //
       
    39 // ----------------------------------------------------------------------------
       
    40 CFileManagerThreadWrapper::~CFileManagerThreadWrapper()
       
    41     {
       
    42     Cancel();
       
    43     delete iNotifyObserver;
       
    44     iSemaphore.Close();
       
    45     }
       
    46 
       
    47 // ----------------------------------------------------------------------------
       
    48 // CFileManagerThreadWrapper::NewL()
       
    49 //
       
    50 // ----------------------------------------------------------------------------
       
    51 CFileManagerThreadWrapper* CFileManagerThreadWrapper::NewL()
       
    52     {
       
    53     CFileManagerThreadWrapper* self =
       
    54         new (ELeave) CFileManagerThreadWrapper();
       
    55 
       
    56     CleanupStack::PushL( self );
       
    57     self->ConstructL();
       
    58     CleanupStack::Pop( self );
       
    59     return self;
       
    60     }
       
    61 
       
    62 // ----------------------------------------------------------------------------
       
    63 // CFileManagerThreadWrapper::ConstructL()
       
    64 //
       
    65 // ----------------------------------------------------------------------------
       
    66 void CFileManagerThreadWrapper::ConstructL()
       
    67     {
       
    68     CActiveScheduler::Add( this );
       
    69     User::LeaveIfError( iSemaphore.CreateLocal( 0 ) );
       
    70     iNotifyObserver = CNotifyObserver::NewL( *this );
       
    71     }
       
    72 
       
    73 // ----------------------------------------------------------------------------
       
    74 // CFileManagerThreadWrapper::RunL()
       
    75 //
       
    76 // ----------------------------------------------------------------------------
       
    77 void CFileManagerThreadWrapper::RunL()
       
    78     {
       
    79     iNotifyObserver->Cancel();
       
    80 
       
    81     TInt err( iStatus.Int() );
       
    82     LOG_IF_ERROR1( err, "CFileManagerThreadWrapper::RunL()-err=%d", err )
       
    83 
       
    84     if ( iNotify & MFileManagerThreadFunction::ENotifyFinished )
       
    85         {
       
    86         TRAP_IGNORE( iFunction->NotifyThreadClientL(
       
    87             MFileManagerThreadFunction::ENotifyFinished, err ) );
       
    88         }
       
    89     }
       
    90 
       
    91 // ----------------------------------------------------------------------------
       
    92 // CFileManagerThreadWrapper::DoNotifyL()
       
    93 //
       
    94 // ----------------------------------------------------------------------------
       
    95 
       
    96 void CFileManagerThreadWrapper::DoNotifyL( TInt aErr )
       
    97     {
       
    98     LOG_IF_ERROR1( aErr, "CFileManagerThreadWrapper::DoNotifyL()-aErr=%d", aErr )
       
    99 
       
   100     iResumePending = ETrue;
       
   101 
       
   102     if ( aErr != KErrNone &&
       
   103         ( iNotify & MFileManagerThreadFunction::ENotifyError ) )
       
   104         {
       
   105         iFunction->NotifyThreadClientL(
       
   106             MFileManagerThreadFunction::ENotifyError, aErr );
       
   107         }
       
   108     else if ( iNotify & MFileManagerThreadFunction::ENotifyStepFinished )
       
   109         {
       
   110         iFunction->NotifyThreadClientL(
       
   111             MFileManagerThreadFunction::ENotifyStepFinished, aErr );
       
   112         }
       
   113     }
       
   114 
       
   115 // ----------------------------------------------------------------------------
       
   116 // CFileManagerThreadWrapper::RunError()
       
   117 //
       
   118 // ----------------------------------------------------------------------------
       
   119 TInt CFileManagerThreadWrapper::RunError( TInt aErr )
       
   120     {
       
   121     if ( aErr != KErrNone )
       
   122         {
       
   123         ERROR_LOG1( "CFileManagerThreadWrapper::RunError()-err=%d", aErr )
       
   124         iCancel = ETrue;
       
   125         ResumeThread();
       
   126         }
       
   127     return aErr;
       
   128     }
       
   129 
       
   130 // ----------------------------------------------------------------------------
       
   131 // CFileManagerThreadWrapper::DoCancel()
       
   132 //
       
   133 // ----------------------------------------------------------------------------
       
   134 void CFileManagerThreadWrapper::DoCancel()
       
   135     {
       
   136     FUNC_LOG
       
   137 
       
   138     CancelThread();
       
   139     iSemaphore.Signal(); // To avoid deadlock
       
   140     }
       
   141 
       
   142 // ----------------------------------------------------------------------------
       
   143 // CFileManagerThreadWrapper::StartThread()
       
   144 //
       
   145 // ----------------------------------------------------------------------------
       
   146 TInt CFileManagerThreadWrapper::StartThread(
       
   147         MFileManagerThreadFunction& aFunction,
       
   148         TUint aNotify,
       
   149         TThreadPriority aPriority )
       
   150     {
       
   151     FUNC_LOG
       
   152 
       
   153     TInt err( KErrAlreadyExists );
       
   154 
       
   155     if ( !IsActive() )
       
   156         {
       
   157         RThread thread;
       
   158         err = thread.Create(
       
   159             KNullDesC, ThreadFunction, KDefaultStackSize, NULL, this );
       
   160         if ( err == KErrNone )
       
   161             {
       
   162             thread.SetPriority( aPriority );
       
   163             thread.Logon( iStatus );
       
   164 
       
   165             iClientId = RThread().Id();
       
   166             iFunction = &aFunction;
       
   167             iNotify = aNotify;
       
   168             iCancel = EFalse;
       
   169 
       
   170             iNotifyObserver->Activate();
       
   171             SetActive();
       
   172 
       
   173             thread.Resume();
       
   174             thread.Close();
       
   175             }
       
   176         }
       
   177 
       
   178     LOG_IF_ERROR1( err, "CFileManagerThreadWrapper::StartThread()-err=%d",
       
   179         err )
       
   180 
       
   181     return err;
       
   182     }
       
   183 
       
   184 // ----------------------------------------------------------------------------
       
   185 // CFileManagerThreadWrapper::ThreadFunction()
       
   186 //
       
   187 // ----------------------------------------------------------------------------
       
   188 TInt CFileManagerThreadWrapper::ThreadFunction( TAny* ptr )
       
   189     {
       
   190     FUNC_LOG
       
   191 
       
   192     CFileManagerThreadWrapper* self =
       
   193         static_cast< CFileManagerThreadWrapper* >( ptr );
       
   194 
       
   195     CTrapCleanup* cleanupStack = CTrapCleanup::New();
       
   196     if ( !cleanupStack )
       
   197         {
       
   198         return KErrNoMemory;
       
   199         }
       
   200 
       
   201     TRAPD( err, self->ThreadFunctionL() );
       
   202 
       
   203     self->iFunction->ReleaseThread();
       
   204 
       
   205     delete cleanupStack;
       
   206 
       
   207     return err;
       
   208     }
       
   209 
       
   210 // ----------------------------------------------------------------------------
       
   211 // CFileManagerThreadWrapper::ThreadFunctionL()
       
   212 //
       
   213 // ----------------------------------------------------------------------------
       
   214 void CFileManagerThreadWrapper::ThreadFunctionL()
       
   215     {
       
   216     FUNC_LOG
       
   217 
       
   218     iFunction->InitThreadL();
       
   219 
       
   220     while ( !iCancel )
       
   221         {
       
   222         TRAPD( err, iFunction->ThreadStepL() );
       
   223 
       
   224         if ( !iCancel )
       
   225             {
       
   226             if ( err != KErrNone &&
       
   227                 ( iNotify & MFileManagerThreadFunction::ENotifyError ) )
       
   228                 {
       
   229                 User::LeaveIfError( NotifyClientAndWaitConfirm( err ) );
       
   230                 }
       
   231             else if ( iNotify &
       
   232                 MFileManagerThreadFunction::ENotifyStepFinished )
       
   233                 {
       
   234                 User::LeaveIfError( NotifyClientAndWaitConfirm( err ) );
       
   235                 }
       
   236             else
       
   237                 {
       
   238                 User::LeaveIfError( err );
       
   239                 }
       
   240             }
       
   241         if ( iFunction->IsThreadDone() )
       
   242             {
       
   243             break;
       
   244             }
       
   245         }
       
   246 
       
   247     if ( iCancel )
       
   248         {
       
   249         User::LeaveIfError( KErrCancel );
       
   250         }
       
   251     }
       
   252 
       
   253 // ----------------------------------------------------------------------------
       
   254 // CFileManagerThreadWrapper::CancelThread()
       
   255 //
       
   256 // ----------------------------------------------------------------------------
       
   257 void CFileManagerThreadWrapper::CancelThread()
       
   258     {
       
   259     FUNC_LOG
       
   260 
       
   261     iCancel = ETrue;
       
   262     }
       
   263 
       
   264 // ----------------------------------------------------------------------------
       
   265 // CFileManagerThreadWrapper::IsThreadCanceled()
       
   266 //
       
   267 // ----------------------------------------------------------------------------
       
   268 TBool CFileManagerThreadWrapper::IsThreadCanceled() const
       
   269     {
       
   270     return iCancel;
       
   271     }
       
   272 
       
   273 // ----------------------------------------------------------------------------
       
   274 // CFileManagerThreadWrapper::NotifyClientAndWaitConfirm()
       
   275 //
       
   276 // ----------------------------------------------------------------------------
       
   277 TInt CFileManagerThreadWrapper::NotifyClientAndWaitConfirm( TInt aErr )
       
   278     {
       
   279     FUNC_LOG
       
   280 
       
   281     RThread client;
       
   282     TInt err( client.Open( iClientId ) );
       
   283 
       
   284     if ( err == KErrNone )
       
   285         {
       
   286         iNotifyObserver->Complete( client, aErr );
       
   287         client.Close();
       
   288         iSemaphore.Wait(); // Wait resume from client
       
   289         }
       
   290     return err;
       
   291     }
       
   292 
       
   293 // ----------------------------------------------------------------------------
       
   294 // CFileManagerThreadWrapper::ResumeThread()
       
   295 //
       
   296 // ----------------------------------------------------------------------------
       
   297 void CFileManagerThreadWrapper::ResumeThread()
       
   298     {
       
   299     FUNC_LOG
       
   300 
       
   301     if ( !iNotifyObserver->IsActive() && iResumePending )
       
   302         {
       
   303         iResumePending = EFalse;
       
   304         iNotifyObserver->Activate();
       
   305         iSemaphore.Signal(); // Resume thread stepping
       
   306         }
       
   307     }
       
   308 
       
   309 // ----------------------------------------------------------------------------
       
   310 // CFileManagerThreadWrapper::IsThreadStarted()
       
   311 //
       
   312 // ----------------------------------------------------------------------------
       
   313 TBool CFileManagerThreadWrapper::IsThreadStarted() const
       
   314     {
       
   315     return IsActive();
       
   316     }
       
   317 
       
   318 // ----------------------------------------------------------------------------
       
   319 // CFileManagerThreadWrapper::CNotifyObserver::CNotifyObserver()
       
   320 //
       
   321 // ----------------------------------------------------------------------------
       
   322 CFileManagerThreadWrapper::CNotifyObserver::CNotifyObserver(
       
   323     CFileManagerThreadWrapper& aWrapper ) :
       
   324         CActive( CActive::EPriorityStandard ),
       
   325         iWrapper( aWrapper )
       
   326     {
       
   327     }
       
   328 
       
   329 // ----------------------------------------------------------------------------
       
   330 // CFileManagerThreadWrapper::CNotifyObserver::NewL()
       
   331 //
       
   332 // ----------------------------------------------------------------------------
       
   333 CFileManagerThreadWrapper::CNotifyObserver*
       
   334     CFileManagerThreadWrapper::CNotifyObserver::NewL(
       
   335         CFileManagerThreadWrapper& aWrapper )
       
   336     {
       
   337     CNotifyObserver* self = new (ELeave) CNotifyObserver( aWrapper );
       
   338     CActiveScheduler::Add( self );
       
   339     return self;
       
   340     }
       
   341 
       
   342 // ----------------------------------------------------------------------------
       
   343 // CFileManagerThreadWrapper::CNotifyObserver::~CNotifyObserver()
       
   344 //
       
   345 // ----------------------------------------------------------------------------
       
   346 CFileManagerThreadWrapper::CNotifyObserver::~CNotifyObserver()
       
   347     {
       
   348     Cancel();
       
   349     }
       
   350 
       
   351 // ----------------------------------------------------------------------------
       
   352 // CFileManagerThreadWrapper::CNotifyObserver::RunL()
       
   353 //
       
   354 // ----------------------------------------------------------------------------
       
   355 void CFileManagerThreadWrapper::CNotifyObserver::RunL()
       
   356     {
       
   357     iWrapper.DoNotifyL( iStatus.Int() );
       
   358     }
       
   359 
       
   360 // ----------------------------------------------------------------------------
       
   361 // CFileManagerThreadWrapper::CNotifyObserver::RunError()
       
   362 //
       
   363 // ----------------------------------------------------------------------------
       
   364 TInt CFileManagerThreadWrapper::CNotifyObserver::RunError( TInt aErr )
       
   365     {
       
   366     return iWrapper.RunError( aErr );
       
   367     }
       
   368 
       
   369 // ----------------------------------------------------------------------------
       
   370 // CFileManagerThreadWrapper::CNotifyObserver::DoCancel()
       
   371 //
       
   372 // ----------------------------------------------------------------------------
       
   373 void CFileManagerThreadWrapper::CNotifyObserver::DoCancel()
       
   374     {
       
   375     // Just complete status immediately since
       
   376     // background thread does not complete status anymore
       
   377     TRequestStatus* status = &iStatus;
       
   378     User::RequestComplete( status, KErrCancel );
       
   379     }
       
   380 
       
   381 // ----------------------------------------------------------------------------
       
   382 // CFileManagerThreadWrapper::CNotifyObserver::Activate()
       
   383 //
       
   384 // ----------------------------------------------------------------------------
       
   385 void CFileManagerThreadWrapper::CNotifyObserver::Activate()
       
   386     {
       
   387     if ( !IsActive() )
       
   388         {
       
   389         iStatus = KRequestPending;
       
   390         SetActive();
       
   391         }
       
   392     }
       
   393 
       
   394 // ----------------------------------------------------------------------------
       
   395 // CFileManagerThreadWrapper::CNotifyObserver::Complete()
       
   396 //
       
   397 // ----------------------------------------------------------------------------
       
   398 void CFileManagerThreadWrapper::CNotifyObserver::Complete(
       
   399     RThread& aThread, TInt aResult )
       
   400     {
       
   401     if ( IsActive() )
       
   402         {
       
   403         TRequestStatus* status = &iStatus;
       
   404         aThread.RequestComplete( status, aResult );
       
   405         }
       
   406     }
       
   407 
       
   408 // End of File