| 1 | /*******************************************************************\r |
| 2 | *\r |
| 3 | * File: PolledAS.cpp\r |
| 4 | *\r |
| 5 | * Author: Peter van Sebille (peter@yipton.net)\r |
| 6 | *\r |
| 7 | * (c) Copyright 2002, Peter van Sebille\r |
| 8 | * All Rights Reserved\r |
| 9 | *\r |
| 10 | *******************************************************************/\r |
| 11 | \r |
| 12 | /*\r |
| 13 | * Oh Lord, forgive me for I have sinned.\r |
| 14 | * In their infinite wisdom, Symbian Engineers have decided that\r |
| 15 | * the Active Scheduler's queue of Active Objects is private\r |
| 16 | * and no getters are provided... sigh.\r |
| 17 | * This mere mortal will have to excercise the power of C pre-processor \r |
| 18 | * once more to circumvent the will of the gods.\r |
| 19 | */\r |
| 20 | \r |
| 21 | \r |
| 22 | #include <e32std.h>\r |
| 23 | \r |
| 24 | // from e32base.h\r |
| 25 | class CBase\r |
| 26 | {\r |
| 27 | public:\r |
| 28 | IMPORT_C virtual ~CBase();\r |
| 29 | inline TAny* operator new(TUint aSize,TAny *aBase) {Mem::FillZ(aBase,aSize);return(aBase);}\r |
| 30 | IMPORT_C TAny* operator new(TUint aSize);\r |
| 31 | inline TAny* operator new(TUint aSize, TLeave) {return newL(aSize);}\r |
| 32 | IMPORT_C TAny* operator new(TUint aSize,TUint anExtraSize);\r |
| 33 | protected:\r |
| 34 | IMPORT_C CBase();\r |
| 35 | private:\r |
| 36 | CBase(const CBase&);\r |
| 37 | CBase& operator=(const CBase&);\r |
| 38 | IMPORT_C static TAny* newL(TUint aSize);\r |
| 39 | };\r |
| 40 | \r |
| 41 | class CActive : public CBase\r |
| 42 | {\r |
| 43 | public:\r |
| 44 | enum TPriority\r |
| 45 | {\r |
| 46 | EPriorityIdle=-100,\r |
| 47 | EPriorityLow=-20,\r |
| 48 | EPriorityStandard=0,\r |
| 49 | EPriorityUserInput=10,\r |
| 50 | EPriorityHigh=20,\r |
| 51 | };\r |
| 52 | public:\r |
| 53 | IMPORT_C ~CActive();\r |
| 54 | IMPORT_C void Cancel();\r |
| 55 | IMPORT_C void Deque();\r |
| 56 | IMPORT_C void SetPriority(TInt aPriority);\r |
| 57 | inline TBool IsActive() const {return(iActive);}\r |
| 58 | inline TBool IsAdded() const {return(iLink.iNext!=NULL);}\r |
| 59 | inline TInt Priority() const {return iLink.iPriority;}\r |
| 60 | protected:\r |
| 61 | IMPORT_C CActive(TInt aPriority);\r |
| 62 | IMPORT_C void SetActive();\r |
| 63 | // Pure virtual\r |
| 64 | virtual void DoCancel() =0;\r |
| 65 | virtual void RunL() =0;\r |
| 66 | IMPORT_C virtual TInt RunError(TInt aError);\r |
| 67 | public:\r |
| 68 | TRequestStatus iStatus;\r |
| 69 | private:\r |
| 70 | TBool iActive;\r |
| 71 | TPriQueLink iLink;\r |
| 72 | friend class CActiveScheduler;\r |
| 73 | // friend class CServer;\r |
| 74 | friend class CPrivatePolledActiveScheduler; // added\r |
| 75 | };\r |
| 76 | \r |
| 77 | //\r |
| 78 | class CActiveScheduler : public CBase\r |
| 79 | {\r |
| 80 | public:\r |
| 81 | IMPORT_C CActiveScheduler();\r |
| 82 | IMPORT_C ~CActiveScheduler();\r |
| 83 | IMPORT_C static void Install(CActiveScheduler* aScheduler);\r |
| 84 | IMPORT_C static CActiveScheduler* Current();\r |
| 85 | IMPORT_C static void Add(CActive* anActive);\r |
| 86 | IMPORT_C static void Start();\r |
| 87 | IMPORT_C static void Stop();\r |
| 88 | IMPORT_C static TBool RunIfReady(TInt& aError, TInt aMinimumPriority);\r |
| 89 | IMPORT_C static CActiveScheduler* Replace(CActiveScheduler* aNewActiveScheduler);\r |
| 90 | IMPORT_C virtual void WaitForAnyRequest();\r |
| 91 | IMPORT_C virtual void Error(TInt anError) const;\r |
| 92 | private:\r |
| 93 | void DoStart();\r |
| 94 | IMPORT_C virtual void OnStarting();\r |
| 95 | IMPORT_C virtual void OnStopping();\r |
| 96 | IMPORT_C virtual void Reserved_1();\r |
| 97 | IMPORT_C virtual void Reserved_2();\r |
| 98 | friend class CPrivatePolledActiveScheduler; // added\r |
| 99 | protected:\r |
| 100 | inline TInt Level() const;\r |
| 101 | private:\r |
| 102 | TInt iLevel;\r |
| 103 | TPriQue<CActive> iActiveQ;\r |
| 104 | };\r |
| 105 | \r |
| 106 | class TCleanupItem;\r |
| 107 | class CleanupStack\r |
| 108 | {\r |
| 109 | public:\r |
| 110 | IMPORT_C static void PushL(TAny* aPtr);\r |
| 111 | IMPORT_C static void PushL(CBase* aPtr);\r |
| 112 | IMPORT_C static void PushL(TCleanupItem anItem);\r |
| 113 | IMPORT_C static void Pop();\r |
| 114 | IMPORT_C static void Pop(TInt aCount);\r |
| 115 | IMPORT_C static void PopAndDestroy();\r |
| 116 | IMPORT_C static void PopAndDestroy(TInt aCount);\r |
| 117 | IMPORT_C static void Check(TAny* aExpectedItem);\r |
| 118 | inline static void Pop(TAny* aExpectedItem);\r |
| 119 | inline static void Pop(TInt aCount, TAny* aLastExpectedItem);\r |
| 120 | inline static void PopAndDestroy(TAny* aExpectedItem);\r |
| 121 | inline static void PopAndDestroy(TInt aCount, TAny* aLastExpectedItem);\r |
| 122 | };\r |
| 123 | \r |
| 124 | \r |
| 125 | /*\r |
| 126 | * This will declare CPrivatePolledActiveScheduler as a friend\r |
| 127 | * of all classes that define a friend. CPrivatePolledActiveScheduler needs to\r |
| 128 | * be a friend of CActive\r |
| 129 | */\r |
| 130 | //#define friend friend class CPrivatePolledActiveScheduler; friend\r |
| 131 | \r |
| 132 | \r |
| 133 | /*\r |
| 134 | * This will change the:\r |
| 135 | * void DoStart();\r |
| 136 | * method in CActiveScheduler to:\r |
| 137 | * void DoStart(); friend class CPrivatePolledActiveScheduler;\r |
| 138 | * We need this to access the private datamembers in CActiveScheduler.\r |
| 139 | */\r |
| 140 | //#define DoStart() DoStart(); friend class CPrivatePolledActiveScheduler;\r |
| 141 | //#include <e32base.h>\r |
| 142 | #include "PolledAS.h"\r |
| 143 | \r |
| 144 | \r |
| 145 | class CPrivatePolledActiveScheduler : public CActiveScheduler\r |
| 146 | {\r |
| 147 | public:\r |
| 148 | void Schedule();\r |
| 149 | };\r |
| 150 | \r |
| 151 | \r |
| 152 | \r |
| 153 | void CPrivatePolledActiveScheduler::Schedule()\r |
| 154 | {\r |
| 155 | TDblQueIter<CActive> q(iActiveQ);\r |
| 156 | q.SetToFirst();\r |
| 157 | FOREVER\r |
| 158 | {\r |
| 159 | CActive *pR=q++;\r |
| 160 | if (pR)\r |
| 161 | {\r |
| 162 | if (pR->IsActive() && pR->iStatus!=KRequestPending)\r |
| 163 | {\r |
| 164 | pR->iActive=EFalse;\r |
| 165 | TRAPD(r,pR->RunL());\r |
| 166 | break;\r |
| 167 | }\r |
| 168 | }\r |
| 169 | else\r |
| 170 | break;\r |
| 171 | }\r |
| 172 | }\r |
| 173 | \r |
| 174 | \r |
| 175 | CPolledActiveScheduler::~CPolledActiveScheduler()\r |
| 176 | {\r |
| 177 | delete iPrivatePolledActiveScheduler;\r |
| 178 | }\r |
| 179 | \r |
| 180 | //static CPolledActiveScheduler* sPolledActiveScheduler = NULL;\r |
| 181 | CPolledActiveScheduler* CPolledActiveScheduler::NewL()\r |
| 182 | {\r |
| 183 | //sPolledActiveScheduler = \r |
| 184 | CPolledActiveScheduler* self = new(ELeave)CPolledActiveScheduler;\r |
| 185 | CleanupStack::PushL(self);\r |
| 186 | self->ConstructL();\r |
| 187 | CleanupStack::Pop();\r |
| 188 | return self;\r |
| 189 | }\r |
| 190 | \r |
| 191 | void CPolledActiveScheduler::ConstructL()\r |
| 192 | {\r |
| 193 | iPrivatePolledActiveScheduler = new(ELeave) CPrivatePolledActiveScheduler;\r |
| 194 | iPrivatePolledActiveScheduler->Install(iPrivatePolledActiveScheduler);\r |
| 195 | }\r |
| 196 | \r |
| 197 | \r |
| 198 | void CPolledActiveScheduler::Schedule()\r |
| 199 | {\r |
| 200 | iPrivatePolledActiveScheduler->Schedule();\r |
| 201 | }\r |
| 202 | \r |
| 203 | /*\r |
| 204 | CPolledActiveScheduler* CPolledActiveScheduler::Instance()\r |
| 205 | {\r |
| 206 | // return (CPolledActiveScheduler*) CActiveScheduler::Current();\r |
| 207 | return sPolledActiveScheduler;\r |
| 208 | }\r |
| 209 | */\r |