diff -r 000000000000 -r c6b0df440bee dbgagents/trkagent/eka2driver/TrkEventHandler.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/dbgagents/trkagent/eka2driver/TrkEventHandler.cpp Tue Mar 02 10:33:16 2010 +0530 @@ -0,0 +1,398 @@ +/* +* Copyright (c) 2004 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 +#include +#include +#include +#include +#include + +#include "TrkKernelDriver.h" +#include "TrkDriver.h" +#include "TrkEventHandler.h" + + +DMetroTrkEventHandler::DMetroTrkEventHandler() + : DKernelEventHandler(EventHandler, this) +{ + LOG_MSG("DMetroTrkEventHandler::DMetroTrkEventHandler()"); + +} + + +TInt DMetroTrkEventHandler::Create(DLogicalDevice* aDevice, DLogicalChannel* aChannel, DThread* aClient) +{ + LOG_MSG("DMetroTrkEventHandler::Create()"); + + TInt err; + err = aDevice->Open(); + if (err != KErrNone) + return err; + iDevice = aDevice; + + iChannel = aChannel; //Don't add ref the channel, since channel closes the event handler before it ever gets destroyed. + + err = aClient->Open(); + if (err != KErrNone) + return err; + iClientThread = aClient; + + // Use a semaphore to protect our data structures from concurrent access. + err = Kern::SemaphoreCreate(iLock, _L("TrkEventHandlerLock"), 1 /* Initial count */); + + if (err != KErrNone) + return err; + + return Add(); +} + + +DMetroTrkEventHandler::~DMetroTrkEventHandler() +{ + LOG_MSG("DMetroTrkEventHandler::~DMetroTrkEventHandler()"); + + if (iLock) + iLock->Close(NULL); + + if (iDevice) + iDevice->Close(NULL); + + if (iClientThread) + Kern::SafeClose((DObject*&)iClientThread, NULL); + +} + + +TInt DMetroTrkEventHandler::Start() +{ + LOG_MSG("DMetroTrkEventHandler::Start()"); + + TInt r = KErrNone; + iTracking = ETrue; + return r; +} + + +TInt DMetroTrkEventHandler::Stop() +{ + LOG_MSG("DMetroTrkEventHandler::Stop()"); + + //NKern::ThreadEnterCS(); + //Kern::SemaphoreWait(*iLock); + iTracking = EFalse; + //Kern::SemaphoreSignal(*iLock); + //NKern::ThreadLeaveCS(); + + return KErrNone; +} + + +TUint DMetroTrkEventHandler::EventHandler(TKernelEvent aType, TAny* a1, TAny* a2, TAny* aThis) +{ + return ((DMetroTrkEventHandler*)aThis)->HandleEvent(aType, a1, a2); +} + +TUint DMetroTrkEventHandler::HandleEvent(TKernelEvent aType, TAny* a1, TAny* a2) +{ + if (iTracking) + { + iCounters[aType]++; + switch (aType) + { + case EEventSwExc: + { + if (HandleSwException((TExcType)(TInt)a1)) + return (TUint)DKernelEventHandler::EExcHandled; + } + + case EEventHwExc: + { + if (HandleHwException((TArmExcInfo*)a1)) + return (TUint)DKernelEventHandler::EExcHandled; + } + case EEventUpdateProcess: + case EEventAddThread: + case EEventUpdateThread: + case EEventRemoveThread: + case EEventNewChunk: + case EEventDeleteChunk: + //currently we don't handle any of these events; + break; + case EEventAddProcess: + { + AddProcess((DProcess*)a1, (DThread*)a2); + break; + } + case EEventRemoveProcess: + { + RemoveProcess((DProcess*)a1); + break; + } + case EEventStartThread: + { + StartThread((DThread*)a1); + break; + } + // According to Symbian, the only way to catch panics in EKA2 is through this event. + case EEventKillThread: + { + if (HandleEventKillThread((DThread*)a1)) + return (TUint)DKernelEventHandler::EExcHandled; + break; + } + case EEventAddLibrary: + { + AddLibrary((DLibrary*)a1, (DThread*)a2); + break; + } + + case EEventRemoveLibrary: + { + RemoveLibrary((DLibrary*)a1); + break; + } + + case EEventUserTrace: + { + HandleUserTrace((TText*)a1, (TInt)a2); + break; + } + case EEventAddCodeSeg: + { + // + // EventAddCodeSeg is not fired for all libs, for example, if a static lib is in ROM, + // then you don't need get AddCodeSeg event for that lib. + // + //AddCodeSegment((DCodeSeg*)a1, (DProcess*)a2); + break; + } + case EEventRemoveCodeSeg: + { + // RemoveCodeSegment((DCodeSeg*)a1, (DProcess*)a2); + break; + } + default: + break; + } + } + return DKernelEventHandler::ERunNext; +} + +// +// DMetroTrkEventHandler::HandleEventKillThread +// + +TBool DMetroTrkEventHandler::HandleEventKillThread(DThread* aThread) +{ + LOG_MSG("DMetroTrkEventHandler::HandleEventKillThread()"); + + //NKern::ThreadEnterCS(); + //Kern::SemaphoreWait(*iLock); + + TBool ret = ((DMetroTrkChannel*)iChannel)->HandleEventKillThread(aThread); + + //Kern::SemaphoreSignal(*iLock); + //NKern::ThreadLeaveCS(); + + return ret; +} + + +// +// DMetroTrkEventHandler::HandleSwException +// + +TBool DMetroTrkEventHandler::HandleSwException(TExcType aExcType) +{ + LOG_MSG("DMetroTrkEventHandler::HandleSwException()"); + + NKern::ThreadEnterCS(); + Kern::SemaphoreWait(*iLock); + + TBool ret = ((DMetroTrkChannel*)iChannel)->HandleSwException(aExcType); + + Kern::SemaphoreSignal(*iLock); + NKern::ThreadLeaveCS(); + + return ret; +} + +// +// DMetroTrkEventHandler::HandleHwException +// + +TBool DMetroTrkEventHandler::HandleHwException(TArmExcInfo* aExcInfo) +{ + LOG_MSG("DMetroTrkEventHandler::HandleHwException()"); + + TBool ret = EFalse; + + NKern::ThreadEnterCS(); + Kern::SemaphoreWait(*iLock); + + if (aExcInfo) + { + ret = ((DMetroTrkChannel*)iChannel)->HandleHwException(aExcInfo); + } + + Kern::SemaphoreSignal(*iLock); + NKern::ThreadLeaveCS(); + + return ret; +} + +// +// DMetroTrkEventHandler::HandleUserTrace +// +TBool DMetroTrkEventHandler::HandleUserTrace(TText* aStr, TInt aLen) +{ + LOG_MSG("DMetroTrkEventHandler::HandleUserTrace()"); + TBool ret = EFalse; + + NKern::ThreadEnterCS(); + Kern::SemaphoreWait(*iLock); + + if (aStr && aLen > 0) + { + ret = ((DMetroTrkChannel*)iChannel)->HandleUserTrace(aStr, aLen); + } + + Kern::SemaphoreSignal(*iLock); + NKern::ThreadLeaveCS(); + + return ret; +} + +// +// DMetroTrkEventHandler::AddProcess +// +void DMetroTrkEventHandler::AddProcess(DProcess* aProcess, DThread *aThread) +{ + LOG_MSG("DMetroTrkEventHandler::AddProcess()"); + + NKern::ThreadEnterCS(); + Kern::SemaphoreWait(*iLock); + + if (iChannel && aProcess && aThread) + ((DMetroTrkChannel*)iChannel)->AddProcess(aProcess, aThread); + + Kern::SemaphoreSignal(*iLock); + NKern::ThreadLeaveCS(); +} + +// +// DMetroTrkEventHandler::StartThread +// +void DMetroTrkEventHandler::StartThread(DThread *aThread) +{ + LOG_MSG("DMetroTrkEventHandler::StartThread()"); + + NKern::ThreadEnterCS(); + Kern::SemaphoreWait(*iLock); + + if (iChannel && aThread) + ((DMetroTrkChannel*)iChannel)->StartThread(aThread); + + Kern::SemaphoreSignal(*iLock); + NKern::ThreadLeaveCS(); +} +// +// DMetroTrkEventHandler::RemoveProcess +// +void DMetroTrkEventHandler::RemoveProcess(DProcess *aProcess) +{ + LOG_MSG("DMetroTrkEventHandler::RemoveProcess()"); + + NKern::ThreadEnterCS(); + Kern::SemaphoreWait(*iLock); + + if (iChannel && aProcess) + ((DMetroTrkChannel*)iChannel)->RemoveProcess(aProcess); + + Kern::SemaphoreSignal(*iLock); + NKern::ThreadLeaveCS(); +} + +// +// DMetroTrkEventHandler::AddLibrary +// +void DMetroTrkEventHandler::AddLibrary(DLibrary *aLibrary, DThread *aThread) +{ + LOG_MSG("DMetroTrkEventHandler::AddLibrary()"); + + NKern::ThreadEnterCS(); + Kern::SemaphoreWait(*iLock); + + if (iChannel && aLibrary) + ((DMetroTrkChannel*)iChannel)->AddLibrary(aLibrary, aThread); + + Kern::SemaphoreSignal(*iLock); + NKern::ThreadLeaveCS(); +} + +// +// DMetroTrkEventHandler::RemoveLibrary +// +void DMetroTrkEventHandler::RemoveLibrary(DLibrary *aLibrary) +{ + LOG_MSG("DMetroTrkEventHandler::RemoveLibrary()"); + + NKern::ThreadEnterCS(); + Kern::SemaphoreWait(*iLock); + + if (iChannel && aLibrary) + ((DMetroTrkChannel*)iChannel)->RemoveLibrary(aLibrary); + + Kern::SemaphoreSignal(*iLock); + NKern::ThreadLeaveCS(); +} + +// +// DMetroTrkEventHandler::AddCodeSegment +// +void DMetroTrkEventHandler::AddCodeSegment(DCodeSeg *aCodeSeg, DProcess *aProcess) +{ + LOG_MSG("DMetroTrkEventHandler::AddCodeSegment()"); + + NKern::ThreadEnterCS(); + Kern::SemaphoreWait(*iLock); + + if (iChannel && aCodeSeg && aProcess) + ((DMetroTrkChannel*)iChannel)->AddCodeSegment(aCodeSeg, aProcess); + + Kern::SemaphoreSignal(*iLock); + NKern::ThreadLeaveCS(); +} + +// +// DMetroTrkEventHandler::RemoveCodeSegment +// +void DMetroTrkEventHandler::RemoveCodeSegment(DCodeSeg *aCodeSeg, DProcess *aProcess) +{ + LOG_MSG("DMetroTrkEventHandler::RemoveCodeSegment()"); + + NKern::ThreadEnterCS(); + Kern::SemaphoreWait(*iLock); + + if (iChannel && aCodeSeg && aProcess) + ((DMetroTrkChannel*)iChannel)->RemoveCodeSegment(aCodeSeg, aProcess); + + Kern::SemaphoreSignal(*iLock); + NKern::ThreadLeaveCS(); +}