+/*******************************************************************\r
+ *\r
+ * File: PolledAS.cpp\r
+ *\r
+ * Author: Peter van Sebille (peter@yipton.net)\r
+ *\r
+ * (c) Copyright 2002, Peter van Sebille\r
+ * All Rights Reserved\r
+ *\r
+ *******************************************************************/\r
+\r
+/*\r
+ * Oh Lord, forgive me for I have sinned.\r
+ * In their infinite wisdom, Symbian Engineers have decided that\r
+ * the Active Scheduler's queue of Active Objects is private\r
+ * and no getters are provided... sigh.\r
+ * This mere mortal will have to excercise the power of C pre-processor \r
+ * once more to circumvent the will of the gods.\r
+ */\r
+\r
+\r
+#include <e32std.h>\r
+\r
+// from e32base.h\r
+class CBase\r
+ {\r
+public:\r
+ /**\r
+ Default constructor\r
+ */\r
+ inline CBase() {}\r
+ IMPORT_C virtual ~CBase();\r
+ inline TAny* operator new(TUint aSize, TAny* aBase) __NO_THROW { Mem::FillZ(aBase, aSize); return aBase; }\r
+ inline TAny* operator new(TUint aSize) __NO_THROW { return User::AllocZ(aSize); }\r
+ inline TAny* operator new(TUint aSize, TLeave) { return User::AllocZL(aSize); }\r
+ inline TAny* operator new(TUint aSize, TUint aExtraSize) { return User::AllocZ(aSize + aExtraSize); }\r
+ inline TAny* operator new(TUint aSize, TLeave, TUint aExtraSize) { return User::AllocZL(aSize + aExtraSize); }\r
+ IMPORT_C static void Delete(CBase* aPtr);\r
+protected:\r
+ IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1);\r
+private:\r
+ CBase(const CBase&);\r
+ CBase& operator=(const CBase&);\r
+private:\r
+ };\r
+\r
+\r
+class TRequestStatusFaked\r
+ {\r
+public:\r
+ inline TRequestStatusFaked() : iFlags(0) {};\r
+ inline TRequestStatusFaked(TInt aVal) : iStatus(aVal), iFlags(aVal==KRequestPending ? TRequestStatusFaked::ERequestPending : 0) {}\r
+/* inline TInt operator=(TInt aVal);\r
+ inline TBool operator==(TInt aVal) const;\r
+*/\r
+ inline TBool operator!=(TInt aVal) const {return(iStatus!=aVal);}\r
+/*\r
+ inline TBool operator>=(TInt aVal) const;\r
+ inline TBool operator<=(TInt aVal) const;\r
+ inline TBool operator>(TInt aVal) const;\r
+ inline TBool operator<(TInt aVal) const;\r
+ inline TInt Int() const;\r
+private:\r
+*/\r
+ enum\r
+ {\r
+ EActive = 1, //bit0\r
+ ERequestPending = 2, //bit1\r
+ };\r
+ TInt iStatus;\r
+ TUint iFlags;\r
+ friend class CActive;\r
+ friend class CActiveScheduler;\r
+ friend class CServer2;\r
+ };\r
+\r
+\r
+class CActive : public CBase\r
+ {\r
+public:\r
+enum TPriority\r
+ {\r
+ EPriorityIdle=-100,\r
+ EPriorityLow=-20,\r
+ EPriorityStandard=0,\r
+ EPriorityUserInput=10,\r
+ EPriorityHigh=20,\r
+ };\r
+public:\r
+ IMPORT_C ~CActive();\r
+ IMPORT_C void Cancel();\r
+ IMPORT_C void Deque();\r
+ IMPORT_C void SetPriority(TInt aPriority);\r
+ inline TBool IsActive() const {return(iStatus.iFlags&TRequestStatus::EActive);}\r
+ inline TBool IsAdded() const {return(iLink.iNext!=NULL);}\r
+ inline TInt Priority() const {return iLink.iPriority;}\r
+protected:\r
+ IMPORT_C CActive(TInt aPriority);\r
+ IMPORT_C void SetActive();\r
+ virtual void DoCancel() =0;\r
+ virtual void RunL() =0;\r
+ IMPORT_C virtual TInt RunError(TInt aError);\r
+protected:\r
+ IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1);\r
+public:\r
+ TRequestStatusFaked iStatus; // hope this will work\r
+private:\r
+// TBool iActive;\r
+ TPriQueLink iLink;\r
+ TAny* iSpare;\r
+ friend class CActiveScheduler;\r
+ friend class CServer;\r
+ friend class CServer2;\r
+ friend class CPrivatePolledActiveScheduler; // added\r
+ };\r
+\r
+\r
+\r
+class CActiveScheduler : public CBase\r
+ {\r
+ friend class CActiveSchedulerWait;\r
+public:\r
+ struct TLoop;\r
+ typedef TLoop* TLoopOwner;\r
+public:\r
+ IMPORT_C CActiveScheduler();\r
+ IMPORT_C ~CActiveScheduler();\r
+ IMPORT_C static void Install(CActiveScheduler* aScheduler);\r
+ IMPORT_C static CActiveScheduler* Current();\r
+ IMPORT_C static void Add(CActive* aActive);\r
+ IMPORT_C static void Start();\r
+ IMPORT_C static void Stop();\r
+ IMPORT_C static TBool RunIfReady(TInt& aError, TInt aMinimumPriority);\r
+ IMPORT_C static CActiveScheduler* Replace(CActiveScheduler* aNewActiveScheduler);\r
+ IMPORT_C virtual void WaitForAnyRequest();\r
+ IMPORT_C virtual void Error(TInt aError) const;\r
+ IMPORT_C void Halt(TInt aExitCode) const;\r
+ IMPORT_C TInt StackDepth() const;\r
+private:\r
+ static void Start(TLoopOwner* aOwner);\r
+ IMPORT_C virtual void OnStarting();\r
+ IMPORT_C virtual void OnStopping();\r
+ IMPORT_C virtual void Reserved_1();\r
+ IMPORT_C virtual void Reserved_2();\r
+ void Run(TLoopOwner* const volatile& aLoop);\r
+ void DoRunL(TLoopOwner* const volatile& aLoop, CActive* volatile & aCurrentObj);\r
+ friend class CPrivatePolledActiveScheduler; // added\r
+protected:\r
+ IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1);\r
+protected:\r
+ inline TInt Level() const {return StackDepth();} // deprecated\r
+private:\r
+ TLoop* iStack;\r
+ TPriQue<CActive> iActiveQ;\r
+ TAny* iSpare;\r
+ };\r
+\r
+\r
+\r
+class TCleanupItem;\r
+class CleanupStack\r
+ {\r
+public:\r
+ IMPORT_C static void PushL(TAny* aPtr);\r
+ IMPORT_C static void PushL(CBase* aPtr);\r
+ IMPORT_C static void PushL(TCleanupItem anItem);\r
+ IMPORT_C static void Pop();\r
+ IMPORT_C static void Pop(TInt aCount);\r
+ IMPORT_C static void PopAndDestroy();\r
+ IMPORT_C static void PopAndDestroy(TInt aCount);\r
+ IMPORT_C static void Check(TAny* aExpectedItem);\r
+ inline static void Pop(TAny* aExpectedItem);\r
+ inline static void Pop(TInt aCount, TAny* aLastExpectedItem);\r
+ inline static void PopAndDestroy(TAny* aExpectedItem);\r
+ inline static void PopAndDestroy(TInt aCount, TAny* aLastExpectedItem);\r
+ };\r
+\r
+\r
+/*\r
+ * This will declare CPrivatePolledActiveScheduler as a friend\r
+ * of all classes that define a friend. CPrivatePolledActiveScheduler needs to\r
+ * be a friend of CActive\r
+ */\r
+//#define friend friend class CPrivatePolledActiveScheduler; friend\r
+\r
+\r
+/*\r
+ * This will change the:\r
+ * void DoStart();\r
+ * method in CActiveScheduler to:\r
+ * void DoStart(); friend class CPrivatePolledActiveScheduler;\r
+ * We need this to access the private datamembers in CActiveScheduler.\r
+ */\r
+//#define DoStart() DoStart(); friend class CPrivatePolledActiveScheduler;\r
+//#include <e32base.h>\r
+#include "PolledAS.h"\r
+\r
+\r
+class CPrivatePolledActiveScheduler : public CActiveScheduler\r
+{\r
+public:\r
+ void Schedule();\r
+};\r
+\r
+\r
+void CPrivatePolledActiveScheduler::Schedule()\r
+{\r
+ TDblQueIter<CActive> q(iActiveQ);\r
+ q.SetToFirst();\r
+ FOREVER\r
+ {\r
+ CActive *pR=q++;\r
+ if (pR)\r
+ {\r
+ //TRequestStatus::EActive = 1, //bit0\r
+ //TRequestStatus::ERequestPending = 2, //bit1\r
+ if (pR->IsActive() && pR->iStatus!=KRequestPending)\r
+ {\r
+// pR->iActive=EFalse; // won't this cause trouble?\r
+ pR->iStatus.iFlags&=~TRequestStatusFaked::EActive;\r
+ //debugPrintFile(_L("as: %08x"), pR);\r
+ TRAPD(r,pR->RunL());\r
+ //pR->iStatus=TRequestStatus::ERequestPending;\r
+ break;\r
+ }\r
+ }\r
+ else\r
+ break;\r
+ }\r
+}\r
+\r
+\r
+static CPolledActiveScheduler* sPolledActiveScheduler = NULL;\r
+\r
+CPolledActiveScheduler::~CPolledActiveScheduler()\r
+{\r
+ sPolledActiveScheduler = NULL;\r
+ delete iPrivatePolledActiveScheduler;\r
+}\r
+\r
+CPolledActiveScheduler* CPolledActiveScheduler::NewL()\r
+{\r
+ // if (sPolledActiveScheduler == NULL)\r
+ {\r
+ sPolledActiveScheduler = new(ELeave)CPolledActiveScheduler;\r
+ CleanupStack::PushL(sPolledActiveScheduler);\r
+ sPolledActiveScheduler->ConstructL();\r
+ CleanupStack::Pop();\r
+ }\r
+ return sPolledActiveScheduler;\r
+}\r
+\r
+void CPolledActiveScheduler::ConstructL()\r
+{\r
+ iPrivatePolledActiveScheduler = new(ELeave) CPrivatePolledActiveScheduler;\r
+ iPrivatePolledActiveScheduler->Install(iPrivatePolledActiveScheduler);\r
+}\r
+\r
+\r
+void CPolledActiveScheduler::Schedule()\r
+{\r
+ iPrivatePolledActiveScheduler->Schedule();\r
+}\r
+\r
+CPolledActiveScheduler* CPolledActiveScheduler::Instance()\r
+{\r
+// return (CPolledActiveScheduler*) CActiveScheduler::Current();\r
+ return sPolledActiveScheduler;\r
+}\r