loggingservices/eventlogger/LogServ/src/LogServOperationQueue.cpp
changeset 0 08ec8eefde2f
child 40 b8bdbc8f59c7
equal deleted inserted replaced
-1:000000000000 0:08ec8eefde2f
       
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "LogServOperationQueue.h"
       
    17 
       
    18 // User includes
       
    19 #include "logservpanic.h"
       
    20 #include "LogServOperationBase.h"
       
    21 #include "LogServTaskInterface.h"
       
    22 
       
    23 
       
    24 /////////////////////////////////////////////////////////////////////////////////////////
       
    25 // -----> CLogServOperationQueue (source)
       
    26 /////////////////////////////////////////////////////////////////////////////////////////
       
    27 
       
    28 CLogServOperationQueue::CLogServOperationQueue(MLogServTaskInterface& aTaskInterface, TInt aPriority)
       
    29 :	CActive(aPriority),
       
    30 	iTaskInterface(aTaskInterface),
       
    31 	iQueuePending(CLogServOperationBase::QueueOffset()),
       
    32 	iQueueCompleted(CLogServOperationBase::QueueOffset())
       
    33 	{
       
    34 	CActiveScheduler::Add(this);
       
    35 	}
       
    36 
       
    37 CLogServOperationQueue::~CLogServOperationQueue()
       
    38 	{
       
    39 	Cancel();
       
    40 	//
       
    41 	CLogServOperationBase* item = NULL;
       
    42 	//
       
    43 	TSglQueIter<CLogServOperationBase> pendingIterator(iQueuePending);
       
    44 	while ((item = pendingIterator++) != NULL)
       
    45 		{
       
    46 		delete item;
       
    47 		}
       
    48 	//
       
    49 	TSglQueIter<CLogServOperationBase> completedIterator(iQueueCompleted);
       
    50 	while ((item = completedIterator++) != NULL)
       
    51 		{
       
    52 		delete item;
       
    53 		}
       
    54 	}
       
    55 
       
    56 CLogServOperationQueue* CLogServOperationQueue::NewL(MLogServTaskInterface& aTaskInterface, TInt aPriority)
       
    57 	{
       
    58 	CLogServOperationQueue* self = new(ELeave) CLogServOperationQueue(aTaskInterface, aPriority);
       
    59 	return self;
       
    60 	}
       
    61 
       
    62 /////////////////////////////////////////////////////////////////////////////////////////
       
    63 /////////////////////////////////////////////////////////////////////////////////////////
       
    64 /////////////////////////////////////////////////////////////////////////////////////////
       
    65 
       
    66 void CLogServOperationQueue::OMOperationQueueAdd(CLogServOperationBase& aOp)
       
    67 //
       
    68 //	Add a new event to the queue and restart processing if necessary
       
    69 //
       
    70 	{
       
    71 	LOGTEXT3("CLogServOperationQueue::OMOperationQueueAdd() - Type: %d, Id: %d", aOp.Type(), aOp.Id());
       
    72 	//
       
    73 	iQueuePending.AddLast(aOp);
       
    74 	if	(!IsActive())
       
    75 		CompleteRequest();
       
    76 	//
       
    77 	LOGTEXT("CLogServOperationQueue::OMOperationQueueAdd() - end");
       
    78 	}
       
    79 
       
    80 //
       
    81 //	Removes an operation from the relevant server queue
       
    82 //
       
    83 void CLogServOperationQueue::OMOperationQueueRemove(CLogServOperationBase& aOperation)
       
    84 	{
       
    85 	const TLogOperationId operationId = aOperation.Id();
       
    86 	const TLogServSessionId sessionId = aOperation.SessionId();
       
    87 	//
       
    88 	LOGTEXT3("CLogServOperationQueue::OMOperationQueueRemove() - Id: %d, SessionId: %d", operationId, sessionId);
       
    89 	//
       
    90 	if(QueueContainsOperation(iQueuePending, operationId, sessionId))
       
    91 		{
       
    92 		iQueuePending.Remove(aOperation);
       
    93 		}
       
    94 	else
       
    95 		{
       
    96 		iQueueCompleted.Remove(aOperation);
       
    97 		}
       
    98 	//
       
    99 	LOGTEXT("CLogServOperationQueue::OMOperationQueueRemove() - end");
       
   100 	}
       
   101 
       
   102 void CLogServOperationQueue::OMGetResultL(TLogOperationId aId, TLogServSessionId aSessionId, const RMessage2& aMessageToWriteTo)
       
   103 //
       
   104 //	Get the result of a specific operation
       
   105 //
       
   106 	{
       
   107 	LOGTEXT3("CLogServOperationQueue::OMGetResultL() - Id: %d, SessionId: %d", aId, aSessionId);
       
   108 
       
   109 	// Look for the op
       
   110 	CLogServOperationBase* op = FindOperation(iQueueCompleted, aId, aSessionId);
       
   111 
       
   112 	// If we found it, then return the result
       
   113 	if	(op != NULL)
       
   114 		{
       
   115 		op->WriteL(aMessageToWriteTo);
       
   116 		delete op;
       
   117 		}
       
   118 	//
       
   119 	LOGTEXT("CLogServOperationQueue::OMGetResultL() - end");
       
   120 	}
       
   121 
       
   122 void CLogServOperationQueue::OMCancel(TLogOperationId aOpId, TLogServSessionId aSessionId, TBool aCompleteRequest)
       
   123 //
       
   124 //	Cancel a specific operation
       
   125 //
       
   126 	{
       
   127 	LOGTEXT4("CLogServOperationQueue::OMCancel() - Id: %d, SessionId: %d, CompleteRequest: %d", aOpId, aSessionId, aCompleteRequest);
       
   128 
       
   129 	if	(iCurrentOperation && iCurrentOperation->SessionId() == aSessionId && (aOpId == KLogNullOperationId || iCurrentOperation->Id() == aOpId))
       
   130 		{
       
   131 		// We need to cancel the current active operation because it belongs to this session
       
   132 		//
       
   133 		// This should complete the request with KErrCancel causing RunL to leave
       
   134 		// RunError completes the request and removes the operation from the pending queue
       
   135 		iTaskInterface.TaskCancelCurrent();
       
   136 		//
       
   137 		if	(!aCompleteRequest)
       
   138 			iCurrentOperation->ClearMessagePointer();
       
   139 		}
       
   140 	else
       
   141 		{
       
   142 		// The active operation doesn't belong to this session - just remove any relevant operations from the queues
       
   143 		//
       
   144 		// We are taking advantage of the fact that a session will only ever have one operation outstanding
       
   145 		// so a cancel request basically means - cancel everything belonging to the session
       
   146 		CLogServOperationBase* op = NULL;
       
   147 		while((op = FindOperation(iQueuePending, aOpId, aSessionId)) != NULL)
       
   148 			{
       
   149 			if	(aCompleteRequest)
       
   150 				{
       
   151 				op->Cancel();
       
   152 				}
       
   153 
       
   154 			// The operation dequeues itself from the containing queue in its destructor via
       
   155 			// the MLogServOperationManager abstract interface.
       
   156 			delete op;
       
   157 
       
   158 			// We can exit now if we were looking for a particular operation
       
   159 			if	(aOpId > KLogNullOperationId)
       
   160 				{
       
   161 				return;
       
   162 				}
       
   163 			}
       
   164 
       
   165 		// Just delete the completed operation
       
   166 		DeleteFromQueue(iQueueCompleted, aOpId, aSessionId);
       
   167 		}
       
   168 	//
       
   169 	LOGTEXT("CLogServOperationQueue::OMCancel() - end");
       
   170 	}
       
   171 
       
   172 //
       
   173 //	Stop/cancel and delete all operations belonging to a particular session
       
   174 //	If the session has just died we don't want to complete the request - the kernel would panic us
       
   175 //
       
   176 void CLogServOperationQueue::OMCancel(TLogServSessionId aSessionId, TBool aCompleteRequest)
       
   177 	{
       
   178 	OMCancel(KLogNullOperationId, aSessionId, aCompleteRequest);
       
   179 	}
       
   180 
       
   181 /////////////////////////////////////////////////////////////////////////////////////////
       
   182 /////////////////////////////////////////////////////////////////////////////////////////
       
   183 /////////////////////////////////////////////////////////////////////////////////////////
       
   184 
       
   185 void CLogServOperationQueue::RunL()
       
   186 //
       
   187 //	Called to indicate that the operation has completed - so complete the client request
       
   188 //
       
   189 	{
       
   190 	LOGTEXT2("CLogServOperationQueue::RunL(%d)", iStatus.Int());
       
   191 
       
   192 	// If the queue has just been restarted there won't be an existing operation
       
   193 	if (iCurrentOperation)
       
   194 		{
       
   195 		LOGTEXT3("CLogServOperationQueue::RunL() - Current operation Type: %d, Id: %d,", iCurrentOperation->Type(), iCurrentOperation->Id());
       
   196 
       
   197 		// Handle errors in RunError
       
   198 		User::LeaveIfError(iStatus.Int());
       
   199 
       
   200 		// Remember the type of operation for later
       
   201 		const TLogOperationType type = iCurrentOperation->Type();
       
   202 
       
   203 		// Complete the operation
       
   204 		if	(iCurrentOperation->CompleteProcessingL(iStatus.Int()) == CLogServOperationBase::EOperationComplete)
       
   205 			{
       
   206 			LOGTEXT("CLogServOperationQueue::RunL() - Operation is complete, deleting it");
       
   207 			delete iCurrentOperation;
       
   208 			iCurrentOperation = NULL;
       
   209 			}
       
   210 		else
       
   211 			{
       
   212 			// The client is going to ask for some results.
       
   213 			//
       
   214 			// Move the operation to another queue until it's done
       
   215 			// The session will actually delete the operation
       
   216 			LOGTEXT("CLogServOperationQueue::RunL() - Operation result awaiting client fetch");
       
   217 			iQueuePending.Remove(*iCurrentOperation);
       
   218 			iQueueCompleted.AddLast(*iCurrentOperation);
       
   219 			}
       
   220 
       
   221 		// Any errors from maintenance will be ignored because the operation is null
       
   222 		iCurrentOperation = NULL;
       
   223 
       
   224 		LOGTEXT("CLogServOperationQueue::RunL() - Starting maintenance");
       
   225 		iTaskInterface.TaskMaintenanceStartL(iStatus, type != ELogOperationEventGet);
       
   226 		SetActive();
       
   227 		}
       
   228 	else
       
   229 		{
       
   230 		LOGTEXT("CLogServOperationQueue::RunL() - finding next operation");
       
   231 
       
   232 		// Start the next operation
       
   233 		StartNextOpL();
       
   234 		}
       
   235 
       
   236 	LOGTEXT("CLogServOperationQueue::RunL() - end");
       
   237 	}
       
   238 
       
   239 void CLogServOperationQueue::DoCancel()
       
   240 //
       
   241 //	Implements cancel policy. Only called if the maintenance is active?
       
   242 //
       
   243 	{
       
   244 	iTaskInterface.TaskCancelCurrent();
       
   245 	}
       
   246 
       
   247 TInt CLogServOperationQueue::RunError(TInt aError)
       
   248 //
       
   249 //	Handle errors
       
   250 //
       
   251 	{
       
   252 	LOGTEXT2("CLogServOperationQueue::RunError(%d)", aError);
       
   253 
       
   254 	if	(iCurrentOperation)
       
   255 		{
       
   256 		LOGTEXT3("CLogServOperationQueue::RunError() - Current operation Type: %d, Id: %d,", iCurrentOperation->Type(), iCurrentOperation->Id());
       
   257 
       
   258 		// Fail the client request with the error
       
   259 		if	(iCurrentOperation->HaveMessagePointer())
       
   260 			iCurrentOperation->Complete(aError);
       
   261 		delete iCurrentOperation;
       
   262 		iCurrentOperation = NULL;
       
   263 		}
       
   264 
       
   265 	// Restart by mending the database if necessary
       
   266 	TRAPD(mendError, iTaskInterface.TaskMaintenanceStartL(iStatus, ETrue));
       
   267 	if	(mendError)
       
   268 		{
       
   269 		LOGTEXT2("CLogServOperationQueue::RunError() - mend error: %d)", mendError);
       
   270 
       
   271 		// Just ignore the maintenance error and complete ourselves so we continue to execute operations
       
   272 		CompleteRequest(KErrNone);
       
   273 		}
       
   274 	else
       
   275 		{
       
   276 		LOGTEXT("CLogServOperationQueue::RunError() - setting active again");
       
   277 		SetActive();
       
   278 		}
       
   279 
       
   280 	LOGTEXT("CLogServOperationQueue::RunError() - end");
       
   281 	return KErrNone;
       
   282 	}
       
   283 
       
   284 void CLogServOperationQueue::CompleteRequest(TInt aCompletionCode)
       
   285 	{
       
   286 	TRequestStatus* status = &iStatus;
       
   287 	User::RequestComplete(status, aCompletionCode);
       
   288 	SetActive();
       
   289 	}
       
   290 
       
   291 void CLogServOperationQueue::StartNextOpL()
       
   292 //
       
   293 //	Start the next operation on the queue
       
   294 //
       
   295 	{
       
   296 	LOGTEXT("CLogServOperationQueue::StartNextOpL()");
       
   297 
       
   298 	iCurrentOperation = NULL;
       
   299 	if (!IsActive() && !iQueuePending.IsEmpty())
       
   300 		{
       
   301 		iCurrentOperation = iQueuePending.First();
       
   302 
       
   303 		LOGTEXT3("CLogServOperationQueue::StartNextOpL() - New next operation, Type: %d, Id: %d", iCurrentOperation->Type(), iCurrentOperation->Id());
       
   304 
       
   305 		iCurrentOperation->StartL(iStatus);
       
   306 		SetActive();
       
   307 		}
       
   308 
       
   309 	LOGTEXT("CLogServOperationQueue::StartNextOpL() - end");
       
   310 	}
       
   311 
       
   312 void CLogServOperationQueue::DeleteFromQueue(TSglQue<CLogServOperationBase>& aQueue, TLogOperationId aOperationId, TLogServSessionId aSessionId)
       
   313 //
       
   314 //	Delete all operations belonging to a particular session from a queue
       
   315 //
       
   316 	{
       
   317 	LOGTEXT3("CLogServOperationQueue::DeleteFromQueue() - aId: %d, aSessionId: %d", aOperationId, aSessionId);
       
   318 
       
   319 	CLogServOperationBase* op = NULL;
       
   320 	while((op = FindOperation(aQueue, aOperationId, aSessionId)) != NULL)
       
   321 		{
       
   322 		delete op;
       
   323 
       
   324 		// We can exit now if we were looking for a particular operation
       
   325 		if	(aOperationId > KLogNullOperationId)
       
   326 			{
       
   327 			LOGTEXT("CLogServOperationQueue::DeleteFromQueue() - operation found successfully");
       
   328 			return;
       
   329 			}
       
   330 		}
       
   331 
       
   332 #ifdef LOGGING_ENABLED
       
   333 	if	(aOperationId != KLogNullOperationId)
       
   334 		{
       
   335 		LOGTEXT2("CLogServOperationQueue::DeleteFromQueue() - operation id '%d' wasn't found!", aOperationId);
       
   336 		}
       
   337 #endif
       
   338 
       
   339 	LOGTEXT("CLogServOperationQueue::DeleteFromQueue() - end");
       
   340 	}
       
   341 
       
   342 TBool CLogServOperationQueue::QueueContainsOperation(TSglQue<CLogServOperationBase>& aQueue, TLogOperationId aOperationId, TLogServSessionId aSessionId)
       
   343 //
       
   344 //	Finds an operation in a queue
       
   345 //
       
   346 	{
       
   347 	LOGTEXT3("CLogServOperationQueue::QueueContainsOperation() - aId: %d, aSessionId: %d", aOperationId, aSessionId);
       
   348 
       
   349 	TSglQueIter<CLogServOperationBase> iter(aQueue);
       
   350 	CLogServOperationBase* item = NULL;
       
   351 	
       
   352 	while ((item = iter++) != NULL)
       
   353 		{
       
   354 		if	(item->Id() == aOperationId && item->SessionId() == aSessionId)
       
   355 			{
       
   356 			LOGTEXT("CLogServOperationQueue::QueueContainsOperation() - operation found within queue");
       
   357 			return ETrue;
       
   358 			}
       
   359 		}
       
   360 	
       
   361 	LOGTEXT("CLogServOperationQueue::QueueContainsOperation() - queue doesn't contain operation");
       
   362 	return EFalse;
       
   363 	}
       
   364 
       
   365 CLogServOperationBase* CLogServOperationQueue::FindOperation(TSglQue<CLogServOperationBase>& aQueue, TLogOperationId aOperationId, TLogServSessionId aSessionId)
       
   366 //
       
   367 //	Find the first operation in a queue belonging to a particular session
       
   368 //
       
   369 	{
       
   370 	LOGTEXT3("CLogServOperationQueue::FindOperation() - aId: %d, aSessionId: %d", aOperationId, aSessionId);
       
   371 
       
   372 	TSglQueIter<CLogServOperationBase> iter(aQueue);
       
   373 	CLogServOperationBase* item = NULL;
       
   374 	
       
   375 	while ((item = iter++) != NULL)
       
   376 		{
       
   377 		if	(item->SessionId() == aSessionId && (aOperationId == KLogNullOperationId || item->Id() == aOperationId))
       
   378 			{
       
   379 			LOGTEXT("CLogServOperationQueue::FindOperation() - operation found successfully");
       
   380 			return item;
       
   381 			}
       
   382 		}
       
   383 
       
   384 	LOGTEXT("CLogServOperationQueue::FindOperation() - operation not found");
       
   385 	return NULL;	
       
   386 	}