crashanalysercmd/Libraries/Engine/CrashItemLib/Crash/Container/CIContainerIndexProcessor.cs
changeset 0 818e61de6cd1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crashanalysercmd/Libraries/Engine/CrashItemLib/Crash/Container/CIContainerIndexProcessor.cs	Thu Feb 11 15:50:58 2010 +0200
@@ -0,0 +1,142 @@
+/*
+* Copyright (c) 2009 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.Threading;
+using SymbianUtils;
+using SymbianDebugLib.Engine;
+using SymbianDebugLib.Entity.Configurations;
+using CrashItemLib.Engine;
+using System;
+using CrashItemLib.Crash.Messages;
+
+namespace CrashItemLib.Crash.Container
+{
+    internal class CIContainerIndexProcessor
+    {
+        #region Enumerations
+        public enum TEvent
+        {
+            EEventStarting = 0,
+            EEventCompleted
+        }
+        #endregion
+
+        #region Delegates & events
+        public delegate void ProcessorEventHandler( TEvent aEvent );
+        public event ProcessorEventHandler EventHandler = delegate { };
+        #endregion
+
+        #region Constructors
+        public CIContainerIndexProcessor( CIContainerIndex aIndex, CIEngine aEngine )
+        {
+            iIndex = aIndex;
+            iEngine = aEngine;
+        }
+        #endregion
+
+        #region API
+        public void Start( TSynchronicity aSynchronicity )
+        {
+            if ( aSynchronicity == TSynchronicity.EAsynchronous )
+            {
+                ThreadPool.QueueUserWorkItem( new WaitCallback( RunWorker ) );
+            }
+            else
+            {
+                RunWorker();
+            }
+        }
+        #endregion
+        
+        #region Properties
+        #endregion
+
+        #region Internal methods
+        private void RunWorker()
+        {            
+            RunWorker(null);
+        }
+
+        private void RunWorker( object aNotUsed )
+        {
+            iEngine.Trace( "[CIContainerIndexProcessor] RunWorker() - START - index groupings: {0}", iIndex.Count );
+
+            EventHandler( TEvent.EEventStarting );
+
+            DbgEngine debugEngine = iEngine.DebugEngine;
+            bool needToPrimeDebugEngine = debugEngine.MetaDataConfig.IsConfigurationDataAvailable;
+            iEngine.Trace( "[CIContainerIndexProcessor] RunWorker() - needToPrimeDebugEngine: {0}", needToPrimeDebugEngine );
+
+            // Process the index "buckets" until all are exhausted.
+            for ( CIContainerCollection collection = iIndex.DequeueNextContainer(); collection != null; collection = iIndex.DequeueNextContainer() )
+            {
+                try
+                {
+                    if ( collection.Count > 0 )
+                    {
+                        // Get the rom serial number - all containers in the collection share a common serial
+                        uint serialNumber = CIContainerIndex.GetRomChecksum( collection[ 0 ] );
+                        iEngine.Trace( "[CIContainerIndexProcessor] RunWorker() - {0} containers for rom checksum: 0x{1:x8}", collection.Count, serialNumber );
+
+                        // Prepare debug engine meta-data as needed.
+                        if ( needToPrimeDebugEngine )
+                        {
+                            DbgEntityConfigIdentifier identifier = new DbgEntityConfigIdentifier( serialNumber );
+
+                            iEngine.Trace( "[CIContainerIndexProcessor] RunWorker() - synchronously switching debug meta-data config..." );
+                            debugEngine.ConfigManager.SwitchConfigurationSynchronously( identifier );
+                            iEngine.Trace( "[CIContainerIndexProcessor] RunWorker() - switch complete." );
+                        }
+
+                        // Process the list of crash item containers in separate threads until all are handled.
+                        // This is quite a heavyweight operation since it also potentially primes the debug engine with
+                        // the needed symbols and then finalizes every associated crash container.
+                        // However, we run this in a separate thread so it will not block the UI.
+                        iEngine.Trace( "[CIContainerIndexProcessor] RunWorker() - running finalizer for {0} items with rom checksum: 0x{1:x8}", collection.Count, serialNumber );
+
+                        // We wait until the finalizer is finished, but we're running in a worker thread so this is OK.
+                        CIContainerFinalizer finalizer = new CIContainerFinalizer( collection, iEngine );
+                        finalizer.Start( SymbianUtils.TSynchronicity.ESynchronous );
+
+                        iEngine.Trace( "[CIContainerIndexProcessor] RunWorker() - finalization complete for {0} items with rom checksum: 0x{1:x8}", collection.Count, serialNumber );
+                    }
+                }                       
+                catch (Exception e)
+                {
+                    iEngine.Trace("Error: RunWorker() hit an unexpected exception!");
+
+                    foreach (CIContainer container in collection)
+                    {
+                        CIMessageError error = new CIMessageError(container, "RunWorker failed");
+                        error.AddLine("Unexpected exception encountered during container processing - analysis has failed!");
+                        container.Messages.Add(error);
+                    }
+                }
+            }
+            iEngine.Trace( "[CIContainerIndexProcessor] RunWorker() - Notifying about completion..." );
+
+            EventHandler( TEvent.EEventCompleted );
+
+            iEngine.Trace( "[CIContainerIndexProcessor] RunWorker() - END" );
+        }
+        #endregion
+
+        #region Data members
+        private readonly CIContainerIndex iIndex;
+        private readonly CIEngine iEngine;
+        #endregion
+    }
+}