--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/analyzetool/kerneleventhandler/src/analyzetooleventhandler.cpp Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,427 @@
+/*
+* 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: Definitions for the class DAnalyzeToolEventHandler.
+*
+*/
+
+
+// INCLUDE FILES
+#include "analyzetooleventhandler.h"
+#include <kernel/kern_priv.h>
+
+// CONSTANTS
+
+// The handler mutex literal
+_LIT( KHandlerMutexName, "AnalyzeToolHandlerMutex" );
+
+// The handle data mutex literal
+_LIT( KDataMutexName, "AnalyzeToolDataMutex" );
+
+
+// ================= MEMBER FUNCTIONS =========================================
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::Create()
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+TInt DAnalyzeToolEventHandler::Create( DLogicalDevice* aDevice,
+ const TUint aProcessId )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::Create()" );
+ TInt ret( KErrNone );
+
+ // Store owner process ID
+ iProcessId = aProcessId;
+ LOGSTR2( "ATDD DAnalyzeToolEventHandler::Create > iProcessId %d",
+ iProcessId );
+
+ // Open the device
+ ret = aDevice->Open();
+ if ( ret != KErrNone )
+ return ret;
+ iDevice = aDevice;
+
+ // Create mutex for the handler
+ ret = Kern::MutexCreate( iHandlerMutex, KHandlerMutexName, KMutexOrdDebug );
+ if ( ret != KErrNone )
+ return ret;
+ // Create mutex for the data
+ ret = Kern::MutexCreate( iDataMutex, KDataMutexName, KMutexOrdDebug-1 );
+ if ( ret != KErrNone )
+ return ret;
+
+ // Add handler to the handler queue
+ return Add();
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::~DAnalyzeToolEventHandler()
+// C++ default constructor.
+// -----------------------------------------------------------------------------
+//
+DAnalyzeToolEventHandler::~DAnalyzeToolEventHandler()
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::~DAnalyzeToolEventHandler()" );
+
+ CancelInformLibraryEvent();
+
+ // Close the data mutex
+ if ( iDataMutex )
+ {
+ iDataMutex->Close( NULL );
+ }
+
+ // Close the handler mutex
+ if ( iHandlerMutex )
+ {
+ iHandlerMutex->Close( NULL );
+ }
+
+ // Close the device mutex
+ if ( iDevice )
+ {
+ iDevice->Close( NULL );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::EventHandler()
+// Function for receiving kernel events
+// -----------------------------------------------------------------------------
+//
+TUint DAnalyzeToolEventHandler::EventHandler( TKernelEvent aEvent,
+ TAny* a1, TAny* a2, TAny* aThis )
+ {
+
+ // Clarify the event type
+ switch ( aEvent)
+ {
+ case EEventRemoveLibrary:
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventRemoveLibrary" );
+ // Cast the pointer to the handler
+ DAnalyzeToolEventHandler* handler =
+ ( ( DAnalyzeToolEventHandler* ) aThis );
+ // Create variable for library information
+ TLibraryEventInfo info;
+ // Set as library remove event
+ info.iEventType = TLibraryEventInfo::ELibraryRemoved;
+ // Handle the event
+ handler->HandleLibraryEvent( ( DLibrary* ) a1, ( DThread* ) a2, info );
+ break;
+ }
+ case EEventAddLibrary:
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventAddLibrary" );
+ // Cast the pointer to the handler
+ DAnalyzeToolEventHandler* handler =
+ ( ( DAnalyzeToolEventHandler* ) aThis );
+ // Create variable for library information
+ TLibraryEventInfo info;
+ // Set as library remove event
+ info.iEventType = TLibraryEventInfo::ELibraryAdded;
+ // Handle the event
+ handler->HandleLibraryEvent( ( DLibrary* ) a1, ( DThread* ) a2, info );
+ break;
+ }
+ case EEventHwExc:
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventHwExc" );
+ break;
+ }
+ case EEventSwExc:
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventSwExc" );
+ break;
+ }
+ case EEventRemoveThread:
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventRemoveThread" );
+ break;
+ }
+ case EEventKillThread:
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventKillThread" );
+
+ // Cast the pointer to the handler
+ DAnalyzeToolEventHandler* handler =
+ ( ( DAnalyzeToolEventHandler* ) aThis );
+
+ // Create variable for library information
+ TLibraryEventInfo info;
+
+ // Set as kill thread event
+ info.iEventType = TLibraryEventInfo::EKillThread;
+ // Handle the event
+ handler->HandleKillThreadEvent( ( DThread* ) a1, info );
+ break;
+ }
+ default:
+ {
+ }
+ break;
+ }
+ return ERunNext;
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::HandleLibraryEvent()
+// Handles the EEventAddLibrary and EEventRemoveLibrary events.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::HandleLibraryEvent( DLibrary* aLib,
+ DThread* aThread, TLibraryEventInfo& aInfo )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::HandleLibraryEvent()" );
+
+ // Aqcuire the handler mutex
+ Kern::MutexWait( *iHandlerMutex );
+
+ // Aqcuire the data mutex
+ Kern::MutexWait( *iDataMutex );
+
+ TBool addInfo( EFalse );
+
+ // Check the library event type
+ if ( aInfo.iEventType == TLibraryEventInfo::ELibraryAdded )
+ {
+ if ( aThread != NULL )
+ {
+ if ( iProcessId == aThread->iOwningProcess->iId )
+ {
+ LOGSTR1( "ATDD > Process id match" );
+ aInfo.iProcessId = aThread->iOwningProcess->iId;
+ addInfo = ETrue;
+ }
+ }
+ }
+ else if ( aInfo.iEventType == TLibraryEventInfo::ELibraryRemoved )
+ {
+ if ( aThread != NULL )
+ {
+ aInfo.iProcessId = aThread->iOwningProcess->iId;
+ }
+ else
+ {
+ aInfo.iProcessId = 0;
+ }
+ addInfo = ETrue;
+ }
+
+ if ( addInfo )
+ {
+ // Store lib info
+ aLib->AppendName( aInfo.iLibraryName );//lint !e64 !e1514
+ aInfo.iSize = aLib->iCodeSeg->iSize;
+ aInfo.iRunAddress = aLib->iCodeSeg->iRunAddress;
+ // Store library event info to the array
+ iEventArray.Append( aInfo );
+ LOGSTR2( "ATDD > iEventArray.Count() = %d", iEventArray.Count() );
+
+ // if client has subscribed the event it is queued
+ if ( iClientThread != NULL )
+ {
+ iEventDfc.Enque();
+ }
+ }
+
+ // Release the data mutex
+ Kern::MutexSignal( *iDataMutex );
+
+ // Release the handler mutex
+ Kern::MutexSignal( *iHandlerMutex );
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::InformLibraryEvent()
+// Subscribes library event.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::InformLibraryEvent( TRequestStatus* aStatus,
+ TAny* aLibraryInfo,
+ TThreadMessage& aMessage )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::InformLibraryEvent()" );
+
+ // Aqcuire the data mutex
+ Kern::MutexWait( *iDataMutex );
+
+ // Check if request from client which is already pending
+ DThread* current = aMessage.Client();
+
+ LOGSTR2( "ATDD > Current Thread ID = %d", current->iId );
+
+ // Ensure that client doesn't subscribe service when there is a pending
+ // subscription
+ if ( NULL != iClientThread )
+ {
+ aMessage.PanicClient( KClientPanic, EPanicRequestPending );
+ }
+ else
+ {
+ // Store the client variable pointers
+ iClientThread = current;
+ iClientRequestStatus = aStatus;
+ iClientInfo = aLibraryInfo;
+ }
+
+ // Release the data mutex
+ Kern::MutexSignal( *iDataMutex );
+
+ // Queue the event since now the client has subscribed it
+ iEventDfc.Enque();
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::CancelInformLibraryEvent
+// Cancels subscription of the library event.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::CancelInformLibraryEvent()
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::CancelInformLibraryEvent()" );
+
+ iEventDfc.Cancel();
+
+ // Aqcuire the data mutex
+ Kern::MutexWait( *iDataMutex );
+
+ if ( NULL != iClientThread && iEventArray.Count() > 0 )
+ {
+ // Signal the request as complete
+ Kern::RequestComplete( iClientThread,
+ iClientRequestStatus,
+ KErrCancel );
+
+ iClientThread = NULL;
+ iClientRequestStatus = NULL;
+ iClientInfo = NULL;
+
+ // Reset the event array
+ iEventArray.Reset();
+ }
+
+ // Release the data mutex
+ Kern::MutexSignal( *iDataMutex );
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::HandleKillThreadEvent()
+// Handles the EEventKillThread events.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::HandleKillThreadEvent( DThread* aThread,
+ TLibraryEventInfo& aInfo )
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::HandleKillThreadEvent()" );
+
+ // Aqcuire the handler mutex
+ Kern::MutexWait( *iHandlerMutex );
+
+ // Aqcuire the data mutex
+ Kern::MutexWait( *iDataMutex );
+
+ aInfo.iProcessId = aThread->iOwningProcess->iId;
+ TBool alone( aThread->iOwningProcess->iThreadQ.First()->Alone() );
+ LOGSTR2( "ATDD > Is alone = %d", alone );
+
+ // Check if this our process and is the only thread item.
+ if ( aInfo.iProcessId == iProcessId && !alone )
+ {
+ if ( aThread )
+ {
+ // Set current Thread id
+ LOGSTR2( "ATDD > Thread ID = %d", aThread->iId );
+ aInfo.iThreadId = aThread->iId;
+ // Append event to array (beginning of the array)
+ iEventArray.Insert( aInfo, 0 );
+
+ // if client has subscribed the event it is queued
+ if ( iClientThread != NULL )
+ {
+ iEventDfc.Enque();
+ }
+ }
+ }
+
+ // Release the data mutex
+ Kern::MutexSignal( *iDataMutex );
+
+ // Release the handler mutex
+ Kern::MutexSignal( *iHandlerMutex );
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::DoEventComplete()
+// Informs client about the occured event.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::DoEventComplete()
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::DoEventComplete()" );
+
+ // Aqcuire the handler mutex
+ Kern::MutexWait( *iHandlerMutex );
+
+ // Aqcuire the data mutex
+ Kern::MutexWait( *iDataMutex );
+
+ if ( NULL != iClientThread && iEventArray.Count() > 0 )
+ {
+ TInt ret = Kern::ThreadRawWrite( iClientThread,
+ iClientInfo,
+ &iEventArray[0],
+ sizeof( iEventArray[0] ) );
+
+ LOGSTR2( "ATDD > ThreadRawWrite err = %d", ret );
+
+ // Signal the request as complete
+ Kern::RequestComplete( iClientThread,
+ iClientRequestStatus,
+ ret );
+
+ // Remove first item to array
+ iEventArray.Remove( 0 );
+
+ // Compresses the array down to a minimum
+ iEventArray.Compress();
+
+ // Ensure that pointers are set to NULL
+ iClientThread = NULL;
+ iClientRequestStatus = NULL;
+ iClientInfo = NULL;
+
+ LOGSTR2( "ATDD > iEventArray = %d", iEventArray.Count() );
+ }
+
+ // Release the data mutex
+ Kern::MutexSignal( *iDataMutex );
+
+ // Release the handler mutex
+ Kern::MutexSignal( *iHandlerMutex );
+ }
+
+// -----------------------------------------------------------------------------
+// DAnalyzeToolEventHandler::EventDfc()
+// Static function for DFC events.
+// -----------------------------------------------------------------------------
+//
+void DAnalyzeToolEventHandler::EventDfc(TAny* aPtr)
+ {
+ LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventDfc()" );
+ ( (DAnalyzeToolEventHandler*) aPtr )->DoEventComplete();
+ }
+
+// End of File