diff -r 12c456ceeff2 -r 5253a20d2a1e emailuis/emailui/src/FreestyleEmailDownloadInformationMediator.cpp --- a/emailuis/emailui/src/FreestyleEmailDownloadInformationMediator.cpp Thu Jan 07 12:38:38 2010 +0200 +++ b/emailuis/emailui/src/FreestyleEmailDownloadInformationMediator.cpp Mon Jan 18 20:08:26 2010 +0200 @@ -44,7 +44,8 @@ // CFSEmailDownloadInfoMediator::CFSEmailDownloadInfoMediator( CFSMailClient& aMailClient ) : CActive( EPriorityNormal ), iMailClient(aMailClient), - iDownloadArray( KArrayGranularity, _FOFF(TDownload, iRequestId) ), iDownloadsStarted ( EFalse ) + iDownloadArray( KArrayGranularity, _FOFF(TDownload, iRequestId) ), iDownloadsStarted ( EFalse ), + iNotificationsInProgress( 0 ), iObserverDeleted( EFalse ) { FUNC_LOG; CActiveScheduler::Add( this ); @@ -383,11 +384,11 @@ void CFSEmailDownloadInfoMediator::StopObserving( MFSEmailDownloadInformationObserver* aObserver, TFSMailMsgId aMessageId ) { FUNC_LOG; - for (TInt i=0; i=0; i--) { if ( iObserverArray[i].iObserver == aObserver && iObserverArray[i].iMessageId == aMessageId ) { - iObserverArray.Remove(i); + RemoveObserver(i); } } } @@ -395,14 +396,14 @@ void CFSEmailDownloadInfoMediator::StopObserving( MFSEmailDownloadInformationObserver* aObserver ) { FUNC_LOG; - for (TInt i=0; i=0; i-- ) { if ( iObserverArray[i].iObserver == aObserver ) { - iObserverArray.Remove(i); + RemoveObserver(i); } } - for (TInt i=0; i=0; i-- ) { if ( iAllObserverArray[i] == aObserver ) { @@ -411,6 +412,23 @@ } } +void CFSEmailDownloadInfoMediator::RemoveObserver( TInt aIdx ) + { + if ( iNotificationsInProgress == 0 ) + { + // If we're not currently iterating over the array, remove the entry + // immediately. + iObserverArray.Remove( aIdx ); + } + else + { + // We're currently iterating over the array: mark the entry as + // deleted and flag that we've done so. + iObserverArray[aIdx].iDeleted = ETrue; + iObserverDeleted = ETrue; + } + } + void CFSEmailDownloadInfoMediator::DownloadL( TPartData aPart, TBool aCompleteNote ) { FUNC_LOG; @@ -725,25 +743,61 @@ SetActive(); } - + void CFSEmailDownloadInfoMediator::NotifyObserversL( const TFSProgress& aEvent, const TPartData& aPart ) { FUNC_LOG; + + // notify observers of this particular message part + iNotificationsInProgress++; + TRAPD( error, NotifyPartObserversL( aEvent, aPart ) ); + if ( --iNotificationsInProgress == 0 ) + { + CleanUpObservers(); + } + if ( error ) + { + User::Leave( error ); + } + + // send response to every 'all observer' + for ( TInt i=iAllObserverArray.Count()-1; i>=0; i-- ) + { + iAllObserverArray[i]->RequestResponseL( aEvent, aPart ); + } + } + +void CFSEmailDownloadInfoMediator::NotifyPartObserversL( const TFSProgress& aEvent, const TPartData& aPart ) + { + FUNC_LOG; // go through all observers - for ( TInt j=iObserverArray.Count()-1; j>=0; j--) + for ( TInt j=iObserverArray.Count()-1; j>=0; j-- ) { // if observer is observing this message - if ( iObserverArray[j].iMessageId == aPart.iMessageId ) + if ( !iObserverArray[j].iDeleted && iObserverArray[j].iMessageId == aPart.iMessageId ) { // send response to observer iObserverArray[j].iObserver->RequestResponseL( aEvent, aPart ); } } - // send response to every 'all observer' - for (TInt i=0; iRequestResponseL( aEvent, aPart ); - } + } + +void CFSEmailDownloadInfoMediator::CleanUpObservers() + { + FUNC_LOG; + // If one or more observers have been marked for deletion, go through + // the observer array and remove them. + if ( iObserverDeleted ) + { + for ( TInt j=iObserverArray.Count()-1; j>=0; j-- ) + { + if ( iObserverArray[j].iDeleted ) + { + iObserverArray.Remove(j); + } + } + iObserverDeleted = EFalse; + } } void CFSEmailDownloadInfoMediator::RunL()