sensorservices/sensorserver/src/server/sensrvmediatorbase.cpp
changeset 0 4e1aa6a622a0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sensorservices/sensorserver/src/server/sensrvmediatorbase.cpp	Tue Feb 02 00:53:00 2010 +0200
@@ -0,0 +1,336 @@
+/*
+* Copyright (c) 2006 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:  Base class for Active objects to mediate control flow
+*                 between threads.
+*
+*/
+
+
+
+#include "sensrvdefines.h"
+#include "sensrvmediatorbase.h"
+#include "sensrvpluginproxy.h"
+#include "sensrvtransaction.h"
+#include "sensrvtransactionqueue.h"
+#include "sensrvsession.h"
+
+// ---------------------------------------------------------------------------
+// C++ constructor
+// ---------------------------------------------------------------------------
+//
+CSensrvMediatorBase::CSensrvMediatorBase()
+    : CActive(EPriorityHigh)
+    {
+    // Nothing to do
+    }
+
+// ---------------------------------------------------------------------------
+// 2nd phase of construction.
+// ---------------------------------------------------------------------------
+//
+void CSensrvMediatorBase::BaseConstructL(CSensrvPluginProxy* aProxy)
+    {
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::BaseConstructL(aProxy: 0x%x)" ), aProxy->ImplementationUid().iUid ) );   
+            
+    iProxy = aProxy;
+    iQueue = CSensrvTransactionQueue::NewL(EFalse);
+
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::BaseConstructL - return" ) ) );
+    }
+
+// ---------------------------------------------------------------------------
+// Destructor
+// ---------------------------------------------------------------------------
+//
+CSensrvMediatorBase::~CSensrvMediatorBase()
+    {
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::~CSensrvMediatorBase(), mediated thread: %S" ), &iThreadName ) );
+    
+    Cancel(); 
+    
+    BaseDestruct();
+
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::~CSensrvMediatorBase - return" ) ) );
+    }
+
+// ---------------------------------------------------------------------------
+// BaseDestruct
+// ---------------------------------------------------------------------------
+//
+void CSensrvMediatorBase::BaseDestruct()
+    {
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::BaseDestruct()" ) ) );
+    
+    // Empty the transaction link list and delete any mediator transactions in queue
+    delete iQueue;
+    iQueue = NULL;
+    
+    // iProxy not owned so not cleaned.
+    
+    iThread.Close();
+    
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::BaseDestruct - return void" ) ) );
+    }
+
+
+// ---------------------------------------------------------------------------
+// Adds transaction pointer to the end of queue and completes
+// this mediator's request on the other thread, causing RunL to be executed
+// there.
+// ---------------------------------------------------------------------------
+//
+TInt CSensrvMediatorBase::Notify(CSensrvTransaction* aTransaction)
+    {
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::Notify(aTransaction: 0x%x), mediated thread: %S" ), aTransaction, &iThreadName ) );
+        
+    TInt err(KErrNone);
+
+#ifndef __SENSRV_TEST_ALWAYS_FAIL_SERVER_MEDIATOR_NOTIFY
+    // Add transaction pointer to queue, unless it is NULL
+    if (aTransaction)
+        {
+        err = iQueue->Add(aTransaction);
+        }
+#else // !__SENSRV_TEST_ALWAYS_FAIL_SERVER_MEDIATOR_NOTIFY
+    // Always fail adding transaction when on server mediator, unless it is NULL
+    if (aTransaction)
+        {
+        if (iMutex == &iProxy->Mutex())
+            {
+            err = KErrNoMemory;
+            }
+        else
+            {
+            err = iQueue->Add(aTransaction);
+            }
+        }
+#endif // !__SENSRV_TEST_ALWAYS_FAIL_SERVER_MEDIATOR_NOTIFY
+    
+    // If adding transaction failed, set notify failed state to indicate this.
+    if (err != KErrNone)
+        {
+        iNotifyFailed = ETrue;
+        aTransaction->SetState(CSensrvTransaction::ETransStateNotifyFailed);
+        } 
+
+    CompleteRequest(KErrNone);
+
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::Notify - return %d" ), err ) );
+    
+    return err;
+    }
+
+// ---------------------------------------------------------------------------
+// Initializes mediator.
+// Completion is not yet enabled. It will be enabled when scheduler has
+// run at least one idle loop to ensure mediator request is not completed 
+// before scheduler is activated.
+// ---------------------------------------------------------------------------
+//
+TInt CSensrvMediatorBase::Initialize()
+    {
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::Initialize()" ) ) );
+    
+    TInt err(KErrNone);
+
+    if ( !iInitialized )
+        {
+        err = iThread.Open(iThread.Id());
+        
+        if (err == KErrNone)
+            {
+#if defined (COMPONENT_TRACE_FLAG) || defined(ERROR_TRACE_FLAG)
+            iThreadName = iThread.Name();
+#endif
+
+            COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::Initialize - mediated thread: %S" ), &iThreadName ) );
+
+            // iMutex must be set by child class before calling Initialize
+            __ASSERT_ALWAYS(iMutex, User::Panic(KSensrvPanicCategory, ESensrvPanicNullMutex));
+            __ASSERT_ALWAYS(CActiveScheduler::Current()!= NULL, User::Panic(KSensrvPanicCategory, ESensrvPanicNullScheduler));
+
+            CActiveScheduler::Add(this);
+            iStatus = KRequestPending;
+            SetActive();
+            iInitialized = ETrue;
+            }
+        else
+            {
+            ERROR_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::Initialize - ERROR: Mediator initialize failed" ) ) );
+            }
+        }
+
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::Initialize - return %d" ), err ) );
+    
+    return err;
+    }
+
+// ---------------------------------------------------------------------------
+// Removes session initiated transactions from queue
+// ---------------------------------------------------------------------------
+//
+void CSensrvMediatorBase::SessionTerminated(CSensrvSession* aSession)
+    {
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::SessionTerminated(), mediated thread: %S" ), &iThreadName ) );
+
+    iQueue->Remove(aSession);
+
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::SessionTerminated - return" ) ) );
+    }
+
+// ---------------------------------------------------------------------------
+// Removes all transactions from queue
+// ---------------------------------------------------------------------------
+//
+void CSensrvMediatorBase::RemoveAllTransactions()
+    {
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::RemoveAllTransactions(), mediated thread: %S" ), &iThreadName ) );
+
+    iQueue->RemoveAll();
+
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::RemoveAllTransactions - return" ) ) );
+    }
+
+// ---------------------------------------------------------------------------
+// Removes single transaction from queue
+// ---------------------------------------------------------------------------
+//
+void CSensrvMediatorBase::RemoveSingleTransaction(CSensrvTransaction* aTransaction)
+    {
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::RemoveSingleTransaction(), mediated thread: %S" ), &iThreadName ) );
+
+    iQueue->Remove(aTransaction);
+
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::RemoveSingleTransaction - return" ) ) );
+    }
+
+// -----------------------------------------------------------------------------
+// Handle notification from the other thread.
+// -----------------------------------------------------------------------------
+//
+void CSensrvMediatorBase::RunL()
+    {
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::RunL(), mediated thread: %S" ), &iThreadName ) );
+    
+    // Check if there are any transactions in queue, and if so,
+    // get the first one and request handling for it.
+    iMutex->Wait();
+    
+    // Before handling any transactions, check notify failure
+    if (iNotifyFailed)
+        {
+        HandleNotifyFailure();
+        iNotifyFailed = EFalse;
+        }
+    else
+        {
+        CSensrvTransaction* transaction = iQueue->First();
+                       
+        // Handle the received transaction (even if it is NULL), 
+        HandleTransaction(transaction);
+
+        // Remove transaction from queue. Since mediator queues don't own transactions,
+        // this does not yet complete it, unless it is a mediator transaction.
+        if (transaction)
+            {
+            iQueue->Remove(transaction);
+            }
+        }
+        
+    // Reactivate 
+    iStatus = KRequestPending;
+    SetActive();
+
+    // Complete right away if there are more transactions
+    if (!iQueue->IsEmpty())
+        {
+        CompleteRequest(KErrNone);
+        }
+
+    // SSY mediator mutex will be destroyed already if this is cleanup activation
+    if(iMutex)
+        {
+        iMutex->Signal();
+        }
+    
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::RunL - return" ) ) );
+    }
+    
+// -----------------------------------------------------------------------------
+// Handle error in RunL
+// -----------------------------------------------------------------------------
+//
+#ifdef COMPONENT_TRACE_DEBUG
+TInt CSensrvMediatorBase::RunError(TInt aError)
+#else
+TInt CSensrvMediatorBase::RunError(TInt /*aError*/)
+#endif
+    {
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::RunError(%d), mediated thread: %S" ), aError, &iThreadName) );
+
+    // Panic this thread if there is unhandled error in RunL.
+    // This should not be possible.
+    User::Panic(KSensrvPanicCategory, ESensrvPanicMediatorRunError);
+    
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::RunError - return %d" ), KErrNone ) );
+
+    return KErrNone;
+    }
+
+// -----------------------------------------------------------------------------
+// Handle cancel order on this active object.
+// -----------------------------------------------------------------------------
+//
+void CSensrvMediatorBase::DoCancel()
+    {
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::DoCancel(), mediated thread: %S" ), &iThreadName ) );
+
+    // Request needs to be completed with KErrCancel
+    CompleteRequest(KErrCancel);
+
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::DoCancel - return" ) ) );
+    }
+
+// -----------------------------------------------------------------------------
+// Completes request if active.
+// If not active, there is probably some problem with thread mutexing,
+// but we cannot complete in that case anyway.
+// -----------------------------------------------------------------------------
+//
+void CSensrvMediatorBase::CompleteRequest(TInt aReason)
+    {
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::CompleteRequest(aReason: %d), mediated thread: %S" ), aReason, &iThreadName ) );
+
+    if (!IsActive())
+        {
+        // Mediator is not active, which means it is probably waiting for mutex at RunL, so no need to complete again.
+        COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::CompleteRequest - Not active when attempted completion." ) ) );
+        }
+    else if (iStatus==KRequestPending)
+        {
+        // Cause RunL to be executed in the owner thread.    
+        TRequestStatus* status = &iStatus;
+        iThread.RequestComplete(status, aReason);
+        COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::CompleteRequest - Completion done." ) ) );
+        }
+    else
+        {
+        // Already completed but not yet handled, do nothing.
+        COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::CompleteRequest - Completion not necessary" ) ) );
+        }
+
+    COMPONENT_TRACE( ( _L( "Sensor Server - CSensrvMediatorBase::CompleteRequest - return" ) ) );
+    }
+
+