memana/analyzetoolclient/kerneleventhandler/src/analyzetooleventhandler.cpp
changeset 0 f0f2b8682603
equal deleted inserted replaced
-1:000000000000 0:f0f2b8682603
       
     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:  Definitions for the class DAnalyzeToolEventHandler.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // INCLUDE FILES
       
    20 #include "analyzetooleventhandler.h"
       
    21 #include <kernel/kern_priv.h>
       
    22 
       
    23 // CONSTANTS
       
    24 
       
    25 // The handler mutex literal
       
    26 _LIT( KHandlerMutexName, "AnalyzeToolHandlerMutex" );
       
    27 
       
    28 // The handle data mutex literal
       
    29 _LIT( KDataMutexName, "AnalyzeToolDataMutex" );
       
    30 
       
    31 
       
    32 // ================= MEMBER FUNCTIONS =========================================
       
    33 
       
    34 // -----------------------------------------------------------------------------
       
    35 // DAnalyzeToolEventHandler::Create()
       
    36 // C++ default constructor.
       
    37 // -----------------------------------------------------------------------------
       
    38 //
       
    39 TInt DAnalyzeToolEventHandler::Create( DLogicalDevice* aDevice,
       
    40     const TUint aProcessId )
       
    41     {
       
    42     LOGSTR1( "ATDD DAnalyzeToolEventHandler::Create()" );
       
    43     TInt ret( KErrNone );
       
    44     
       
    45     // Store owner process ID
       
    46     iProcessId = aProcessId;
       
    47     LOGSTR2( "ATDD DAnalyzeToolEventHandler::Create > iProcessId %d", 
       
    48             iProcessId );
       
    49     
       
    50     // Open the device
       
    51     ret = aDevice->Open();
       
    52     if ( ret != KErrNone )
       
    53         return ret;
       
    54     iDevice = aDevice;
       
    55 
       
    56     // Create mutex for the handler
       
    57     ret = Kern::MutexCreate( iHandlerMutex, KHandlerMutexName, KMutexOrdDebug );
       
    58     if ( ret != KErrNone )
       
    59         return ret;
       
    60     // Create mutex for the data
       
    61     ret = Kern::MutexCreate( iDataMutex, KDataMutexName, KMutexOrdDebug-1 );
       
    62     if ( ret != KErrNone )
       
    63         return ret;
       
    64 
       
    65     // Add handler to the handler queue
       
    66     return Add();
       
    67     }
       
    68 
       
    69 // -----------------------------------------------------------------------------
       
    70 // DAnalyzeToolEventHandler::~DAnalyzeToolEventHandler()
       
    71 // C++ default constructor.
       
    72 // -----------------------------------------------------------------------------
       
    73 //
       
    74 DAnalyzeToolEventHandler::~DAnalyzeToolEventHandler()
       
    75     {
       
    76     LOGSTR1( "ATDD DAnalyzeToolEventHandler::~DAnalyzeToolEventHandler()" );
       
    77     
       
    78     CancelInformLibraryEvent();
       
    79     
       
    80     // Close the data mutex
       
    81     if ( iDataMutex )
       
    82         {
       
    83         iDataMutex->Close( NULL );
       
    84         }
       
    85 
       
    86     // Close the handler mutex
       
    87     if ( iHandlerMutex )
       
    88         {
       
    89         iHandlerMutex->Close( NULL );
       
    90         }
       
    91 
       
    92     // Close the device mutex
       
    93     if ( iDevice )
       
    94         {
       
    95         iDevice->Close( NULL );
       
    96         }
       
    97     }
       
    98 
       
    99 // -----------------------------------------------------------------------------
       
   100 // DAnalyzeToolEventHandler::EventHandler()
       
   101 // Function for receiving kernel events
       
   102 // -----------------------------------------------------------------------------
       
   103 //
       
   104 TUint DAnalyzeToolEventHandler::EventHandler( TKernelEvent aEvent, 
       
   105     TAny* a1, TAny* a2, TAny* aThis )
       
   106     {
       
   107     
       
   108     // Clarify the event type
       
   109     switch ( aEvent)
       
   110         {
       
   111         case EEventRemoveLibrary:
       
   112             {
       
   113             LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventRemoveLibrary" );
       
   114             // Cast the pointer to the handler
       
   115             DAnalyzeToolEventHandler* handler = 
       
   116             ( ( DAnalyzeToolEventHandler* ) aThis );
       
   117             // Create variable for library information
       
   118             TLibraryEventInfo info;
       
   119             // Set as library remove event
       
   120             info.iEventType = TLibraryEventInfo::ELibraryRemoved;
       
   121             // Handle the event
       
   122             handler->HandleLibraryEvent( ( DLibrary* ) a1, ( DThread* ) a2, info );
       
   123             break;
       
   124             }
       
   125         case EEventAddLibrary:
       
   126             {
       
   127             LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventAddLibrary" );
       
   128             // Cast the pointer to the handler
       
   129             DAnalyzeToolEventHandler* handler = 
       
   130             ( ( DAnalyzeToolEventHandler* ) aThis );
       
   131             // Create variable for library information
       
   132             TLibraryEventInfo info;
       
   133             // Set as library remove event
       
   134             info.iEventType = TLibraryEventInfo::ELibraryAdded;
       
   135             // Handle the event
       
   136             handler->HandleLibraryEvent( ( DLibrary* ) a1, ( DThread* ) a2, info );
       
   137             break;
       
   138             }
       
   139         case EEventHwExc:
       
   140             {
       
   141             LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventHwExc" );
       
   142             break;
       
   143             }
       
   144         case EEventSwExc:
       
   145             {
       
   146             LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventSwExc" );
       
   147             break;
       
   148             }
       
   149         case EEventRemoveThread:
       
   150             {
       
   151             LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventRemoveThread" );
       
   152             break;
       
   153             }
       
   154         case EEventKillThread:
       
   155             {
       
   156             LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventHandler() - EEventKillThread" );
       
   157             
       
   158             // Cast the pointer to the handler
       
   159             DAnalyzeToolEventHandler* handler = 
       
   160                 ( ( DAnalyzeToolEventHandler* ) aThis );
       
   161             
       
   162             // Create variable for library information
       
   163             TLibraryEventInfo info;
       
   164             
       
   165             // Set as kill thread event
       
   166             info.iEventType = TLibraryEventInfo::EKillThread;
       
   167             // Handle the event
       
   168             handler->HandleKillThreadEvent( ( DThread* ) a1, info );
       
   169             break;
       
   170             }
       
   171         default:
       
   172             {
       
   173             }
       
   174             break;
       
   175         }  
       
   176     return ERunNext;
       
   177     }
       
   178 
       
   179 // -----------------------------------------------------------------------------
       
   180 // DAnalyzeToolEventHandler::HandleLibraryEvent()
       
   181 // Handles the EEventAddLibrary and EEventRemoveLibrary events.
       
   182 // -----------------------------------------------------------------------------
       
   183 //
       
   184 void DAnalyzeToolEventHandler::HandleLibraryEvent( DLibrary* aLib, 
       
   185     DThread* aThread, TLibraryEventInfo& aInfo )
       
   186     {
       
   187     LOGSTR1( "ATDD DAnalyzeToolEventHandler::HandleLibraryEvent()" );
       
   188     
       
   189     // Aqcuire the handler mutex
       
   190     Kern::MutexWait( *iHandlerMutex );
       
   191 
       
   192     // Aqcuire the data mutex
       
   193     Kern::MutexWait( *iDataMutex );
       
   194     
       
   195     TBool addInfo( EFalse );
       
   196     
       
   197     // Check the library event type
       
   198     if ( aInfo.iEventType == TLibraryEventInfo::ELibraryAdded )
       
   199         {
       
   200         if ( aThread != NULL )
       
   201             {
       
   202             if ( iProcessId == aThread->iOwningProcess->iId )
       
   203                 {
       
   204                 LOGSTR1( "ATDD > Process id match" );
       
   205                 aInfo.iProcessId = aThread->iOwningProcess->iId;
       
   206                 addInfo = ETrue;
       
   207                 }
       
   208             }
       
   209         }
       
   210     else if ( aInfo.iEventType == TLibraryEventInfo::ELibraryRemoved )
       
   211         {
       
   212         if ( aThread != NULL )
       
   213             {
       
   214             aInfo.iProcessId = aThread->iOwningProcess->iId;
       
   215             }
       
   216         else
       
   217             {
       
   218             aInfo.iProcessId = 0;
       
   219             }
       
   220         addInfo = ETrue;
       
   221         }
       
   222     
       
   223     if ( addInfo )
       
   224         {
       
   225         // Store lib info
       
   226         aLib->AppendName( aInfo.iLibraryName );//lint !e64 !e1514
       
   227         aInfo.iSize = aLib->iCodeSeg->iSize;
       
   228         aInfo.iRunAddress = aLib->iCodeSeg->iRunAddress;
       
   229         // Store library event info to the array
       
   230         iEventArray.Append( aInfo );
       
   231         LOGSTR2( "ATDD > iEventArray.Count() = %d", iEventArray.Count() );
       
   232         
       
   233         // if client has subscribed the event it is queued
       
   234         if ( iClientThread != NULL )
       
   235             {
       
   236             iEventDfc.Enque();
       
   237             }
       
   238         }
       
   239      
       
   240     // Release the data mutex
       
   241     Kern::MutexSignal( *iDataMutex );
       
   242 
       
   243     // Release the handler mutex
       
   244     Kern::MutexSignal( *iHandlerMutex );
       
   245     }
       
   246 
       
   247 // -----------------------------------------------------------------------------
       
   248 // DAnalyzeToolEventHandler::InformLibraryEvent()
       
   249 // Subscribes library event.
       
   250 // -----------------------------------------------------------------------------
       
   251 //
       
   252 void DAnalyzeToolEventHandler::InformLibraryEvent( TRequestStatus* aStatus, 
       
   253                                                    TAny* aLibraryInfo,
       
   254                                                    TThreadMessage& aMessage )
       
   255     {
       
   256     LOGSTR1( "ATDD DAnalyzeToolEventHandler::InformLibraryEvent()" );
       
   257 
       
   258     // Aqcuire the data mutex
       
   259     Kern::MutexWait( *iDataMutex );  
       
   260     
       
   261     // Check if request from client which is already pending
       
   262     DThread* current = aMessage.Client();
       
   263     
       
   264     LOGSTR2( "ATDD > Current Thread ID = %d", current->iId );
       
   265  
       
   266     // Ensure that client doesn't subscribe service when there is a pending
       
   267     // subscription
       
   268     if ( NULL != iClientThread )
       
   269         {
       
   270         aMessage.PanicClient( KClientPanic, EPanicRequestPending );
       
   271         }
       
   272     else
       
   273         {
       
   274         // Store the client variable pointers
       
   275         iClientThread         = current;
       
   276         iClientRequestStatus  = aStatus;
       
   277         iClientInfo           = aLibraryInfo;
       
   278         }
       
   279     
       
   280     // Release the data mutex
       
   281     Kern::MutexSignal( *iDataMutex );
       
   282     
       
   283     // Queue the event since now the client has subscribed it
       
   284     iEventDfc.Enque();
       
   285     }
       
   286 
       
   287 // -----------------------------------------------------------------------------
       
   288 // DAnalyzeToolEventHandler::CancelInformLibraryEvent
       
   289 // Cancels subscription of the library event.
       
   290 // -----------------------------------------------------------------------------
       
   291 //
       
   292 void DAnalyzeToolEventHandler::CancelInformLibraryEvent()
       
   293     {
       
   294     LOGSTR1( "ATDD DAnalyzeToolEventHandler::CancelInformLibraryEvent()" );
       
   295     
       
   296     iEventDfc.Cancel();
       
   297     
       
   298     // Aqcuire the data mutex
       
   299     Kern::MutexWait( *iDataMutex );
       
   300 
       
   301     if ( NULL != iClientThread && iEventArray.Count() > 0 )
       
   302         {
       
   303         // Signal the request as complete
       
   304         Kern::RequestComplete( iClientThread, 
       
   305                                iClientRequestStatus, 
       
   306                                KErrCancel );
       
   307         
       
   308         iClientThread         = NULL;
       
   309         iClientRequestStatus  = NULL;
       
   310         iClientInfo           = NULL;
       
   311 
       
   312         // Reset the event array
       
   313         iEventArray.Reset();
       
   314         }
       
   315    
       
   316     // Release the data mutex
       
   317     Kern::MutexSignal( *iDataMutex );
       
   318     }
       
   319 
       
   320 // -----------------------------------------------------------------------------
       
   321 // DAnalyzeToolEventHandler::HandleKillThreadEvent()
       
   322 // Handles the EEventKillThread events.
       
   323 // -----------------------------------------------------------------------------
       
   324 //
       
   325 void DAnalyzeToolEventHandler::HandleKillThreadEvent( DThread* aThread, 
       
   326                                                       TLibraryEventInfo& aInfo )
       
   327     {
       
   328     LOGSTR1( "ATDD DAnalyzeToolEventHandler::HandleKillThreadEvent()" );
       
   329     
       
   330     // Aqcuire the handler mutex
       
   331     Kern::MutexWait( *iHandlerMutex );
       
   332 
       
   333     // Aqcuire the data mutex
       
   334     Kern::MutexWait( *iDataMutex );
       
   335     
       
   336     aInfo.iProcessId = aThread->iOwningProcess->iId;
       
   337     TBool alone( aThread->iOwningProcess->iThreadQ.First()->Alone() );
       
   338     LOGSTR2( "ATDD > Is alone = %d", alone );
       
   339     
       
   340     // Check if this our process and is the only thread item.
       
   341     if ( aInfo.iProcessId == iProcessId && !alone )
       
   342         {
       
   343         if ( aThread )
       
   344             {
       
   345             // Set current Thread id
       
   346             LOGSTR2( "ATDD > Thread ID = %d", aThread->iId );
       
   347             aInfo.iThreadId = aThread->iId;
       
   348             // Append event to array (beginning of the array)
       
   349             iEventArray.Insert( aInfo, 0 );
       
   350             
       
   351             // if client has subscribed the event it is queued
       
   352             if ( iClientThread != NULL )
       
   353                 {
       
   354                 iEventDfc.Enque();
       
   355                 }
       
   356             }
       
   357         }
       
   358     
       
   359     // Release the data mutex
       
   360     Kern::MutexSignal( *iDataMutex );
       
   361 
       
   362     // Release the handler mutex
       
   363     Kern::MutexSignal( *iHandlerMutex );
       
   364     }
       
   365 
       
   366 // -----------------------------------------------------------------------------
       
   367 // DAnalyzeToolEventHandler::DoEventComplete()
       
   368 // Informs client about the occured event.
       
   369 // -----------------------------------------------------------------------------
       
   370 //
       
   371 void DAnalyzeToolEventHandler::DoEventComplete()
       
   372     {
       
   373     LOGSTR1( "ATDD DAnalyzeToolEventHandler::DoEventComplete()" );
       
   374     
       
   375     // Aqcuire the handler mutex
       
   376     Kern::MutexWait( *iHandlerMutex );
       
   377 
       
   378     // Aqcuire the data mutex
       
   379     Kern::MutexWait( *iDataMutex );
       
   380     
       
   381     if ( NULL != iClientThread && iEventArray.Count() > 0 )
       
   382         {
       
   383         TInt ret = Kern::ThreadRawWrite( iClientThread, 
       
   384                                          iClientInfo, 
       
   385                                          &iEventArray[0],
       
   386                                          sizeof( iEventArray[0] ) );
       
   387         
       
   388         LOGSTR2( "ATDD > ThreadRawWrite err = %d", ret );
       
   389         
       
   390         // Signal the request as complete
       
   391         Kern::RequestComplete( iClientThread, 
       
   392                                iClientRequestStatus, 
       
   393                                ret );
       
   394         
       
   395         // Remove first item to array
       
   396         iEventArray.Remove( 0 );
       
   397         
       
   398         // Compresses the array down to a minimum
       
   399         iEventArray.Compress();
       
   400         
       
   401         // Ensure that pointers are set to NULL
       
   402         iClientThread         = NULL;
       
   403         iClientRequestStatus  = NULL;
       
   404         iClientInfo           = NULL;
       
   405         
       
   406         LOGSTR2( "ATDD > iEventArray = %d", iEventArray.Count() );
       
   407         }
       
   408     
       
   409     // Release the data mutex
       
   410     Kern::MutexSignal( *iDataMutex );
       
   411 
       
   412     // Release the handler mutex
       
   413     Kern::MutexSignal( *iHandlerMutex );
       
   414     }
       
   415 
       
   416 // -----------------------------------------------------------------------------
       
   417 // DAnalyzeToolEventHandler::EventDfc()
       
   418 // Static function for DFC events.
       
   419 // -----------------------------------------------------------------------------
       
   420 //
       
   421 void DAnalyzeToolEventHandler::EventDfc(TAny* aPtr)
       
   422     {
       
   423     LOGSTR1( "ATDD DAnalyzeToolEventHandler::EventDfc()" ); 
       
   424     ( (DAnalyzeToolEventHandler*) aPtr )->DoEventComplete();
       
   425     }
       
   426 
       
   427 // End of File