diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianSymbolLib/DbgEnginePlugin/SymbolPrimer.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianSymbolLib/DbgEnginePlugin/SymbolPrimer.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,231 @@ +/* +* Copyright (c) 2004-2008 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: +* +*/ + +using System; +using System.Collections.Generic; +using SymbianDebugLib.Entity; +using SymbianDebugLib.PluginAPI; +using SymbianSymbolLib.SourceManagement.Provisioning; +using SymbianSymbolLib.SourceManagement.Source; +using SymbianUtils; + +namespace SymbianSymbolLib.DbgEnginePlugin +{ + internal class SymbolPrimer : DbgPluginPrimer, IEnumerable + { + #region Constructors + public SymbolPrimer( SymbolPlugin aPlugin ) + : base( aPlugin ) + { + // If we've been created then presumably this is the reason... + ProvisioningManager.PrepareToCreateSources(); + } + #endregion + + #region From DbgPluginPrimer + public override void Add( DbgEntity aEntity ) + { + SymSourceProvider provider = null; + // + if ( aEntity.FSEntity.IsFile ) + { + if ( aEntity.Exists && aEntity.FSEntity.IsValid ) + { + provider = ProvisioningManager.GetProvider( aEntity.FSEntity.FullName ); + } + // + if ( provider != null ) + { + using ( SymSourceCollection sources = provider.CreateSources( aEntity.FullName ) ) + { + // Make sure the time to read attribute is setup in alignment with + // whether the entity was explicitly added by the user or found implicitly + // by scanning. + if ( aEntity.WasAddedExplicitly == false ) + { + foreach ( SymSource source in sources ) + { + // This means, don't read this source until it is actually + // referenced by the client. I.e. until the client activates + // a code segment that refers to this + source.TimeToRead = SymSource.TTimeToRead.EReadWhenNeeded; + } + } + + // Ownership is transferred + iSources.AddRange( sources ); + sources.Clear(); + } + } + else + { + throw new NotSupportedException( "Specified file type is not supported" ); + } + } + else + { + throw new ArgumentException( "SymbianSymbolLib does not support directory entities" ); + } + } + + public override void Prime( TSynchronicity aSynchronicity ) + { + SymbolPlugin plugin = this.Plugin; + + // Wipe any state ready for new priming attempt + base.OnPrepareToPrime(); + if ( base.ResetEngineBeforePriming ) + { + plugin.Clear(); + } + + // Tell the plugin which sources we are reading + plugin.StoreSourcesThatWillBePrimed( this ); + + // Listen to soure events so that we can report progress + SourceEventsSubscribe(); + + // Report the "priming started event" + base.ReportEvent( TPrimeEvent.EEventPrimingStarted, null ); + + // Now we can start the sources running. + foreach ( SymSource source in iSources ) + { + // If the source wants to read it's data immediately, then activated + // it right now... + if ( source.TimeToRead == SymSource.TTimeToRead.EReadWhenPriming ) + { + source.Read( aSynchronicity ); + } + else + { + // This source will read it's data on it's own terms so skip + // it to ensure that we can track when all the other sources + // (that do actually read their files now..) are ready. + Skip( source ); + } + } + } + + protected override int Count + { + get { return iSources.Count; } + } + #endregion + + #region API + internal void Skip( SymSource aSource ) + { + System.Diagnostics.Debug.Assert( aSource.TimeToRead == SymSource.TTimeToRead.EReadWhenNeeded ); + bool primeCompleted = base.AddToCompleted( aSource ); + CheckForCompletion( primeCompleted ); + } + #endregion + + #region Properties + internal SymbolPlugin Plugin + { + get { return base.Engine as SymbolPlugin; } + } + + internal SymSourceManager SourceManager + { + get { return Plugin.SourceManager; } + } + + internal SymSourceProviderManager ProvisioningManager + { + get { return Plugin.ProvisioningManager; } + } + #endregion + + #region Internal methods + private void SourceEventsSubscribe() + { + SourceEventsUnsubscribe(); + // + foreach ( SymSource source in iSources ) + { + source.EventHandler += new SymSource.EventHandlerFunction( Source_EventHandler ); + } + } + + private void SourceEventsUnsubscribe() + { + foreach ( SymSource source in iSources ) + { + source.EventHandler -= new SymSource.EventHandlerFunction( Source_EventHandler ); + } + } + + private void Source_EventHandler( SymSource.TEvent aEvent, SymSource aSource, object aData ) + { + bool primeCompleted = false; + + // Map source event onto a primer event + if ( aEvent == SymSource.TEvent.EReadingProgress ) + { + base.SaveLatestProgress( aSource, (int) aData ); + } + + // If all sources are complete, then are we also done? + if ( aEvent == SymSource.TEvent.EReadingComplete ) + { + // We don't need to listen to this source anymore + aSource.EventHandler -= new SymSource.EventHandlerFunction( Source_EventHandler ); + + // Source is 100% complete now. + base.SaveLatestProgress( aSource, 100 ); + + // It's complete, so record as such so that we can tell when all the sources + // are now ready. + primeCompleted = base.AddToCompleted( aSource ); + } + + CheckForCompletion( primeCompleted ); + } + + private void CheckForCompletion( bool aAmIComplete ) + { + // Report any progress + base.ReportProgressIfNeeded( aAmIComplete ); + + // Tidy up and report completion + if ( aAmIComplete ) + { + base.OnPrimeComplete(); + } + } + #endregion + + #region From IEnumerable + public IEnumerator GetEnumerator() + { + return iSources.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return iSources.GetEnumerator(); + } + #endregion + + #region Data members + private SymSourceCollection iSources = new SymSourceCollection(); + #endregion + } +}