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