--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mpx/commonframework/common/src/mpxtaskqueue.cpp Thu Dec 17 08:55:47 2009 +0200
@@ -0,0 +1,576 @@
+/*
+* 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: Serializing the task
+*
+*/
+
+#include <mpxlog.h>
+#include "mpxtaskqueueobserver.h"
+#include "mpxtaskqueue.h"
+
+// ============================ PRIVATE CLASS =================================
+NONSHARABLE_CLASS(CTask) : public CBase
+ {
+public:
+ /**
+ * C++ constructor
+ *
+ * @param aTask task id
+ * @param aCallback callback
+ * @param aHandler task handler
+ * @param aParamData data
+ * @param aBuf, extra data in buffer, ownership transferred.
+ * @param aPtrData, extra pointer data
+ * @param aAlive1, pointer to CBased object, ownership transferred
+ * @param aCObject2, pointer to CBased object, ownership transferred
+ */
+ CTask(TInt aTask,
+ TAny* aCallback,
+ MMPXTaskQueueObserver* aHandler,
+ TInt aParamData=0,
+ CBufBase* aBuf=NULL,
+ TAny* aPtrData=NULL,
+ CBase* aCObject1=NULL,
+ CBase* aCObject2=NULL
+ );
+
+ /**
+ * destructor
+ */
+ ~CTask();
+
+ /**
+ * Offset to the task queue
+ *
+ * @return the offset
+ */
+ static TInt Offset();
+
+public:
+ TInt iTask;
+ TAny* iCallback; // call back when task completed
+ MMPXTaskQueueObserver* iHandler; // task handler which will execute the task
+ TInt iParamData; // Integer data
+ CBufBase* iBuf; // owned. deleted when task is removed
+ TAny* iPtrData; // ojbect data, Not owned.
+ CBase* iCObject1; // owned
+ CBase* iCObject2; // owned
+
+ TPtrC8 iPtr; // Descriptor to iBuf
+ TSglQueLink iLink;
+ };
+
+// ----------------------------------------------------------------------------
+// Task contructor
+// ----------------------------------------------------------------------------
+//
+CTask::CTask(
+ TInt aTask,
+ TAny* aCallback,
+ MMPXTaskQueueObserver* aHandler,
+ TInt aParamData/*=0*/,
+ CBufBase* aBuf/*=NULL*/,
+ TAny* aPtrData/*=NULL*/,
+ CBase* aCObject1/*=NULL*/,
+ CBase* aCObject2/*=NULL*/)
+: iTask(aTask), iCallback(aCallback), iHandler(aHandler),
+ iParamData(aParamData),iBuf(aBuf), iPtrData(aPtrData),
+ iCObject1(aCObject1),iCObject2(aCObject2)
+ {
+ if (iBuf)
+ {
+ iPtr.Set(iBuf->Ptr(0));
+ }
+ else
+ {
+ iPtr.Set(KNullDesC8);
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Task destructor
+// ----------------------------------------------------------------------------
+//
+CTask::~CTask()
+ {
+ delete iBuf;
+ delete iCObject1;
+ delete iCObject2;
+ }
+
+// ----------------------------------------------------------------------------
+// Offset of the task queue
+// ----------------------------------------------------------------------------
+//
+TInt CTask::Offset()
+ {
+ return _FOFF(CTask,iLink);
+ }
+
+// ============================ PRIVATE CLASS =================================
+NONSHARABLE_CLASS(CMPXTaskQueueScheduler) : public CActive
+ {
+ public:
+ /**
+ * Two-phased constructor
+ * @param aObserver the observer
+ * @return object of constructed
+ */
+ static CMPXTaskQueueScheduler* NewL(TSglQue<CTask>& aTaskQueue);
+
+ /**
+ * Destructor
+ */
+ ~CMPXTaskQueueScheduler();
+
+ /**
+ * Schedule to execute next task
+ */
+ void ScheduleNextTask();
+
+ /**
+ * Complete current task
+ */
+ void CompleteTask();
+
+ public: // From base classes
+
+ /**
+ * From CActive
+ * Handles an active object's request completion event
+ */
+ void RunL();
+
+ /**
+ * From CActive
+ * Implements cancellation of an outstanding request.
+ */
+ void DoCancel();
+
+ private:
+ /**
+ * C++ constructor
+ *
+ * @param aObserver observer
+ */
+ CMPXTaskQueueScheduler(TSglQue<CTask>& aTaskQueue);
+
+ /**
+ * 2nd phase contructor
+ *
+ */
+ void ConstructL();
+
+ private:
+ TSglQue<CTask>& iTaskQueue;
+ TBool iTaskProcessing;
+ };
+
+// ----------------------------------------------------------------------------
+// Two-phased constructor
+// ----------------------------------------------------------------------------
+//
+CMPXTaskQueueScheduler* CMPXTaskQueueScheduler::NewL(TSglQue<CTask>& aTaskQueue)
+ {
+ CMPXTaskQueueScheduler* s = new(ELeave)CMPXTaskQueueScheduler(aTaskQueue);
+ CleanupStack::PushL(s);
+ s->ConstructL();
+ CleanupStack::Pop(s);
+ return s;
+ }
+
+// ----------------------------------------------------------------------------
+// Constructor.
+// ----------------------------------------------------------------------------
+//
+CMPXTaskQueueScheduler::CMPXTaskQueueScheduler(TSglQue<CTask>& aTaskQueue)
+ :CActive(EPriorityStandard),
+ iTaskQueue(aTaskQueue),
+ iTaskProcessing(EFalse)
+ {
+ CActiveScheduler::Add(this);
+ }
+
+// ----------------------------------------------------------------------------
+// Constructor.
+// ----------------------------------------------------------------------------
+//
+void CMPXTaskQueueScheduler::ConstructL()
+ {
+ }
+
+// ----------------------------------------------------------------------------
+// Destructor
+// ----------------------------------------------------------------------------
+//
+CMPXTaskQueueScheduler::~CMPXTaskQueueScheduler()
+ {
+ Cancel();
+ }
+
+// ----------------------------------------------------------------------------
+// Schedule to execute next task
+// ----------------------------------------------------------------------------
+//
+void CMPXTaskQueueScheduler::ScheduleNextTask()
+ {
+ if (!IsActive() && !iTaskProcessing)
+ {
+ SetActive();
+ TRequestStatus* status = &iStatus;
+ User::RequestComplete(status, KErrNone);
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Complete current task
+// ----------------------------------------------------------------------------
+//
+void CMPXTaskQueueScheduler::CompleteTask()
+ {
+ iTaskProcessing = EFalse;
+ }
+
+// ----------------------------------------------------------------------------
+// Plugin has completed the request
+// ----------------------------------------------------------------------------
+//
+void CMPXTaskQueueScheduler::RunL()
+ {
+ MPX_FUNC_EX("CMPXTaskQueueScheduler::RunL");
+ if (!iTaskQueue.IsEmpty())
+ {
+ CTask* task=iTaskQueue.First();
+ if (task->iHandler)
+ {
+ iTaskProcessing = ETrue;
+ MPX_DEBUG3("CMPXTaskQueueScheduler::RunL %d cb 0x%08x",
+ task->iTask, task->iCallback);
+ task->iHandler->ExecuteTask(task->iTask,
+ task->iParamData,
+ task->iPtrData,
+ *(task->iBuf),
+ task->iCallback,
+ task->iCObject1,
+ task->iCObject2);
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Canceling has to be done by plugin
+// ----------------------------------------------------------------------------
+//
+void CMPXTaskQueueScheduler::DoCancel()
+ {
+ iTaskProcessing = EFalse;
+ }
+
+
+// ============================ MEMBER FUNCTIONS ==============================
+
+// ----------------------------------------------------------------------------
+// Two-phased constructor
+// ----------------------------------------------------------------------------
+//
+EXPORT_C CMPXTaskQueue* CMPXTaskQueue::NewL()
+ {
+ CMPXTaskQueue* s = new(ELeave)CMPXTaskQueue();
+ CleanupStack::PushL(s);
+ s->ConstructL();
+ CleanupStack::Pop(s);
+ return s;
+ }
+
+// ----------------------------------------------------------------------------
+// Constructor.
+// ----------------------------------------------------------------------------
+//
+CMPXTaskQueue::CMPXTaskQueue()
+ :iTaskList(CTask::Offset())
+ {
+ }
+
+// ----------------------------------------------------------------------------
+// Destructor
+// ----------------------------------------------------------------------------
+//
+EXPORT_C CMPXTaskQueue::~CMPXTaskQueue()
+ {
+ Reset();
+ }
+
+// ----------------------------------------------------------------------------
+// Constructor.
+// ----------------------------------------------------------------------------
+//
+void CMPXTaskQueue::ConstructL()
+ {
+ }
+
+
+// ----------------------------------------------------------------------------
+// Add a task
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CMPXTaskQueue::AddTaskL(
+ TInt aTask,
+ TAny* aCallback,
+ TInt aParamData/*=0*/,
+ CBufBase* aBuf/*=NULL*/,
+ TAny* aPtrData/*=NULL*/,
+ CBase* aCObject1/*=NULL*/,
+ CBase* aCObject2/*=NULL*/)
+ {
+ MPX_FUNC_EX("CMPXTaskQueue::AddTaskL");
+ CTask* t=new(ELeave)CTask(aTask,aCallback,NULL, aParamData,
+ aBuf, aPtrData,aCObject1,aCObject2);
+ iTaskList.AddLast(*t);
+ }
+
+// ----------------------------------------------------------------------------
+// Remove a task
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TAny* CMPXTaskQueue::RemoveTask()
+ {
+ MPX_FUNC_EX("CMPXTaskQueue::RemoveTask()");
+ // Remove current task from queque
+ if (iTaskList.IsEmpty())
+ {
+ return NULL;
+ }
+ CTask* task=iTaskList.First();
+ TAny* cb=task->iCallback;
+ iTaskList.Remove(*task);
+ MPX_DEBUG3("CMPXTaskQueue::RemoveTask %d cb 0x%08x", task->iTask, cb);
+ delete task;
+ return cb;
+ }
+
+// ----------------------------------------------------------------------------
+// Remove task from a client
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CMPXTaskQueue::RemoveTask(TAny* aCallback)
+ {
+ MPX_FUNC_EX("CMPXTaskQueue::RemoveTask(TAny* aCallback)");
+ // Remove current task from queque
+ TSglQueIter<CTask> iter(iTaskList);
+ CTask* t=NULL;
+ while ((t=iter++) != NULL) // Compiler warning on while (t=iter++)
+ {
+ if (t->iCallback == aCallback)
+ {
+ iTaskList.Remove(*t);
+ MPX_DEBUG3("CMPXTaskQueue::RemoveTask %d cb 0x%08x",
+ t->iTask, aCallback);
+ delete t;
+ }
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Reutrn if the task queue empty
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TBool CMPXTaskQueue::IsEmpty()
+ {
+ return iTaskList.IsEmpty();
+ }
+
+// ----------------------------------------------------------------------------
+// Reset task queue
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CMPXTaskQueue::Reset()
+ {
+ TSglQueIter<CTask> iter(iTaskList);
+ CTask* t=NULL;
+ while ((t=iter++) != NULL) // Compiler warning on while (t=iter++)
+ {
+ delete t;
+ }
+ iTaskList.Reset();
+ }
+
+// ----------------------------------------------------------------------------
+// Return current task
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt CMPXTaskQueue::Param()
+ {
+ return iTaskList.IsEmpty() ? KErrNotFound : iTaskList.First()->iParamData;
+ }
+
+// ----------------------------------------------------------------------------
+// Return current parameter data
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TInt CMPXTaskQueue::Task()
+ {
+ return iTaskList.IsEmpty() ? KErrNotFound : iTaskList.First()->iTask;
+ }
+
+// ----------------------------------------------------------------------------
+// Return current call back
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TAny* CMPXTaskQueue::Callback()
+ {
+ return iTaskList.IsEmpty() ? NULL : iTaskList.First()->iCallback;
+ }
+
+// ----------------------------------------------------------------------------
+// Return pointer data
+// ----------------------------------------------------------------------------
+//
+EXPORT_C TAny* CMPXTaskQueue::PtrData()
+ {
+ return iTaskList.IsEmpty() ? NULL : iTaskList.First()->iPtrData;
+ }
+
+// ----------------------------------------------------------------------------
+// Return buffer data
+// ----------------------------------------------------------------------------
+//
+EXPORT_C const TDesC8& CMPXTaskQueue::BufData()
+ {
+ if (iTaskList.IsEmpty())
+ {
+ return KNullDesC8;
+ }
+ else
+ {
+ return iTaskList.First()->iPtr;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Two-phased constructor
+// ----------------------------------------------------------------------------
+//
+EXPORT_C CMPXActiveTaskQueue* CMPXActiveTaskQueue::NewL()
+ {
+ CMPXActiveTaskQueue* s = new(ELeave)CMPXActiveTaskQueue();
+ CleanupStack::PushL(s);
+ s->ConstructL();
+ CleanupStack::Pop(s);
+ return s;
+ }
+
+// ----------------------------------------------------------------------------
+// Constructor.
+// ----------------------------------------------------------------------------
+//
+CMPXActiveTaskQueue::CMPXActiveTaskQueue()
+ {
+ }
+
+// ----------------------------------------------------------------------------
+// Constructor.
+// ----------------------------------------------------------------------------
+//
+void CMPXActiveTaskQueue::ConstructL()
+ {
+ iScheduler = CMPXTaskQueueScheduler::NewL(iTaskList);
+ }
+
+
+// ----------------------------------------------------------------------------
+// Destructor
+// ----------------------------------------------------------------------------
+//
+EXPORT_C CMPXActiveTaskQueue::~CMPXActiveTaskQueue()
+ {
+ MPX_FUNC_EX("CMPXActiveTaskQueue::~CMPXActiveTaskQueue");
+ if (iScheduler)
+ {
+ delete iScheduler;
+ }
+ }
+
+// ----------------------------------------------------------------------------
+// Add a task
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CMPXActiveTaskQueue::AddTaskL(
+ TInt aTask,
+ TAny* aCallback,
+ MMPXTaskQueueObserver* aHandler,
+ TInt aParamData/*=0*/,
+ CBufBase* aBuf/*=NULL*/,
+ TAny* aPtrData/*=NULL*/,
+ CBase* aCObject1/*=NULL*/,
+ CBase* aCObject2/*=NULL*/)
+ {
+ MPX_FUNC_EX("CMPXActiveTaskQueue::AddTaskL");
+ CTask* t=new(ELeave)CTask(aTask,aCallback,aHandler,aParamData,
+ aBuf,aPtrData,aCObject1,aCObject2);
+ iTaskList.AddLast(*t);
+ ScheduleNextTask();
+ }
+
+// ----------------------------------------------------------------------------
+// Schedule to execute next task
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CMPXActiveTaskQueue::ScheduleNextTask()
+ {
+ iScheduler->ScheduleNextTask();
+ }
+
+// ----------------------------------------------------------------------------
+// Complete current task
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CMPXActiveTaskQueue::CompleteTask()
+ {
+ MPX_FUNC_EX("CMPXActiveTaskQueue::CompleteTask()");
+ (void)RemoveTask();
+ iScheduler->CompleteTask();
+ ScheduleNextTask();
+ }
+
+// ----------------------------------------------------------------------------
+// Cancels all outsatnding tasks
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CMPXActiveTaskQueue::CancelRequests()
+ {
+ MPX_FUNC_EX("CMPXActiveTaskQueue::CancelRequests");
+ iScheduler->Cancel();
+ CMPXTaskQueue::Reset();
+ }
+
+// ----------------------------------------------------------------------------
+// CMPXActiveTaskQueue::CompleteAllTasks
+// ----------------------------------------------------------------------------
+//
+EXPORT_C void CMPXActiveTaskQueue::CompleteAllTasks(
+ TInt aError)
+ {
+ MPX_FUNC_EX("CMPXActiveTaskQueue::CompleteAllTasks");
+ iScheduler->Cancel();
+
+ TSglQueIter<CTask> iter(iTaskList);
+ CTask* task(NULL);
+ while ((task = iter++) != NULL) // Compiler warning on while (t=iter++)
+ {
+ task->iHandler->HandleTaskError(task->iTask, task->iPtrData,
+ task->iCallback, aError);
+ delete task;
+ }
+ iTaskList.Reset();
+ }