--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/loggingservices/eventlogger/LogServ/src/LogServOperationQueue.cpp Fri Jan 22 11:06:30 2010 +0200
@@ -0,0 +1,386 @@
+// Copyright (c) 2002-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 "LogServOperationQueue.h"
+
+// User includes
+#include "logservpanic.h"
+#include "LogServOperationBase.h"
+#include "LogServTaskInterface.h"
+
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// -----> CLogServOperationQueue (source)
+/////////////////////////////////////////////////////////////////////////////////////////
+
+CLogServOperationQueue::CLogServOperationQueue(MLogServTaskInterface& aTaskInterface, TInt aPriority)
+: CActive(aPriority),
+ iTaskInterface(aTaskInterface),
+ iQueuePending(CLogServOperationBase::QueueOffset()),
+ iQueueCompleted(CLogServOperationBase::QueueOffset())
+ {
+ CActiveScheduler::Add(this);
+ }
+
+CLogServOperationQueue::~CLogServOperationQueue()
+ {
+ Cancel();
+ //
+ CLogServOperationBase* item = NULL;
+ //
+ TSglQueIter<CLogServOperationBase> pendingIterator(iQueuePending);
+ while ((item = pendingIterator++) != NULL)
+ {
+ delete item;
+ }
+ //
+ TSglQueIter<CLogServOperationBase> completedIterator(iQueueCompleted);
+ while ((item = completedIterator++) != NULL)
+ {
+ delete item;
+ }
+ }
+
+CLogServOperationQueue* CLogServOperationQueue::NewL(MLogServTaskInterface& aTaskInterface, TInt aPriority)
+ {
+ CLogServOperationQueue* self = new(ELeave) CLogServOperationQueue(aTaskInterface, aPriority);
+ return self;
+ }
+
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CLogServOperationQueue::OMOperationQueueAdd(CLogServOperationBase& aOp)
+//
+// Add a new event to the queue and restart processing if necessary
+//
+ {
+ LOGTEXT3("CLogServOperationQueue::OMOperationQueueAdd() - Type: %d, Id: %d", aOp.Type(), aOp.Id());
+ //
+ iQueuePending.AddLast(aOp);
+ if (!IsActive())
+ CompleteRequest();
+ //
+ LOGTEXT("CLogServOperationQueue::OMOperationQueueAdd() - end");
+ }
+
+//
+// Removes an operation from the relevant server queue
+//
+void CLogServOperationQueue::OMOperationQueueRemove(CLogServOperationBase& aOperation)
+ {
+ const TLogOperationId operationId = aOperation.Id();
+ const TLogServSessionId sessionId = aOperation.SessionId();
+ //
+ LOGTEXT3("CLogServOperationQueue::OMOperationQueueRemove() - Id: %d, SessionId: %d", operationId, sessionId);
+ //
+ if(QueueContainsOperation(iQueuePending, operationId, sessionId))
+ {
+ iQueuePending.Remove(aOperation);
+ }
+ else
+ {
+ iQueueCompleted.Remove(aOperation);
+ }
+ //
+ LOGTEXT("CLogServOperationQueue::OMOperationQueueRemove() - end");
+ }
+
+void CLogServOperationQueue::OMGetResultL(TLogOperationId aId, TLogServSessionId aSessionId, const RMessage2& aMessageToWriteTo)
+//
+// Get the result of a specific operation
+//
+ {
+ LOGTEXT3("CLogServOperationQueue::OMGetResultL() - Id: %d, SessionId: %d", aId, aSessionId);
+
+ // Look for the op
+ CLogServOperationBase* op = FindOperation(iQueueCompleted, aId, aSessionId);
+
+ // If we found it, then return the result
+ if (op != NULL)
+ {
+ op->WriteL(aMessageToWriteTo);
+ delete op;
+ }
+ //
+ LOGTEXT("CLogServOperationQueue::OMGetResultL() - end");
+ }
+
+void CLogServOperationQueue::OMCancel(TLogOperationId aOpId, TLogServSessionId aSessionId, TBool aCompleteRequest)
+//
+// Cancel a specific operation
+//
+ {
+ LOGTEXT4("CLogServOperationQueue::OMCancel() - Id: %d, SessionId: %d, CompleteRequest: %d", aOpId, aSessionId, aCompleteRequest);
+
+ if (iCurrentOperation && iCurrentOperation->SessionId() == aSessionId && (aOpId == KLogNullOperationId || iCurrentOperation->Id() == aOpId))
+ {
+ // We need to cancel the current active operation because it belongs to this session
+ //
+ // This should complete the request with KErrCancel causing RunL to leave
+ // RunError completes the request and removes the operation from the pending queue
+ iTaskInterface.TaskCancelCurrent();
+ //
+ if (!aCompleteRequest)
+ iCurrentOperation->ClearMessagePointer();
+ }
+ else
+ {
+ // The active operation doesn't belong to this session - just remove any relevant operations from the queues
+ //
+ // We are taking advantage of the fact that a session will only ever have one operation outstanding
+ // so a cancel request basically means - cancel everything belonging to the session
+ CLogServOperationBase* op = NULL;
+ while((op = FindOperation(iQueuePending, aOpId, aSessionId)) != NULL)
+ {
+ if (aCompleteRequest)
+ {
+ op->Cancel();
+ }
+
+ // The operation dequeues itself from the containing queue in its destructor via
+ // the MLogServOperationManager abstract interface.
+ delete op;
+
+ // We can exit now if we were looking for a particular operation
+ if (aOpId > KLogNullOperationId)
+ {
+ return;
+ }
+ }
+
+ // Just delete the completed operation
+ DeleteFromQueue(iQueueCompleted, aOpId, aSessionId);
+ }
+ //
+ LOGTEXT("CLogServOperationQueue::OMCancel() - end");
+ }
+
+//
+// Stop/cancel and delete all operations belonging to a particular session
+// If the session has just died we don't want to complete the request - the kernel would panic us
+//
+void CLogServOperationQueue::OMCancel(TLogServSessionId aSessionId, TBool aCompleteRequest)
+ {
+ OMCancel(KLogNullOperationId, aSessionId, aCompleteRequest);
+ }
+
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////
+
+void CLogServOperationQueue::RunL()
+//
+// Called to indicate that the operation has completed - so complete the client request
+//
+ {
+ LOGTEXT2("CLogServOperationQueue::RunL(%d)", iStatus.Int());
+
+ // If the queue has just been restarted there won't be an existing operation
+ if (iCurrentOperation)
+ {
+ LOGTEXT3("CLogServOperationQueue::RunL() - Current operation Type: %d, Id: %d,", iCurrentOperation->Type(), iCurrentOperation->Id());
+
+ // Handle errors in RunError
+ User::LeaveIfError(iStatus.Int());
+
+ // Remember the type of operation for later
+ const TLogOperationType type = iCurrentOperation->Type();
+
+ // Complete the operation
+ if (iCurrentOperation->CompleteProcessingL(iStatus.Int()) == CLogServOperationBase::EOperationComplete)
+ {
+ LOGTEXT("CLogServOperationQueue::RunL() - Operation is complete, deleting it");
+ delete iCurrentOperation;
+ iCurrentOperation = NULL;
+ }
+ else
+ {
+ // The client is going to ask for some results.
+ //
+ // Move the operation to another queue until it's done
+ // The session will actually delete the operation
+ LOGTEXT("CLogServOperationQueue::RunL() - Operation result awaiting client fetch");
+ iQueuePending.Remove(*iCurrentOperation);
+ iQueueCompleted.AddLast(*iCurrentOperation);
+ }
+
+ // Any errors from maintenance will be ignored because the operation is null
+ iCurrentOperation = NULL;
+
+ LOGTEXT("CLogServOperationQueue::RunL() - Starting maintenance");
+ iTaskInterface.TaskMaintenanceStartL(iStatus, type != ELogOperationEventGet);
+ SetActive();
+ }
+ else
+ {
+ LOGTEXT("CLogServOperationQueue::RunL() - finding next operation");
+
+ // Start the next operation
+ StartNextOpL();
+ }
+
+ LOGTEXT("CLogServOperationQueue::RunL() - end");
+ }
+
+void CLogServOperationQueue::DoCancel()
+//
+// Implements cancel policy. Only called if the maintenance is active?
+//
+ {
+ iTaskInterface.TaskCancelCurrent();
+ }
+
+TInt CLogServOperationQueue::RunError(TInt aError)
+//
+// Handle errors
+//
+ {
+ LOGTEXT2("CLogServOperationQueue::RunError(%d)", aError);
+
+ if (iCurrentOperation)
+ {
+ LOGTEXT3("CLogServOperationQueue::RunError() - Current operation Type: %d, Id: %d,", iCurrentOperation->Type(), iCurrentOperation->Id());
+
+ // Fail the client request with the error
+ if (iCurrentOperation->HaveMessagePointer())
+ iCurrentOperation->Complete(aError);
+ delete iCurrentOperation;
+ iCurrentOperation = NULL;
+ }
+
+ // Restart by mending the database if necessary
+ TRAPD(mendError, iTaskInterface.TaskMaintenanceStartL(iStatus, ETrue));
+ if (mendError)
+ {
+ LOGTEXT2("CLogServOperationQueue::RunError() - mend error: %d)", mendError);
+
+ // Just ignore the maintenance error and complete ourselves so we continue to execute operations
+ CompleteRequest(KErrNone);
+ }
+ else
+ {
+ LOGTEXT("CLogServOperationQueue::RunError() - setting active again");
+ SetActive();
+ }
+
+ LOGTEXT("CLogServOperationQueue::RunError() - end");
+ return KErrNone;
+ }
+
+void CLogServOperationQueue::CompleteRequest(TInt aCompletionCode)
+ {
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, aCompletionCode);
+ SetActive();
+ }
+
+void CLogServOperationQueue::StartNextOpL()
+//
+// Start the next operation on the queue
+//
+ {
+ LOGTEXT("CLogServOperationQueue::StartNextOpL()");
+
+ iCurrentOperation = NULL;
+ if (!IsActive() && !iQueuePending.IsEmpty())
+ {
+ iCurrentOperation = iQueuePending.First();
+
+ LOGTEXT3("CLogServOperationQueue::StartNextOpL() - New next operation, Type: %d, Id: %d", iCurrentOperation->Type(), iCurrentOperation->Id());
+
+ iCurrentOperation->StartL(iStatus);
+ SetActive();
+ }
+
+ LOGTEXT("CLogServOperationQueue::StartNextOpL() - end");
+ }
+
+void CLogServOperationQueue::DeleteFromQueue(TSglQue<CLogServOperationBase>& aQueue, TLogOperationId aOperationId, TLogServSessionId aSessionId)
+//
+// Delete all operations belonging to a particular session from a queue
+//
+ {
+ LOGTEXT3("CLogServOperationQueue::DeleteFromQueue() - aId: %d, aSessionId: %d", aOperationId, aSessionId);
+
+ CLogServOperationBase* op = NULL;
+ while((op = FindOperation(aQueue, aOperationId, aSessionId)) != NULL)
+ {
+ delete op;
+
+ // We can exit now if we were looking for a particular operation
+ if (aOperationId > KLogNullOperationId)
+ {
+ LOGTEXT("CLogServOperationQueue::DeleteFromQueue() - operation found successfully");
+ return;
+ }
+ }
+
+#ifdef LOGGING_ENABLED
+ if (aOperationId != KLogNullOperationId)
+ {
+ LOGTEXT2("CLogServOperationQueue::DeleteFromQueue() - operation id '%d' wasn't found!", aOperationId);
+ }
+#endif
+
+ LOGTEXT("CLogServOperationQueue::DeleteFromQueue() - end");
+ }
+
+TBool CLogServOperationQueue::QueueContainsOperation(TSglQue<CLogServOperationBase>& aQueue, TLogOperationId aOperationId, TLogServSessionId aSessionId)
+//
+// Finds an operation in a queue
+//
+ {
+ LOGTEXT3("CLogServOperationQueue::QueueContainsOperation() - aId: %d, aSessionId: %d", aOperationId, aSessionId);
+
+ TSglQueIter<CLogServOperationBase> iter(aQueue);
+ CLogServOperationBase* item = NULL;
+
+ while ((item = iter++) != NULL)
+ {
+ if (item->Id() == aOperationId && item->SessionId() == aSessionId)
+ {
+ LOGTEXT("CLogServOperationQueue::QueueContainsOperation() - operation found within queue");
+ return ETrue;
+ }
+ }
+
+ LOGTEXT("CLogServOperationQueue::QueueContainsOperation() - queue doesn't contain operation");
+ return EFalse;
+ }
+
+CLogServOperationBase* CLogServOperationQueue::FindOperation(TSglQue<CLogServOperationBase>& aQueue, TLogOperationId aOperationId, TLogServSessionId aSessionId)
+//
+// Find the first operation in a queue belonging to a particular session
+//
+ {
+ LOGTEXT3("CLogServOperationQueue::FindOperation() - aId: %d, aSessionId: %d", aOperationId, aSessionId);
+
+ TSglQueIter<CLogServOperationBase> iter(aQueue);
+ CLogServOperationBase* item = NULL;
+
+ while ((item = iter++) != NULL)
+ {
+ if (item->SessionId() == aSessionId && (aOperationId == KLogNullOperationId || item->Id() == aOperationId))
+ {
+ LOGTEXT("CLogServOperationQueue::FindOperation() - operation found successfully");
+ return item;
+ }
+ }
+
+ LOGTEXT("CLogServOperationQueue::FindOperation() - operation not found");
+ return NULL;
+ }