diff -r 0ff24a8f6ca2 -r 98307c651589 memspy/Driver/Kernel/Source/MemSpyDriverUserEventMonitor.cpp --- a/memspy/Driver/Kernel/Source/MemSpyDriverUserEventMonitor.cpp Fri Aug 27 11:37:29 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,429 +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 "MemSpyDriverUserEventMonitor.h" - -// System includes -#include - -// User includes -#include "MemSpyDriverUtils.h" -#include "MemSpyDriverDevice.h" -#include "MemSpyDriverOSAdaption.h" -#include "MemSpyDriverEventMonitor.h" - -// Literal constants -_LIT( KMemSpyDriverClientEMMutexName, "MemSpyDriverClientEM_0x" ); - - - - -DMemSpyDriverClientEMManager::DMemSpyDriverClientEMManager( DMemSpyDriverDevice& aDevice ) -: iDevice( aDevice ) - { - } - - -DMemSpyDriverClientEMManager::~DMemSpyDriverClientEMManager() - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::~DMemSpyDriverClientEMManager() - START")); - - NKern::ThreadEnterCS(); - FreeAllInstances(); - NKern::ThreadLeaveCS(); - - TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::~DMemSpyDriverClientEMManager() - END")); - } - - -TInt DMemSpyDriverClientEMManager::Create() - { - return KErrNone; - } - - -DMemSpyDriverClientEM* DMemSpyDriverClientEMManager::EMOpen() - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::EMOpen() - START - iNextHandle: %d, iDevice: 0x%08x", iNextHandle+1, &iDevice ) ); - NKern::ThreadEnterCS(); - // - DMemSpyDriverClientEM* object = new DMemSpyDriverClientEM( iDevice, ++iNextHandle ); - if ( object != NULL ) - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::EMOpen() - calling create..." ) ); - const TInt error = object->Create(); - if ( error != KErrNone ) - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::EMOpen() - creation error: %d", error ) ); - delete object; - object = NULL; - } - else - { - iEMInstances.Add( &object->iLink ); - } - } - // - NKern::ThreadLeaveCS(); - TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::EMOpen() - END - object: 0x%08x", object ) ); - // - return object; - } - - -TInt DMemSpyDriverClientEMManager::EMClose( TUint aHandle ) - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::EMClose() - START - aHandle: 0x%08x", aHandle ) ); - TInt error = KErrNotFound; - // - DMemSpyDriverClientEM* object = EMInstance( aHandle ); - if ( object != NULL ) - { - NKern::ThreadEnterCS(); - object->iLink.Deque(); - delete object; - NKern::ThreadLeaveCS(); - error = KErrNone; - } - // - TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::EMClose() - END - error: %d", error ) ); - return error; - } - - -DMemSpyDriverClientEM* DMemSpyDriverClientEMManager::EMInstance( TUint aHandle ) - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::EMInstance() - START - aHandle: 0x%08x", aHandle ) ); - DMemSpyDriverClientEM* ret = NULL; - // - const SDblQueLink* const anchor = &iEMInstances.iA; - for (SDblQueLink* link = iEMInstances.First(); link != anchor; link = link->iNext ) - { - DMemSpyDriverClientEM* object = _LOFF( link, DMemSpyDriverClientEM, iLink ); - // - if ( object->Handle() == aHandle ) - { - ret = object; - break; - } - } - // - TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::EMInstance() - END - aHandle: 0x%08x, ret: 0x%08x", aHandle, ret ) ); - return ret; - } - - -void DMemSpyDriverClientEMManager::FreeAllInstances() - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::FreeAllInstances() - START") ); - - SDblQueLink* link = iEMInstances.GetFirst(); - while( link ) - { - DMemSpyDriverClientEM* object = _LOFF( link, DMemSpyDriverClientEM, iLink ); - delete object; - link = iEMInstances.GetFirst(); - } - - TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::FreeAllInstances() - END") ); - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -DMemSpyDriverClientEM::DMemSpyDriverClientEM( DMemSpyDriverDevice& aDevice, TUint aHandle ) -: iDevice( aDevice ), iHandle( aHandle ) - { - } - - -DMemSpyDriverClientEM::~DMemSpyDriverClientEM() - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::~DMemSpyDriverClientEM() - START - this: 0x%08x", this )); - iDevice.EventMonitor().RequestEventsCancel( *this ); - - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::~DMemSpyDriverClientEM() - calling NotifyChangesCancel..." ) ); - NotifyChangesCancel(); - - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::~DMemSpyDriverClientEM() - calling ResetPendingChanges..." ) ); - ResetPendingChanges(); - - if ( iLock ) - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::~DMemSpyDriverClientEM() - closing mutex..." ) ); - iLock->Close(NULL); - } - - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::~DMemSpyDriverClientEM() - END - this: 0x%08x" )); - } - - -TInt DMemSpyDriverClientEM::Create() - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::Create() - START - handle: 0x%08x", Handle() ) ); - - // Create mutex - TName name( KMemSpyDriverClientEMMutexName ); - name.AppendNumFixedWidth( (TUint) this, EHex, 8 ); - TInt error = Kern::MutexCreate( iLock, name, KMutexOrdNone ); - // - if ( error == KErrNone ) - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::Create() - calling global device driver event monitor...") ); - iDevice.EventMonitor().RequestEvents( *this ); - } - // - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::Create() - END - handle: 0x%08x, err: %d", Handle(), error ) ); - return error; - } - - -TInt DMemSpyDriverClientEM::NotifyChanges( DThread* aClientThread, TRequestStatus* aClientRS, TAny* aClientContext ) - { - Kern::MutexWait( *iLock ); - - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::NotifyChanges() - START - handle: 0x%08x", Handle() ) ); - TInt r = KErrInUse; - // - if ( iClientRS == NULL ) - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::NotifyChanges() - saving client's request...") ); - iClientThread = aClientThread; - iClientRS = aClientRS; - iClientContext = aClientContext; - // - if ( !iPendingChanges.IsEmpty() ) - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::NotifyOnChange() - Have buffered changes - SENDING TO CLIENT IMMEDIATELY..." ) ); - - // We have something in the pending buffer so we can - // give it back to the client immediately. - DMemSpyDriverClientEM::TChange* cachedChange = _LOFF( iPendingChanges.First(), DMemSpyDriverClientEM::TChange, iLink ); - cachedChange->iLink.Deque(); - - // Notify about change - CompleteClientsRequest( cachedChange->iCompletionCode, cachedChange->iContext ); - - // Discard cached entry - NKern::ThreadEnterCS(); - delete cachedChange; - NKern::ThreadLeaveCS(); - } - // - r = KErrNone; - } - // - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::NotifyChanges() - END - handle: 0x%08x, error: %d", Handle(), r ) ); - Kern::MutexSignal( *iLock ); - return r; - } - - -TInt DMemSpyDriverClientEM::NotifyChangesCancel() - { - Kern::MutexWait( *iLock ); - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::NotifyChangesCancel() - START - handle: 0x%08x, iClientThread: 0x%08x, iClientRS: 0x%08x", Handle(), iClientThread, iClientRS ) ); - // - TInt r = KErrNotReady; - // - if ( iClientRS != NULL ) - { - DThread* clientThread = iClientThread; - TRequestStatus* clientRS = iClientRS; - // - iClientThread = NULL; - iClientRS = NULL; - iClientContext = NULL; - // - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::NotifyChangesCancel() - doing final request complete...") ); - Kern::RequestComplete( clientThread, clientRS, KErrCancel ); - r = KErrNone; - } - // - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::NotifyChangesCancel() - END - handle: 0x%08x, error: %d", Handle(), r ) ); - Kern::MutexSignal( *iLock ); - return r; - } - - -TUint DMemSpyDriverClientEM::EMTypeMask() const - { - const TUint ret = EMemSpyEventThreadAdd | EMemSpyEventThreadKill | - EMemSpyEventProcessAdd | EMemSpyEventProcessRemove | - EMemSpyEventChunkAdd | EMemSpyEventChunkDelete; - return ret; - } - - -void DMemSpyDriverClientEM::EMHandleProcessAdd( DProcess& aProcess ) - { - const TUint pid = iDevice.OSAdaption().DProcess().GetId( aProcess ); - // - Kern::MutexWait( *iLock ); - CompleteClientsRequest( EMemSpyDriverEventTypeProcessCreate, pid ); - Kern::MutexSignal( *iLock ); - } - - -void DMemSpyDriverClientEM::EMHandleProcessRemoved( DProcess& aProcess ) - { - const TUint pid = iDevice.OSAdaption().DProcess().GetId( aProcess ); - // - Kern::MutexWait( *iLock ); - CompleteClientsRequest( EMemSpyDriverEventTypeProcessRemove, pid ); - Kern::MutexSignal( *iLock ); - } - - -void DMemSpyDriverClientEM::EMHandleThreadAdd( DThread& aThread ) - { - const TUint tid = iDevice.OSAdaption().DThread().GetId( aThread ); - // - Kern::MutexWait( *iLock ); - CompleteClientsRequest( EMemSpyDriverEventTypeThreadCreate, tid ); - Kern::MutexSignal( *iLock ); - } - - -void DMemSpyDriverClientEM::EMHandleThreadKilled( DThread& aThread ) - { - const TUint tid = iDevice.OSAdaption().DThread().GetId( aThread ); - // - Kern::MutexWait( *iLock ); - CompleteClientsRequest( EMemSpyDriverEventTypeThreadKill, tid ); - Kern::MutexSignal( *iLock ); - } - - -void DMemSpyDriverClientEM::EMHandleChunkAdd( DChunk& aChunk ) - { - Kern::MutexWait( *iLock ); - CompleteClientsRequest( EMemSpyDriverEventTypeChunkAdd, (TUint) &aChunk ); - Kern::MutexSignal( *iLock ); - } - - -void DMemSpyDriverClientEM::EMHandleChunkDeleted( DChunk& aChunk ) - { - Kern::MutexWait( *iLock ); - CompleteClientsRequest( EMemSpyDriverEventTypeChunkDestroy, (TUint) &aChunk ); - Kern::MutexSignal( *iLock ); - } - - -void DMemSpyDriverClientEM::CompleteClientsRequest( TInt aCompletionCode, TUint aContext ) - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::CompleteClientsRequest() - START - handle: 0x%08x, iClientThread: 0x%08x, iClientRS: 0x%08x, iClientContext: 0x%08x, aCompletionCode: %d, aContext: %d, changesPending: %d", Handle(), iClientThread, iClientRS, iClientContext, aCompletionCode, aContext, !iPendingChanges.IsEmpty() ) ); - // - if ( iClientRS != NULL ) - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::CompleteClientsRequest() - attempting to complete client's request...") ); - - // First write context info - const TInt writeErr = Kern::ThreadRawWrite( iClientThread, iClientContext, &aContext, sizeof(TUint) ); - if ( writeErr != KErrNone ) - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::CompleteClientsRequest() - write error: %d", writeErr ) ); - aCompletionCode = writeErr; - } - - // Now complete event - avoiding race conditions! - DThread* clientThread = iClientThread; - TRequestStatus* clientRS = iClientRS; - // - iClientThread = NULL; - iClientRS = NULL; - iClientContext = NULL; - // - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::CompleteClientsRequest() - doing final request complete...") ); - Kern::RequestComplete( clientThread, clientRS, aCompletionCode ); - } - else - { - // Buffer the change for next time around... - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::CompleteClientsRequest() - BUFFERING change event whilst client is AWOL...", this ) ); - NKern::ThreadEnterCS(); - - DMemSpyDriverClientEM::TChange* cachedChange = new DMemSpyDriverClientEM::TChange( aCompletionCode, aContext ); - if ( cachedChange ) - { - iPendingChanges.Add( &cachedChange->iLink ); - } - // - NKern::ThreadLeaveCS(); - } - // - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::CompleteClientsRequest() - END - handle: 0x%08x", Handle() ) ); - } - - -void DMemSpyDriverClientEM::ResetPendingChanges() - { - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::ResetPendingChanges() - START - this: 0x%08x", this ) ); - NKern::ThreadEnterCS(); - // - SDblQueLink* link = iPendingChanges.GetFirst(); - while( link ) - { - DMemSpyDriverClientEM::TChange* cachedChange = _LOFF( link, DMemSpyDriverClientEM::TChange, iLink ); - delete cachedChange; - link = iPendingChanges.GetFirst(); - } - // - NKern::ThreadLeaveCS(); - TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::ResetPendingChanges() - END - this: 0x%08x", this ) ); - } - - - - - - - - - - - - - - -