memspy/Driver/Kernel/Source/MemSpyDriverEventMonitor.cpp
changeset 0 a03f92240627
child 20 ca8a1b6995f6
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/memspy/Driver/Kernel/Source/MemSpyDriverEventMonitor.cpp	Tue Feb 02 01:57:15 2010 +0200
@@ -0,0 +1,448 @@
+/*
+* 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 <kern_priv.h>
+#include <nk_trace.h>
+
+// 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"));
+	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 );
+	// 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;
+    }
+