memspy/Driver/Kernel/Source/MemSpyDriverUserEventMonitor.cpp
changeset 0 a03f92240627
equal deleted inserted replaced
-1:000000000000 0:a03f92240627
       
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:
       
    15 *
       
    16 */
       
    17 
       
    18 #include "MemSpyDriverUserEventMonitor.h"
       
    19 
       
    20 // System includes
       
    21 #include <memspy/driver/memspydriverenumerationsshared.h>
       
    22 
       
    23 // User includes
       
    24 #include "MemSpyDriverUtils.h"
       
    25 #include "MemSpyDriverDevice.h"
       
    26 #include "MemSpyDriverOSAdaption.h"
       
    27 #include "MemSpyDriverEventMonitor.h"
       
    28 
       
    29 // Literal constants
       
    30 _LIT( KMemSpyDriverClientEMMutexName, "MemSpyDriverClientEM_0x" );
       
    31 
       
    32 
       
    33 
       
    34 
       
    35 DMemSpyDriverClientEMManager::DMemSpyDriverClientEMManager( DMemSpyDriverDevice& aDevice )
       
    36 :   iDevice( aDevice )
       
    37     {
       
    38     }
       
    39 
       
    40 
       
    41 DMemSpyDriverClientEMManager::~DMemSpyDriverClientEMManager()
       
    42 	{
       
    43 	TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::~DMemSpyDriverClientEMManager() - START"));
       
    44 
       
    45     NKern::ThreadEnterCS();
       
    46     FreeAllInstances();
       
    47     NKern::ThreadLeaveCS();
       
    48 
       
    49 	TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::~DMemSpyDriverClientEMManager() - END"));
       
    50 	}
       
    51 
       
    52 
       
    53 TInt DMemSpyDriverClientEMManager::Create()
       
    54     {
       
    55     return KErrNone;
       
    56     }
       
    57 
       
    58 
       
    59 DMemSpyDriverClientEM* DMemSpyDriverClientEMManager::EMOpen()
       
    60     {
       
    61     TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::EMOpen() - START - iNextHandle: %d, iDevice: 0x%08x", iNextHandle+1, &iDevice ) );
       
    62     NKern::ThreadEnterCS();
       
    63     //
       
    64     DMemSpyDriverClientEM* object = new DMemSpyDriverClientEM( iDevice, ++iNextHandle );
       
    65     if  ( object != NULL )
       
    66         {
       
    67         TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::EMOpen() - calling create..." ) );
       
    68         const TInt error = object->Create();
       
    69         if ( error != KErrNone )
       
    70             {
       
    71             TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::EMOpen() - creation error: %d", error ) );
       
    72             delete object;
       
    73             object = NULL;
       
    74             }
       
    75         else
       
    76             {
       
    77             iEMInstances.Add( &object->iLink );
       
    78             }
       
    79         }
       
    80     //
       
    81     NKern::ThreadLeaveCS();
       
    82     TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::EMOpen() - END - object: 0x%08x", object ) );
       
    83     //
       
    84     return object;
       
    85     }
       
    86 
       
    87 
       
    88 TInt DMemSpyDriverClientEMManager::EMClose( TUint aHandle )
       
    89     {
       
    90     TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::EMClose() - START - aHandle: 0x%08x", aHandle ) );
       
    91     TInt error = KErrNotFound;
       
    92     //
       
    93     DMemSpyDriverClientEM* object = EMInstance( aHandle );
       
    94     if  ( object != NULL )
       
    95         {
       
    96         NKern::ThreadEnterCS();
       
    97         object->iLink.Deque();
       
    98         delete object;
       
    99         NKern::ThreadLeaveCS();
       
   100         error = KErrNone;
       
   101         }
       
   102     //
       
   103     TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::EMClose() - END - error: %d", error ) );
       
   104     return error;
       
   105     }
       
   106 
       
   107 
       
   108 DMemSpyDriverClientEM* DMemSpyDriverClientEMManager::EMInstance( TUint aHandle )
       
   109     {
       
   110     TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::EMInstance() - START - aHandle: 0x%08x", aHandle ) );
       
   111     DMemSpyDriverClientEM* ret = NULL;
       
   112     //
       
   113 	const SDblQueLink* const anchor = &iEMInstances.iA;
       
   114 	for (SDblQueLink* link = iEMInstances.First(); link != anchor; link = link->iNext )
       
   115 		{
       
   116 		DMemSpyDriverClientEM* object = _LOFF( link, DMemSpyDriverClientEM, iLink );
       
   117         //
       
   118         if  ( object->Handle() == aHandle )
       
   119             {
       
   120             ret = object;
       
   121             break;
       
   122             }
       
   123         }
       
   124     //
       
   125     TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::EMInstance() - END - aHandle: 0x%08x, ret: 0x%08x", aHandle, ret ) );
       
   126     return ret;
       
   127     }
       
   128 
       
   129 
       
   130 void DMemSpyDriverClientEMManager::FreeAllInstances()
       
   131     {
       
   132     TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::FreeAllInstances() - START") );
       
   133 	
       
   134     SDblQueLink* link = iEMInstances.GetFirst();
       
   135 	while( link )
       
   136 		{
       
   137 		DMemSpyDriverClientEM* object = _LOFF( link, DMemSpyDriverClientEM, iLink );
       
   138         delete object;
       
   139         link = iEMInstances.GetFirst();
       
   140 		}
       
   141 
       
   142     TRACE_EM( Kern::Printf("DMemSpyDriverClientEMManager::FreeAllInstances() - END") );
       
   143     }
       
   144 
       
   145 
       
   146 
       
   147 
       
   148 
       
   149 
       
   150 
       
   151 
       
   152 
       
   153 
       
   154 
       
   155 
       
   156 
       
   157 
       
   158 
       
   159 
       
   160 
       
   161 
       
   162 
       
   163 
       
   164 
       
   165 
       
   166 
       
   167 
       
   168 
       
   169 
       
   170 
       
   171 
       
   172 
       
   173 DMemSpyDriverClientEM::DMemSpyDriverClientEM( DMemSpyDriverDevice& aDevice, TUint aHandle )
       
   174 :   iDevice( aDevice ), iHandle( aHandle )
       
   175     {
       
   176     }
       
   177 
       
   178 
       
   179 DMemSpyDriverClientEM::~DMemSpyDriverClientEM()
       
   180     {
       
   181     TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::~DMemSpyDriverClientEM() - START - this: 0x%08x", this ));
       
   182 	iDevice.EventMonitor().RequestEventsCancel( *this );
       
   183 
       
   184     TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::~DMemSpyDriverClientEM() - calling NotifyChangesCancel..." ) );
       
   185     NotifyChangesCancel();
       
   186     
       
   187     TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::~DMemSpyDriverClientEM() - calling ResetPendingChanges..." ) );
       
   188     ResetPendingChanges();
       
   189 
       
   190 	if  ( iLock )
       
   191 		{
       
   192         TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::~DMemSpyDriverClientEM() - closing mutex..." ) );
       
   193 		iLock->Close(NULL);
       
   194 		}
       
   195 
       
   196     TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::~DMemSpyDriverClientEM() - END - this: 0x%08x" ));
       
   197     }
       
   198 
       
   199 
       
   200 TInt DMemSpyDriverClientEM::Create()
       
   201     {
       
   202     TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::Create() - START - handle: 0x%08x", Handle() ) );
       
   203 
       
   204     // Create mutex
       
   205     TName name( KMemSpyDriverClientEMMutexName );
       
   206     name.AppendNumFixedWidth( (TUint) this, EHex, 8 );
       
   207     TInt error = Kern::MutexCreate( iLock, name, KMutexOrdNone );
       
   208     //
       
   209     if  ( error == KErrNone )
       
   210         {
       
   211         TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::Create() - calling global device driver event monitor...") );
       
   212         iDevice.EventMonitor().RequestEvents( *this );
       
   213         }
       
   214     //
       
   215     TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::Create() - END - handle: 0x%08x, err: %d", Handle(), error ) );
       
   216     return error;
       
   217     }
       
   218 
       
   219 
       
   220 TInt DMemSpyDriverClientEM::NotifyChanges( DThread* aClientThread, TRequestStatus* aClientRS, TAny* aClientContext )
       
   221     {
       
   222 	Kern::MutexWait( *iLock );
       
   223 
       
   224     TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::NotifyChanges() - START - handle: 0x%08x", Handle() ) );
       
   225     TInt r = KErrInUse;
       
   226     //
       
   227     if  ( iClientRS == NULL )
       
   228         {
       
   229         TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::NotifyChanges() - saving client's request...") );
       
   230         iClientThread = aClientThread;
       
   231         iClientRS = aClientRS;
       
   232         iClientContext = aClientContext;
       
   233         //
       
   234         if	( !iPendingChanges.IsEmpty() )
       
   235 			{
       
   236             TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::NotifyOnChange() - Have buffered changes - SENDING TO CLIENT IMMEDIATELY..." ) );
       
   237 			
       
   238             // We have something in the pending buffer so we can
       
   239 			// give it back to the client immediately.
       
   240 	        DMemSpyDriverClientEM::TChange* cachedChange = _LOFF( iPendingChanges.First(), DMemSpyDriverClientEM::TChange, iLink );
       
   241 			cachedChange->iLink.Deque();
       
   242 			
       
   243             // Notify about change			
       
   244 			CompleteClientsRequest( cachedChange->iCompletionCode, cachedChange->iContext );
       
   245 			
       
   246 			// Discard cached entry
       
   247             NKern::ThreadEnterCS();
       
   248 			delete cachedChange;
       
   249             NKern::ThreadLeaveCS();
       
   250 			}
       
   251         //
       
   252         r = KErrNone;
       
   253         }
       
   254     //
       
   255     TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::NotifyChanges() - END - handle: 0x%08x, error: %d", Handle(), r ) );
       
   256 	Kern::MutexSignal( *iLock );
       
   257     return r;
       
   258     }
       
   259 
       
   260 
       
   261 TInt DMemSpyDriverClientEM::NotifyChangesCancel()
       
   262     {
       
   263 	Kern::MutexWait( *iLock );
       
   264     TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::NotifyChangesCancel() - START - handle: 0x%08x, iClientThread: 0x%08x, iClientRS: 0x%08x", Handle(), iClientThread, iClientRS ) );
       
   265     //
       
   266     TInt r = KErrNotReady;
       
   267     //
       
   268     if  ( iClientRS != NULL )
       
   269         {
       
   270         DThread* clientThread = iClientThread;
       
   271         TRequestStatus* clientRS = iClientRS;
       
   272         //
       
   273         iClientThread = NULL;
       
   274         iClientRS = NULL;
       
   275         iClientContext = NULL;
       
   276         //
       
   277         TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::NotifyChangesCancel() - doing final request complete...") );
       
   278 		Kern::RequestComplete( clientThread, clientRS, KErrCancel );
       
   279         r = KErrNone;
       
   280         }
       
   281     //
       
   282     TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::NotifyChangesCancel() - END - handle: 0x%08x, error: %d", Handle(), r ) );
       
   283 	Kern::MutexSignal( *iLock );
       
   284     return r;
       
   285     }
       
   286 
       
   287 
       
   288 TUint DMemSpyDriverClientEM::EMTypeMask() const
       
   289     {
       
   290     const TUint ret = EMemSpyEventThreadAdd  | EMemSpyEventThreadKill |
       
   291                       EMemSpyEventProcessAdd | EMemSpyEventProcessRemove | 
       
   292                       EMemSpyEventChunkAdd   | EMemSpyEventChunkDelete;
       
   293     return ret;
       
   294     }
       
   295 
       
   296 
       
   297 void DMemSpyDriverClientEM::EMHandleProcessAdd( DProcess& aProcess )
       
   298     {
       
   299     const TUint pid = iDevice.OSAdaption().DProcess().GetId( aProcess );
       
   300     //
       
   301 	Kern::MutexWait( *iLock );
       
   302     CompleteClientsRequest( EMemSpyDriverEventTypeProcessCreate, pid );
       
   303 	Kern::MutexSignal( *iLock );
       
   304     }
       
   305 
       
   306 
       
   307 void DMemSpyDriverClientEM::EMHandleProcessRemoved( DProcess& aProcess )
       
   308     {
       
   309     const TUint pid = iDevice.OSAdaption().DProcess().GetId( aProcess );
       
   310     //
       
   311 	Kern::MutexWait( *iLock );
       
   312     CompleteClientsRequest( EMemSpyDriverEventTypeProcessRemove, pid );
       
   313 	Kern::MutexSignal( *iLock );
       
   314     }
       
   315 
       
   316 
       
   317 void DMemSpyDriverClientEM::EMHandleThreadAdd( DThread& aThread )
       
   318     {
       
   319     const TUint tid = iDevice.OSAdaption().DThread().GetId( aThread );
       
   320     //
       
   321 	Kern::MutexWait( *iLock );
       
   322     CompleteClientsRequest( EMemSpyDriverEventTypeThreadCreate, tid );
       
   323 	Kern::MutexSignal( *iLock );
       
   324     }
       
   325 
       
   326 
       
   327 void DMemSpyDriverClientEM::EMHandleThreadKilled( DThread& aThread )
       
   328     {
       
   329     const TUint tid = iDevice.OSAdaption().DThread().GetId( aThread );
       
   330     //
       
   331 	Kern::MutexWait( *iLock );
       
   332     CompleteClientsRequest( EMemSpyDriverEventTypeThreadKill, tid );
       
   333 	Kern::MutexSignal( *iLock );
       
   334     }
       
   335 
       
   336 
       
   337 void DMemSpyDriverClientEM::EMHandleChunkAdd( DChunk& aChunk ) 
       
   338     {
       
   339 	Kern::MutexWait( *iLock );
       
   340     CompleteClientsRequest( EMemSpyDriverEventTypeChunkAdd, (TUint) &aChunk );
       
   341 	Kern::MutexSignal( *iLock );
       
   342     }
       
   343 
       
   344 
       
   345 void DMemSpyDriverClientEM::EMHandleChunkDeleted( DChunk& aChunk )
       
   346     {
       
   347 	Kern::MutexWait( *iLock );
       
   348     CompleteClientsRequest( EMemSpyDriverEventTypeChunkDestroy, (TUint) &aChunk );
       
   349 	Kern::MutexSignal( *iLock );
       
   350     }
       
   351 
       
   352 
       
   353 void DMemSpyDriverClientEM::CompleteClientsRequest( TInt aCompletionCode, TUint aContext )
       
   354     {
       
   355     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() ) );
       
   356     //
       
   357     if  ( iClientRS != NULL )
       
   358         {
       
   359         TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::CompleteClientsRequest() - attempting to complete client's request...") );
       
   360 
       
   361         // First write context info
       
   362         const TInt writeErr = Kern::ThreadRawWrite( iClientThread, iClientContext, &aContext, sizeof(TUint) );
       
   363 		if  ( writeErr != KErrNone )
       
   364 		    {
       
   365             TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::CompleteClientsRequest() - write error: %d", writeErr ) );
       
   366             aCompletionCode = writeErr;
       
   367 		    }
       
   368 
       
   369         // Now complete event - avoiding race conditions!
       
   370         DThread* clientThread = iClientThread;
       
   371         TRequestStatus* clientRS = iClientRS;
       
   372         //
       
   373         iClientThread = NULL;
       
   374         iClientRS = NULL;
       
   375         iClientContext = NULL;
       
   376         //
       
   377         TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::CompleteClientsRequest() - doing final request complete...") );
       
   378 		Kern::RequestComplete( clientThread, clientRS, aCompletionCode );
       
   379         }
       
   380     else
       
   381         {
       
   382 		// Buffer the change for next time around...
       
   383         TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::CompleteClientsRequest() - BUFFERING change event whilst client is AWOL...", this ) );
       
   384         NKern::ThreadEnterCS();
       
   385         
       
   386         DMemSpyDriverClientEM::TChange* cachedChange = new DMemSpyDriverClientEM::TChange( aCompletionCode, aContext );
       
   387         if  ( cachedChange )
       
   388             {
       
   389             iPendingChanges.Add( &cachedChange->iLink );
       
   390             }
       
   391         //
       
   392         NKern::ThreadLeaveCS();
       
   393         }
       
   394     //
       
   395     TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::CompleteClientsRequest() - END - handle: 0x%08x", Handle() ) );
       
   396     }
       
   397 
       
   398 
       
   399 void DMemSpyDriverClientEM::ResetPendingChanges()
       
   400     {
       
   401     TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::ResetPendingChanges() - START - this: 0x%08x", this ) );
       
   402     NKern::ThreadEnterCS();
       
   403     //
       
   404     SDblQueLink* link = iPendingChanges.GetFirst();
       
   405 	while( link )
       
   406 		{
       
   407         DMemSpyDriverClientEM::TChange* cachedChange = _LOFF( link, DMemSpyDriverClientEM::TChange, iLink );
       
   408         delete cachedChange;
       
   409         link = iPendingChanges.GetFirst();
       
   410 		}
       
   411     //
       
   412     NKern::ThreadLeaveCS();
       
   413     TRACE_EM( Kern::Printf("DMemSpyDriverClientEM::ResetPendingChanges() - END - this: 0x%08x", this ) );
       
   414     }
       
   415 
       
   416 
       
   417 
       
   418 
       
   419 
       
   420 
       
   421 
       
   422 
       
   423 
       
   424 
       
   425 
       
   426 
       
   427 
       
   428 
       
   429