mpx/commonframework/common/src/mpxtaskqueue.cpp
changeset 0 a2952bb97e68
--- /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();
+    }