diff -r 185201be11b0 -r 516af714ebb4 memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectThread.cpp --- a/memspy/Engine/Source/ThreadAndProcess/MemSpyEngineObjectThread.cpp Thu Sep 02 22:05:40 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,532 +0,0 @@ -/* -* 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: -* -*/ - -#include - -// System includes -#include - -// Driver includes -#include - -// User includes -#include -#include -#include -#include - -// Constants -_LIT( KMemSpyUnknownExitCategory, "Unknown ExitCat" ); -_LIT( KMemSpyUnknownThreadName, "Unknown Thread" ); -_LIT( KMemSpyThreadDoubleColon, "::" ); - - -CMemSpyThread::CMemSpyThread( TThreadId aId, CMemSpyProcess& aProcess ) -: CMemSpyEngineObject( aProcess ), iId( aId ), iProcess( &aProcess ) - { - } - - -CMemSpyThread::~CMemSpyThread() - { - if ( iInfoContainer ) - { - iInfoContainer->Close(); - } - delete iName; - } - - -void CMemSpyThread::ConstructL() - { - RefreshL(); - } - - -CMemSpyThread* CMemSpyThread::NewL( TThreadId aId, CMemSpyProcess& aProcess ) - { - CMemSpyThread* self = CMemSpyThread::NewLC( aId, aProcess ); - CleanupStack::Pop( self ); - return self; - } - - -CMemSpyThread* CMemSpyThread::NewLC( TThreadId aId, CMemSpyProcess& aProcess ) - { - CMemSpyThread* self = new(ELeave) CMemSpyThread( aId, aProcess ); - CleanupStack::PushL( self ); - self->ConstructL(); - return self; - } - - -EXPORT_C void CMemSpyThread::Open() - { - if ( !OpenOrCloseInProgress() ) - { - SetOpenOrCloseInProgress( ETrue ); - CMemSpyEngineObject::Open(); - SetOpenOrCloseInProgress( EFalse ); - } - } - - -EXPORT_C void CMemSpyThread::Close() - { - if ( !OpenOrCloseInProgress() ) - { - SetOpenOrCloseInProgress( ETrue ); - CMemSpyEngineObject::Close(); - SetOpenOrCloseInProgress( EFalse ); - } - } - - -void CMemSpyThread::AppendPriority( TDes& aDes, TThreadPriority aPriority ) - { - switch( aPriority ) - { - case EPriorityNull: - aDes += _L("[Null]"); - break; - case EPriorityMuchLess: - aDes += _L("[Much Less]"); - break; - case EPriorityLess: - aDes += _L("[Less]"); - break; - case EPriorityNormal: - aDes += _L("[Normal]"); - break; - case EPriorityMore: - aDes += _L("[More]"); - break; - case EPriorityMuchMore: - aDes += _L("[Much More]"); - break; - case EPriorityRealTime: - aDes += _L("[Real Time]"); - break; - - // Absolute values - case EPriorityAbsoluteVeryLow: - aDes += _L("[Abs Very Low]"); - break; - case EPriorityAbsoluteLowNormal: - aDes += _L("[Abs Low Norm]"); - break; - case EPriorityAbsoluteLow: - aDes += _L("[Abs Low]"); - break; - case EPriorityAbsoluteBackground: - aDes += _L("[Abs Bgnd]"); - break; - case EPriorityAbsoluteBackgroundNormal: - aDes += _L("[Abs Bgnd Norm]"); - break; - case EPriorityAbsoluteForeground: - aDes += _L("[Abs Fgnd]"); - break; - case EPriorityAbsoluteForegroundNormal: - aDes += _L("[Abs Fgnd Norm]"); - break; - case EPriorityAbsoluteHigh: - aDes += _L("[Abs High]"); - break; - case EPriorityAbsoluteHighNormal: - aDes += _L("[Abs High Norm]"); - break; - case EPriorityAbsoluteRealTime1: - case EPriorityAbsoluteRealTime2: - case EPriorityAbsoluteRealTime3: - case EPriorityAbsoluteRealTime4: - case EPriorityAbsoluteRealTime5: - case EPriorityAbsoluteRealTime6: - case EPriorityAbsoluteRealTime7: - case EPriorityAbsoluteRealTime8: - aDes.AppendFormat( _L("[Abs RT %d]"), ( aPriority - EPriorityAbsoluteRealTime1 ) + 1 ); - break; - default: - aDes += _L("[Unknown Pri.]"); - break; - } - } - - -void CMemSpyThread::AppendExitType( TDes& aDes, TExitType aType ) - { - _LIT( KExitTypeKilled, "Killed" ); - _LIT( KExitTypeTerminated, "Terminated" ); - _LIT( KExitTypePanicked, "Panicked" ); - _LIT( KExitTypePending, "Pending" ); - - // Panic and Terminate are exceptional exit conditions. - // Kill, is ironically, not an exceptional condition. - switch( aType ) - { - case EExitKill: - aDes += KExitTypeKilled; - break; - case EExitTerminate: - aDes += KExitTypeTerminated; - break; - case EExitPanic: - aDes += KExitTypePanicked; - break; - default: - case EExitPending: - aDes += KExitTypePending; - break; - } - } - - -void CMemSpyThread::AppendExitInfo( TDes& aDes, TExitType aType, TInt aExitReason, const TDesC& aExitCategory ) - { - aDes.Append( '[' ); - const TInt length = aDes.Length(); - AppendExitType( aDes, aType ); - aDes.SetLength( length + 1 ); // Remove all but the first letter - aDes.Append( ']' ); - - if ( aType == EExitKill || aType == EExitPending ) - { - // Kill implies "clean" exit. Pending implies not yet dead. - } - else - { - TMemSpyTruncateOverflow overflow; - - // Terminate or Panic implies abnormal exit condition, so - // show full exit info. - _LIT( KAbnormalFormatSpec, " %S-%d" ); - aDes.AppendFormat( KAbnormalFormatSpec, &overflow, &aExitCategory, aExitReason ); - } - } - - -CMemSpyEngine& CMemSpyThread::Engine() const - { - return Process().Engine(); - } - - -void CMemSpyThread::OpenLC( RThread& aThread ) - { - const TInt error = Open( aThread ); - User::LeaveIfError( error ); - CleanupClosePushL( aThread ); - } - - -TInt CMemSpyThread::Open( RThread& aThread ) - { - CMemSpyEngine& engine = iProcess->Engine(); - RMemSpyDriverClient& driver = engine.Driver(); - const TInt error = driver.OpenThread( iId, aThread ); - return error; - } - - -EXPORT_C TPtrC CMemSpyThread::Name() const - { - // Just return the pure name, minus the leading tab - TPtrC pRet( iName->Mid(2) ); - - // Find the last tab position - TInt pos = pRet.Locate(TChar('\t')); - if ( pos > 0 ) - { - pRet.Set( pRet.Left( pos ) ); - } - // - return pRet; - } - - -EXPORT_C TFullName CMemSpyThread::FullName() const - { - TFullName name( iProcess->Name() ); - name += KMemSpyThreadDoubleColon; - name += Name(); - // - return name; - } - - -EXPORT_C TBool CMemSpyThread::IsSystemPermanent() const - { - const TBool ret = ( iFlags & KThreadFlagSystemPermanent ); - return ret; - } - - -EXPORT_C TBool CMemSpyThread::IsSystemCritical() const - { - const TBool ret = ( iFlags & KThreadFlagSystemCritical ); - return ret; - } - - -EXPORT_C CMemSpyThreadInfoContainer& CMemSpyThread::InfoContainerL() - { - if ( iInfoContainer == NULL ) - { - const TBool KConstructAsynchronously = ETrue; - iInfoContainer = CMemSpyThreadInfoContainer::NewL( *this, KConstructAsynchronously ); - } - // - return *iInfoContainer; - } - - -EXPORT_C CMemSpyThreadInfoContainer& CMemSpyThread::InfoContainerForceSyncronousConstructionL() - { - if ( iInfoContainer == NULL ) - { - const TBool KConstructSynchronously = EFalse; - iInfoContainer = CMemSpyThreadInfoContainer::NewL( *this, KConstructSynchronously ); - } - // - return *iInfoContainer; - } - - -EXPORT_C void CMemSpyThread::KillL() - { - CMemSpyEngine& engine = iProcess->Engine(); - RMemSpyDriverClient& driver = engine.Driver(); - // - User::LeaveIfError( driver.ThreadEnd( Id(), EExitKill ) ); - } - - -EXPORT_C void CMemSpyThread::TerminateL() - { - CMemSpyEngine& engine = iProcess->Engine(); - RMemSpyDriverClient& driver = engine.Driver(); - // - User::LeaveIfError( driver.ThreadEnd( Id(), EExitTerminate ) ); - } - - -EXPORT_C void CMemSpyThread::PanicL() - { - CMemSpyEngine& engine = iProcess->Engine(); - RMemSpyDriverClient& driver = engine.Driver(); - // - User::LeaveIfError( driver.ThreadEnd( Id(), EExitPanic ) ); - } - - -EXPORT_C void CMemSpyThread::SetPriorityL( TThreadPriority aPriority ) - { -#ifdef _DEBUG - RDebug::Printf( "CMemSpyThread::SetPriorityL() - START - aPriority: %d, orig pri: %d", aPriority, iPriority ); -#endif - CMemSpyEngine& engine = iProcess->Engine(); - RMemSpyDriverClient& driver = engine.Driver(); - // - const TInt err = driver.SetPriority( Id(), aPriority ); -#ifdef _DEBUG - TInt newPri = -1; - RThread thread; - if ( driver.OpenThread( iId, thread ) == KErrNone ) - { - newPri = thread.Priority(); - thread.Close(); - } - RDebug::Printf( "CMemSpyThread::SetPriorityL() - err: %d, newPri: %d", err, newPri ); -#endif - - User::LeaveIfError( err ); - RefreshL(); -#ifdef _DEBUG - RDebug::Printf( "CMemSpyThread::SetPriorityL() - END" ); -#endif - } - - -void CMemSpyThread::SetDeadL() - { - RefreshL(); - } - - -void CMemSpyThread::SetDeadL( const RThread& aThread ) - { - RefreshL( aThread ); - } - - -void CMemSpyThread::FullName( TDes& aName ) const - { - iProcess->FullName( aName ); - aName.Append( KMemSpyThreadDoubleColon ); - aName.Append( Name() ); - } - - -EXPORT_C TBool CMemSpyThread::IsDead() const - { - const TBool isDead = ( iExitType != EExitPending ); - return isDead; - } - -EXPORT_C TThreadPriority CMemSpyThread::Priority() const - { - return iPriority; - } - - -void CMemSpyThread::RefreshL() - { - CMemSpyEngine& engine = iProcess->Engine(); - RMemSpyDriverClient& driver = engine.Driver(); - - // Try to open thread. We use the device driver since - // it doesn't check (i.e. it bypasses) some of the conditions which the - // default RThread::Open() implementation enforces... - // - // Deliberately ignore error. The other overload of RefreshL will - // cope with the failure. - RThread thread; - driver.OpenThread( iId, thread ); - CleanupClosePushL( thread ); - - // Call refresh with thread to perform actual heavy lifting... - RefreshL( thread ); - - // Clean up. This thread handle might actually not even be open, but that's okay... - CleanupStack::PopAndDestroy( &thread ); - } - - -void CMemSpyThread::RefreshL( const RThread& aThread ) - { - const TBool handleValid = aThread.Handle() != KNullHandle; - if ( handleValid ) - { - // Annoyingly, we request the entire thread info structure just to get the thread flags... - iFlags = 0; - const User::TCritical critType = User::Critical( aThread ); - if ( critType == User::ESystemPermanent ) - { - iFlags |= KThreadFlagSystemPermanent; - } - else if ( critType == User::ESystemCritical ) - { - iFlags |= KThreadFlagSystemCritical; - } - -#ifdef _DEBUG - TMemSpyDriverThreadInfo threadInfo; - User::LeaveIfError( iProcess->Engine().Driver().GetThreadInfo( iId, threadInfo ) ); - RDebug::Print( _L("CMemSpyThread::RefreshL() - old user pri: %d, curr user pri: %d, curr kernel pri: %d, iFlags: %d, name: %S"), iPriority, aThread.Priority(), threadInfo.iThreadPriority, iFlags, &threadInfo.iFullName ); -#endif - } - - // Get exit info - iExitType = handleValid ? aThread.ExitType() : EExitKill; - iPriority = handleValid ? aThread.Priority() : EPriorityNormal; - - // If the thread is dead then we may not be able to get some attributes - // (it depends on whether the thread handle is valid anymore). - iExitReason = 0; - iExitCategory.Zero(); - - if ( IsDead() ) - { - if ( handleValid ) - { - iExitReason = aThread.ExitReason(); - iExitCategory = aThread.ExitCategory(); - } - else - { - iExitCategory = KMemSpyUnknownExitCategory; - } - } - else - { - } - - // Get raw thread name - HBufC* rawThreadName = GetThreadNameLC( aThread ); - - // Full name is enough for the thread name as well as the extra info - // we show - TFullName name; - - // Build S60 listbox formatted name - _LIT( KMemSpyThreadNameFormatSpecBasicName, " \t%S\t\t" ); - name.Format( KMemSpyThreadNameFormatSpecBasicName, rawThreadName ); - CleanupStack::PopAndDestroy( rawThreadName ); - - // If the thread is dead show exit info - if ( IsDead() ) - { - AppendExitInfo( name, iExitType, iExitReason, iExitCategory ); - } - else - { - // Otherwise, show priority - AppendPriority( name, iPriority ); - } - - // Save new fully formatted name - HBufC* newName = name.AllocL(); - delete iName; - iName = newName; - } - - -HBufC* CMemSpyThread::GetThreadNameLC( const RThread& aThreadOrNull ) const - { - TName threadName; - // - const TBool handleValid = aThreadOrNull.Handle() != KNullHandle; - // - if ( handleValid ) - { - // Easy case - we have a valid thread handle. - threadName.Append( aThreadOrNull.Name() ); - } - else - { - // Since we don't have the possibility to enquire after the thread's name - // we'll assume that it used to be alive and therefore at some point we did - // manage to grep it's name... - if ( iName ) - { - const TPtrC pOriginalName( Name() ); - threadName.Append( pOriginalName ); - } - else - { - // Don't have a thread handle, don't have any possibility to get the - // name from a prior cached version. Must use "unknown" - threadName.Append( KMemSpyUnknownThreadName ); - } - } - // - HBufC* ret = threadName.AllocLC(); - return ret; - } - - -