diff -r 000000000000 -r 818e61de6cd1 crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianUtils/SerializedOperations/SerializedOperation.cs --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/crashanalysercmd/PerfToolsSharedLibraries/Engine/SymbianUtils/SerializedOperations/SerializedOperation.cs Thu Feb 11 15:50:58 2010 +0200 @@ -0,0 +1,276 @@ +/* +* 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; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.ComponentModel; + +namespace SymbianUtils.SerializedOperations +{ + public abstract class SerializedOperation : DisposableObject, IComparable + { + #region Delegates & events + public delegate void EventHandler( SerializedOperation aOperation ); + public event EventHandler Started; + public event EventHandler Completed; + #endregion + + #region Constructors + protected SerializedOperation() + : this( true ) + { + } + + protected SerializedOperation( bool aEnabled ) + { + Enabled = aEnabled; + // + iWorker.DoWork += new DoWorkEventHandler( DoWork ); + } + #endregion + + #region Framework API + protected abstract void PerformOperation(); + + public virtual long Priority + { + get { return 0; } + } + #endregion + + #region API + public void EnableAndWait() + { + Trace( "[{0}] EnableAndWait() - START - enabled: {1}, busy: {2}", this.GetType().Name, Enabled, IsBusy ); + System.Diagnostics.Debug.Assert( Enabled == false ); + System.Diagnostics.Debug.Assert( !IsBusy ); + + if ( IsBusy ) + { + while ( IsBusy ) + { + Trace( "[{0}] EnableAndWait() - still busy?: {1}", this.GetType().Name, IsBusy ); + Thread.Sleep( 10 ); + } + } + else + { + SymbianUtils.SymDebug.SymDebugger.Assert( iWaitForCompletion == null ); + using ( iWaitForCompletion = new AutoResetEvent( false ) ) + { + // Enable the operation + Trace( "[{0}] EnableAndWait() - enabling item...", this.GetType().Name ); + Enabled = true; + + // And now block until it completes + Trace( "[{0}] EnableAndWait() - sleeping...", this.GetType().Name ); + iWaitForCompletion.WaitOne(); + Trace( "[{0}] EnableAndWait() - slept!", this.GetType().Name ); + } + } + + Trace( "[{0}] EnableAndWait() - END", this.GetType().Name ); + } + #endregion + + #region Properties + public object Tag + { + get { return iTag; } + set { iTag = value; } + } + + public bool IsBusy + { + get { return iWorker.IsBusy; } + } + + public bool Enabled + { + get { return iEnabled; } + set + { + lock ( iEnabledLock ) + { + if ( value != iEnabled ) + { + iEnabled = value; + if ( OperationManager != null ) + { + OperationManager.OnOperationEnabledStatusChanged( this ); + } + } + } + } + } + + internal SerializedOperationManager OperationManager + { + get { return iManager; } + set { iManager = value; } + } + #endregion + + #region Event handlers + private void DoWork( object aSender, DoWorkEventArgs aArgs ) + { + System.Diagnostics.Debug.Assert( OperationManager != null ); + NotifyStarted(); + // + try + { + PerformOperation(); + } + catch ( Exception opException ) + { + OperationManager.Trace( string.Format( "OPERATION EXCEPTION MSG - op: {0} ({1}) - msg: {2}", this.ToString(), this.GetType(), opException.Message ) ); + OperationManager.Trace( string.Format( "OPERATION EXCEPTION STK {0}", opException.StackTrace ) ); + } + // + NotifyCompleted(); + } + + private void WorkerCompleted() + { + Trace( "[{0}] WorkerCompleted() - START", this.GetType().Name ); + // + System.Diagnostics.Debug.Assert( OperationManager != null ); + OperationManager.OperationCompleted( this ); + // + if ( iWaitForCompletion != null ) + { + Trace( "[{0}] WorkerCompleted() - unblocking main thread...", this.GetType().Name ); + iWaitForCompletion.Set(); + } + // + Trace( "[{0}] WorkerCompleted() - END", this.GetType().Name ); + } + #endregion + + #region Internal methods + protected void Trace( string aMessage ) + { + iManager.Trace( aMessage ); + } + + protected void Trace( string aFormat, params object[] aParams ) + { + iManager.Trace( aFormat, aParams ); + } + + internal void Start() + { + Start( null ); + } + + internal void Start( object aParameter ) + { + System.Diagnostics.Debug.Assert( Enabled ); + iWorker.RunWorkerAsync( aParameter ); + } + + private void NotifyStarted() + { + try + { + if ( Started != null ) + { + Started( this ); + } + } + catch ( Exception ) + { + } + } + + private void NotifyCompleted() + { + try + { + if ( Completed != null ) + { + Completed( this ); + } + try + { + WorkerCompleted(); + } + catch ( Exception ) + { + } + } + catch ( Exception ) + { + } + } + #endregion + + #region From IComparable + public int CompareTo( SerializedOperation aOther ) + { + int ret = 1; + // + if ( aOther != null ) + { + ret = this.Priority.CompareTo( aOther.Priority ); + } + // + return ret; + } + #endregion + + #region From DisposableObject + protected override void CleanupManagedResources() + { + try + { + base.CleanupManagedResources(); + } + finally + { + if ( iWaitForCompletion != null ) + { + iWaitForCompletion.Close(); + iWaitForCompletion = null; + } + if ( iWorker != null ) + { + iWorker.Dispose(); + iWorker = null; + } + } + } + #endregion + + #region From System.Object + public override string ToString() + { + return this.GetType().Name; + } + #endregion + + #region Data members + private object iTag = null; + private object iEnabledLock = new object(); + private bool iEnabled = true; + private SerializedOperationManager iManager = null; + private BackgroundWorker iWorker = new BackgroundWorker(); + private AutoResetEvent iWaitForCompletion = null; + #endregion + } +}