os/persistentdata/loggingservices/eventlogger/LogServ/src/LogServOperationQueue.cpp
First public contribution.
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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
16 #include "LogServOperationQueue.h"
19 #include "logservpanic.h"
20 #include "LogServOperationBase.h"
21 #include "LogServTaskInterface.h"
24 /////////////////////////////////////////////////////////////////////////////////////////
25 // -----> CLogServOperationQueue (source)
26 /////////////////////////////////////////////////////////////////////////////////////////
28 CLogServOperationQueue::CLogServOperationQueue(MLogServTaskInterface& aTaskInterface, TInt aPriority)
30 iTaskInterface(aTaskInterface),
31 iQueuePending(CLogServOperationBase::QueueOffset()),
32 iQueueCompleted(CLogServOperationBase::QueueOffset())
34 CActiveScheduler::Add(this);
37 CLogServOperationQueue::~CLogServOperationQueue()
41 CLogServOperationBase* item = NULL;
43 TSglQueIter<CLogServOperationBase> pendingIterator(iQueuePending);
44 while ((item = pendingIterator++) != NULL)
49 TSglQueIter<CLogServOperationBase> completedIterator(iQueueCompleted);
50 while ((item = completedIterator++) != NULL)
56 CLogServOperationQueue* CLogServOperationQueue::NewL(MLogServTaskInterface& aTaskInterface, TInt aPriority)
58 CLogServOperationQueue* self = new(ELeave) CLogServOperationQueue(aTaskInterface, aPriority);
62 /////////////////////////////////////////////////////////////////////////////////////////
63 /////////////////////////////////////////////////////////////////////////////////////////
64 /////////////////////////////////////////////////////////////////////////////////////////
66 void CLogServOperationQueue::OMOperationQueueAdd(CLogServOperationBase& aOp)
68 // Add a new event to the queue and restart processing if necessary
71 LOGTEXT3("CLogServOperationQueue::OMOperationQueueAdd() - Type: %d, Id: %d", aOp.Type(), aOp.Id());
73 iQueuePending.AddLast(aOp);
77 LOGTEXT("CLogServOperationQueue::OMOperationQueueAdd() - end");
81 // Removes an operation from the relevant server queue
83 void CLogServOperationQueue::OMOperationQueueRemove(CLogServOperationBase& aOperation)
85 const TLogOperationId operationId = aOperation.Id();
86 const TLogServSessionId sessionId = aOperation.SessionId();
88 LOGTEXT3("CLogServOperationQueue::OMOperationQueueRemove() - Id: %d, SessionId: %d", operationId, sessionId);
90 if(QueueContainsOperation(iQueuePending, operationId, sessionId))
92 iQueuePending.Remove(aOperation);
96 iQueueCompleted.Remove(aOperation);
99 LOGTEXT("CLogServOperationQueue::OMOperationQueueRemove() - end");
102 void CLogServOperationQueue::OMGetResultL(TLogOperationId aId, TLogServSessionId aSessionId, const RMessage2& aMessageToWriteTo)
104 // Get the result of a specific operation
107 LOGTEXT3("CLogServOperationQueue::OMGetResultL() - Id: %d, SessionId: %d", aId, aSessionId);
110 CLogServOperationBase* op = FindOperation(iQueueCompleted, aId, aSessionId);
112 // If we found it, then return the result
115 op->WriteL(aMessageToWriteTo);
119 LOGTEXT("CLogServOperationQueue::OMGetResultL() - end");
122 void CLogServOperationQueue::OMCancel(TLogOperationId aOpId, TLogServSessionId aSessionId, TBool aCompleteRequest)
124 // Cancel a specific operation
127 LOGTEXT4("CLogServOperationQueue::OMCancel() - Id: %d, SessionId: %d, CompleteRequest: %d", aOpId, aSessionId, aCompleteRequest);
129 if (iCurrentOperation && iCurrentOperation->SessionId() == aSessionId && (aOpId == KLogNullOperationId || iCurrentOperation->Id() == aOpId))
131 // We need to cancel the current active operation because it belongs to this session
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();
138 // Do not complete the message when the operation completes
140 if (!aCompleteRequest)
142 iCurrentOperation->SetMessageCompletion(aCompleteRequest);
147 // The active operation doesn't belong to this session - just remove any relevant operations from the queues
149 // We are taking advantage of the fact that a session will only ever have one operation outstanding
150 // so a cancel request basically means - cancel everything belonging to the session
151 CLogServOperationBase* op = NULL;
152 while((op = FindOperation(iQueuePending, aOpId, aSessionId)) != NULL)
154 if (aCompleteRequest)
159 // The operation dequeues itself from the containing queue in its destructor via
160 // the MLogServOperationManager abstract interface.
163 // We can exit now if we were looking for a particular operation
164 if (aOpId > KLogNullOperationId)
170 // Just delete the completed operation
171 DeleteFromQueue(iQueueCompleted, aOpId, aSessionId);
174 LOGTEXT("CLogServOperationQueue::OMCancel() - end");
178 // Stop/cancel and delete all operations belonging to a particular session
179 // If the session has just died we don't want to complete the request - the kernel would panic us
181 void CLogServOperationQueue::OMCancel(TLogServSessionId aSessionId, TBool aCompleteRequest)
183 OMCancel(KLogNullOperationId, aSessionId, aCompleteRequest);
186 /////////////////////////////////////////////////////////////////////////////////////////
187 /////////////////////////////////////////////////////////////////////////////////////////
188 /////////////////////////////////////////////////////////////////////////////////////////
190 void CLogServOperationQueue::RunL()
192 // Called to indicate that the operation has completed - so complete the client request
195 LOGTEXT2("CLogServOperationQueue::RunL(%d)", iStatus.Int());
197 // If the queue has just been restarted there won't be an existing operation
198 if (iCurrentOperation)
200 LOGTEXT3("CLogServOperationQueue::RunL() - Current operation Type: %d, Id: %d,", iCurrentOperation->Type(), iCurrentOperation->Id());
202 // Handle errors in RunError
203 User::LeaveIfError(iStatus.Int());
205 // Remember the type of operation for later
206 const TLogOperationType type = iCurrentOperation->Type();
208 // Complete the operation
209 if (iCurrentOperation->CompleteProcessingL(iStatus.Int()) == CLogServOperationBase::EOperationComplete)
211 LOGTEXT("CLogServOperationQueue::RunL() - Operation is complete, deleting it");
212 delete iCurrentOperation;
213 iCurrentOperation = NULL;
217 // The client is going to ask for some results.
219 // Move the operation to another queue until it's done
220 // The session will actually delete the operation
221 LOGTEXT("CLogServOperationQueue::RunL() - Operation result awaiting client fetch");
222 iQueuePending.Remove(*iCurrentOperation);
223 iQueueCompleted.AddLast(*iCurrentOperation);
226 // Any errors from maintenance will be ignored because the operation is null
227 iCurrentOperation = NULL;
229 LOGTEXT("CLogServOperationQueue::RunL() - Starting maintenance");
230 iTaskInterface.TaskMaintenanceStartL(iStatus, type != ELogOperationEventGet);
235 LOGTEXT("CLogServOperationQueue::RunL() - finding next operation");
237 // Start the next operation
241 LOGTEXT("CLogServOperationQueue::RunL() - end");
244 void CLogServOperationQueue::DoCancel()
246 // Implements cancel policy. Only called if the maintenance is active?
249 iTaskInterface.TaskCancelCurrent();
252 TInt CLogServOperationQueue::RunError(TInt aError)
257 LOGTEXT2("CLogServOperationQueue::RunError(%d)", aError);
259 if (iCurrentOperation)
261 LOGTEXT3("CLogServOperationQueue::RunError() - Current operation Type: %d, Id: %d,", iCurrentOperation->Type(), iCurrentOperation->Id());
263 // Fail the client request with the error
264 if (iCurrentOperation->HaveMessagePointer())
265 iCurrentOperation->Complete(aError);
266 delete iCurrentOperation;
267 iCurrentOperation = NULL;
270 // Restart by mending the database if necessary
271 TRAPD(mendError, iTaskInterface.TaskMaintenanceStartL(iStatus, ETrue));
274 LOGTEXT2("CLogServOperationQueue::RunError() - mend error: %d)", mendError);
276 // Just ignore the maintenance error and complete ourselves so we continue to execute operations
277 CompleteRequest(KErrNone);
281 LOGTEXT("CLogServOperationQueue::RunError() - setting active again");
285 LOGTEXT("CLogServOperationQueue::RunError() - end");
289 void CLogServOperationQueue::CompleteRequest(TInt aCompletionCode)
291 TRequestStatus* status = &iStatus;
292 User::RequestComplete(status, aCompletionCode);
296 void CLogServOperationQueue::StartNextOpL()
298 // Start the next operation on the queue
301 LOGTEXT("CLogServOperationQueue::StartNextOpL()");
303 iCurrentOperation = NULL;
304 if (!IsActive() && !iQueuePending.IsEmpty())
306 iCurrentOperation = iQueuePending.First();
308 LOGTEXT3("CLogServOperationQueue::StartNextOpL() - New next operation, Type: %d, Id: %d", iCurrentOperation->Type(), iCurrentOperation->Id());
310 iCurrentOperation->StartL(iStatus);
314 LOGTEXT("CLogServOperationQueue::StartNextOpL() - end");
317 void CLogServOperationQueue::DeleteFromQueue(TSglQue<CLogServOperationBase>& aQueue, TLogOperationId aOperationId, TLogServSessionId aSessionId)
319 // Delete all operations belonging to a particular session from a queue
322 LOGTEXT3("CLogServOperationQueue::DeleteFromQueue() - aId: %d, aSessionId: %d", aOperationId, aSessionId);
324 CLogServOperationBase* op = NULL;
325 while((op = FindOperation(aQueue, aOperationId, aSessionId)) != NULL)
329 // We can exit now if we were looking for a particular operation
330 if (aOperationId > KLogNullOperationId)
332 LOGTEXT("CLogServOperationQueue::DeleteFromQueue() - operation found successfully");
337 #ifdef LOGGING_ENABLED
338 if (aOperationId != KLogNullOperationId)
340 LOGTEXT2("CLogServOperationQueue::DeleteFromQueue() - operation id '%d' wasn't found!", aOperationId);
344 LOGTEXT("CLogServOperationQueue::DeleteFromQueue() - end");
347 TBool CLogServOperationQueue::QueueContainsOperation(TSglQue<CLogServOperationBase>& aQueue, TLogOperationId aOperationId, TLogServSessionId aSessionId)
349 // Finds an operation in a queue
352 LOGTEXT3("CLogServOperationQueue::QueueContainsOperation() - aId: %d, aSessionId: %d", aOperationId, aSessionId);
354 TSglQueIter<CLogServOperationBase> iter(aQueue);
355 CLogServOperationBase* item = NULL;
357 while ((item = iter++) != NULL)
359 if (item->Id() == aOperationId && item->SessionId() == aSessionId)
361 LOGTEXT("CLogServOperationQueue::QueueContainsOperation() - operation found within queue");
366 LOGTEXT("CLogServOperationQueue::QueueContainsOperation() - queue doesn't contain operation");
370 CLogServOperationBase* CLogServOperationQueue::FindOperation(TSglQue<CLogServOperationBase>& aQueue, TLogOperationId aOperationId, TLogServSessionId aSessionId)
372 // Find the first operation in a queue belonging to a particular session
375 LOGTEXT3("CLogServOperationQueue::FindOperation() - aId: %d, aSessionId: %d", aOperationId, aSessionId);
377 TSglQueIter<CLogServOperationBase> iter(aQueue);
378 CLogServOperationBase* item = NULL;
380 while ((item = iter++) != NULL)
382 if (item->SessionId() == aSessionId && (aOperationId == KLogNullOperationId || item->Id() == aOperationId))
384 LOGTEXT("CLogServOperationQueue::FindOperation() - operation found successfully");
389 LOGTEXT("CLogServOperationQueue::FindOperation() - operation not found");