diff -r 185201be11b0 -r 516af714ebb4 perfsrv/memspy/Driver/Kernel/Source/MemSpyDriverEventMonitor.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/perfsrv/memspy/Driver/Kernel/Source/MemSpyDriverEventMonitor.cpp Fri Sep 17 08:38:31 2010 +0300 @@ -0,0 +1,450 @@ +/* +* 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 "MemSpyDriverEventMonitor.h" + +// System includes +#include +#include + +// User includes +#include "MemSpyDriverUtils.h" +#include "MemSpyDriverDevice.h" + +#ifdef __MARM__ +#include "kdebug.h" +#endif //__MARM__ + +_LIT( KMemSpyEventMonitorMutexName, "MemSpyEventMonitor"); + + +DMemSpyEventMonitor::DMemSpyEventMonitor() +: DKernelEventHandler( EventHandler, this ) + { + } + + +DMemSpyEventMonitor::~DMemSpyEventMonitor() + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::~DMemSpyEventMonitor() - START" )); + + if ( iLock ) + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::~DMemSpyEventMonitor() - closing iLock mutex" )); + iLock->Close(NULL); + } + + if ( iDevice ) + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::~DMemSpyEventMonitor() - closing iDevice" )); + iDevice->Close(NULL); + } + + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::~DMemSpyEventMonitor() - END" )); + } + + +TInt DMemSpyEventMonitor::Create( DMemSpyDriverDevice* aDevice ) + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::Create() - START - aDevice: 0x%08x", aDevice )); + TInt err = aDevice->Open(); + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::Create() - device open err: %d", err )); + // + if (err == KErrNone ) + { + iDevice = aDevice; + // + err = Kern::MutexCreate( iLock, KMemSpyEventMonitorMutexName, KMutexOrdNone ); + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::Create() - mutex create error: %d", err )); + // + if (!err) + { + err = Add(); + } + } + // + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::Create() - END - err: %d", err )); + return err; + } + + +TInt DMemSpyEventMonitor::Start() + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::Start() - START")); + + NKern::ThreadEnterCS(); + Kern::MutexWait( *iLock ); + + iTracking = ETrue; + + Kern::MutexSignal( *iLock ); + NKern::ThreadLeaveCS(); + + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::Start() - END") ); + return KErrNone; + } + + +TInt DMemSpyEventMonitor::Stop() + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::Stop() - START") ); + + NKern::ThreadEnterCS(); + Kern::MutexWait( *iLock ); + + iTracking = EFalse; + + Kern::MutexSignal( *iLock ); + NKern::ThreadLeaveCS(); + + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::Stop() - END") ); + return KErrNone; + } + + +TInt DMemSpyEventMonitor::RequestEvents( MMemSpyEventMonitorObserver& aObserver ) + { + NKern::ThreadEnterCS(); + Kern::MutexWait( *iLock ); + + TInt error = KErrAlreadyExists; + // + if ( IsObserving( aObserver ) == EFalse ) + { + iObservers.Add( &aObserver.__iEMLink ); + error = KErrNone; + } + // + Kern::MutexSignal( *iLock ); + NKern::ThreadLeaveCS(); + // + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::RequestEvents() - END - error: %d", error) ); + return error; + } + + +TInt DMemSpyEventMonitor::RequestEventsCancel( MMemSpyEventMonitorObserver& aObserver ) + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::RequestEventsCancel() - START - aObserver: 0x%08x", &aObserver) ); + NKern::ThreadEnterCS(); + Kern::MutexWait( *iLock ); + + const TBool isObserving = IsObserving( aObserver ); + if ( isObserving ) + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::RequestEventsCancel() - dequing observer...") ); + aObserver.__iEMLink.Deque(); + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::RequestEventsCancel() - observer dequeued") ); + } + + Kern::MutexSignal( *iLock ); + NKern::ThreadLeaveCS(); + // + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::RequestEventsCancel() - END") ); + return KErrNone; + } + + +TUint DMemSpyEventMonitor::EventHandler( TKernelEvent aType, TAny* a1, TAny* a2, TAny* aSelf ) + { + DMemSpyEventMonitor* self = (DMemSpyEventMonitor*) aSelf; + const TUint ret = self->HandleEvent( aType, a1, a2 ); + return ret; + } + + +TUint DMemSpyEventMonitor::HandleEvent( TKernelEvent aType, TAny* a1, TAny* /*a2*/ ) + { + // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - PRE WAIT")); + NKern::ThreadEnterCS(); + Kern::MutexWait(*iLock); + // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - POST WAIT")); + + if ( iTracking ) + { + switch( aType ) + { + ////////////////////////////////// + // THREAD HANDLING + ////////////////////////////////// + case EEventAddThread: + { + // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - EEventAddThread")); + EventThreadAdd( (DThread*) a1 ); + break; + } + case EEventRemoveThread: + { + // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - EEventRemoveThread")); + EventThreadRemoved( (DThread*) a1 ); + break; + } + case EEventKillThread: + { + // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - EEventKillThread")); + EventThreadKilled( (DThread*) a1 ); + break; + } + + ////////////////////////////////// + // PROCESS HANDLING + ////////////////////////////////// + case EEventAddProcess: + { + // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - EEventAddProcess")); + EventProcessAdd( (DProcess*) a1 ); + break; + } + case EEventUpdateProcess: + { + // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - EEventUpdateProcess")); + EventProcessUpdate( (DProcess*) a1 ); + break; + } + case EEventRemoveProcess: + { + // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - EEventRemoveProcess")); + EventProcessRemoved( (DProcess*) a1 ); + break; + } + + ////////////////////////////////// + // CHUNK HANDLING + ////////////////////////////////// + case EEventNewChunk: + { + // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - EEventNewChunk")); + EventChunkAdd( (DChunk*) a1 ); + break; + } + case EEventUpdateChunk: + { + // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - EEventUpdateChunk")); + EventChunkUpdate( (DChunk*) a1 ); + break; + } + case EEventDeleteChunk: + { + // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - EEventDeleteChunk")); + EventChunkDelete( (DChunk*) a1 ); + break; + } + + default: + break; + } + } + + // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - PRE SIGNAL ")); + Kern::MutexSignal( *iLock ); + NKern::ThreadLeaveCS(); + // TRACE_EM( Kern::Printf("DMemSpyEventMonitor::HandleEvent() - POST SIGNAL ")); + + // Allow other handlers to see this event + return DKernelEventHandler::ERunNext; + } + + +void DMemSpyEventMonitor::EventProcessAdd( DProcess* aProcess ) + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::EventProcessAdd() - aProcess: 0x%08x [%d] (%O)", aProcess, aProcess->iId, aProcess )); + // + const SDblQueLink* const anchor = &iObservers.iA; + for (SDblQueLink* link = iObservers.First(); link != anchor; link = link->iNext) + { + MMemSpyEventMonitorObserver* const observer = _LOFF(link, MMemSpyEventMonitorObserver, __iEMLink); + const TInt typeMask = observer->EMTypeMask(); + // + if ( typeMask & EMemSpyEventProcessAdd ) + { + observer->EMHandleProcessAdd( *aProcess ); + } + } + } + + +void DMemSpyEventMonitor::EventProcessUpdate( DProcess* aProcess ) + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::EventProcessUpdate() - aProcess: 0x%08x [%d] (%O)", aProcess, aProcess->iId, aProcess )); + // + const SDblQueLink* const anchor = &iObservers.iA; + for (SDblQueLink* link = iObservers.First(); link != anchor; link = link->iNext) + { + MMemSpyEventMonitorObserver* const observer = _LOFF(link, MMemSpyEventMonitorObserver, __iEMLink); + const TInt typeMask = observer->EMTypeMask(); + // + if ( typeMask & EMemSpyEventProcessUpdate ) + { + observer->EMHandleProcessUpdated( *aProcess ); + } + } + } + + +void DMemSpyEventMonitor::EventProcessRemoved( DProcess* aProcess ) + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::EventProcessRemoved() - aProcess: 0x%08x [%d] (%O)", aProcess, aProcess->iId, aProcess )); + // + const SDblQueLink* const anchor = &iObservers.iA; + for (SDblQueLink* link = iObservers.First(); link != anchor; link = link->iNext) + { + MMemSpyEventMonitorObserver* const observer = _LOFF(link, MMemSpyEventMonitorObserver, __iEMLink); + const TInt typeMask = observer->EMTypeMask(); + // + if ( typeMask & EMemSpyEventProcessRemove ) + { + observer->EMHandleProcessRemoved( *aProcess ); + } + } + } + + +void DMemSpyEventMonitor::EventThreadAdd( DThread* aThread ) + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::EventThreadAdd() - aThread: 0x%08x [%4d] (%O)", aThread, aThread->iId, aThread )); + // + const SDblQueLink* const anchor = &iObservers.iA; + for (SDblQueLink* link = iObservers.First(); link != anchor; link = link->iNext) + { + MMemSpyEventMonitorObserver* const observer = _LOFF(link, MMemSpyEventMonitorObserver, __iEMLink); + const TInt typeMask = observer->EMTypeMask(); + // + if ( typeMask & EMemSpyEventThreadAdd ) + { + observer->EMHandleThreadAdd( *aThread ); + } + } + } + + +void DMemSpyEventMonitor::EventThreadRemoved( DThread* aThread ) + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::EventThreadRemoved() - aThread: 0x%08x [%4d] (%O)", aThread, aThread->iId, aThread )); + // + const SDblQueLink* const anchor = &iObservers.iA; + for (SDblQueLink* link = iObservers.First(); link != anchor; link = link->iNext) + { + MMemSpyEventMonitorObserver* const observer = _LOFF(link, MMemSpyEventMonitorObserver, __iEMLink); + const TInt typeMask = observer->EMTypeMask(); + // + if ( typeMask & EMemSpyEventThreadRemove ) + { + observer->EMHandleThreadRemoved( *aThread ); + } + } + } + + +void DMemSpyEventMonitor::EventThreadKilled( DThread* aThread ) + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::EventThreadKilled() - aThread: 0x%08x [%4d] (%O)", aThread, aThread->iId, aThread )); + // + const SDblQueLink* const anchor = &iObservers.iA; + for (SDblQueLink* link = iObservers.First(); link != anchor; link = link->iNext) + { + MMemSpyEventMonitorObserver* const observer = _LOFF(link, MMemSpyEventMonitorObserver, __iEMLink); + const TInt typeMask = observer->EMTypeMask(); + // + if ( typeMask & EMemSpyEventThreadKill ) + { + observer->EMHandleThreadKilled( *aThread ); + } + } + } + + +void DMemSpyEventMonitor::EventChunkAdd( DChunk* aChunk ) + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::EventChunkAdd() - aChunk: 0x%08x [%10d] {OP: %4d, CO: %4d} (%O)", aChunk, aChunk->Size(), ( aChunk->iOwningProcess ? aChunk->iOwningProcess->iId : 0 ), aChunk->iControllingOwner, aChunk )); + // + const SDblQueLink* const anchor = &iObservers.iA; + for (SDblQueLink* link = iObservers.First(); link != anchor; link = link->iNext) + { + MMemSpyEventMonitorObserver* const observer = _LOFF(link, MMemSpyEventMonitorObserver, __iEMLink); + const TInt typeMask = observer->EMTypeMask(); + // + if ( typeMask & EMemSpyEventChunkAdd ) + { + observer->EMHandleChunkAdd( *aChunk ); + } + } + } + + +void DMemSpyEventMonitor::EventChunkUpdate( DChunk* aChunk ) + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::EventChunkUpdate() - aChunk: 0x%08x [%10d] {OP: %4d, CO: %4d} (%O)", aChunk, aChunk->Size(), ( aChunk->iOwningProcess ? aChunk->iOwningProcess->iId : 0 ), aChunk->iControllingOwner, aChunk )); + // + const SDblQueLink* const anchor = &iObservers.iA; + for (SDblQueLink* link = iObservers.First(); link != anchor; link = link->iNext) + { + MMemSpyEventMonitorObserver* const observer = _LOFF(link, MMemSpyEventMonitorObserver, __iEMLink); + const TInt typeMask = observer->EMTypeMask(); + // + if ( typeMask & EMemSpyEventChunkUpdate ) + { + observer->EMHandleChunkUpdated( *aChunk ); + } + } + } + + +void DMemSpyEventMonitor::EventChunkDelete( DChunk* aChunk ) + { + TRACE_EM( Kern::Printf("DMemSpyEventMonitor::EventChunkDelete() - aChunk: 0x%08x [%10d] {OP: %4d, CO: %4d} (%O)", aChunk, aChunk->Size(), ( aChunk->iOwningProcess ? aChunk->iOwningProcess->iId : 0 ), aChunk->iControllingOwner, aChunk )); + // + const SDblQueLink* const anchor = &iObservers.iA; + for (SDblQueLink* link = iObservers.First(); link != anchor; link = link->iNext) + { + MMemSpyEventMonitorObserver* const observer = _LOFF(link, MMemSpyEventMonitorObserver, __iEMLink); + const TInt typeMask = observer->EMTypeMask(); + // + if ( typeMask & EMemSpyEventChunkDelete ) + { + observer->EMHandleChunkDeleted( *aChunk ); + } + } + } + + + + + + + + + + +TBool DMemSpyEventMonitor::IsObserving( MMemSpyEventMonitorObserver& aObserver ) + { + TBool ret = EFalse; + const SDblQueLink* const anchor = &iObservers.iA; + + for (SDblQueLink* link = iObservers.First(); link != anchor; link = link->iNext) + { + MMemSpyEventMonitorObserver* const observer = _LOFF(link, MMemSpyEventMonitorObserver, __iEMLink); + + if ( observer == &aObserver ) + { + ret = ETrue; + break; + } + } + + return ret; + } +