--- /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" ) ) );
+ }
+
+