switch Cyclone to submodule on it's own git repo
[picodrive.git] / platform / uiq3 / engine / polledas.cpp
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         /**\r
29         Default constructor\r
30         */\r
31         inline CBase()  {}\r
32         IMPORT_C virtual ~CBase();\r
33         inline TAny* operator new(TUint aSize, TAny* aBase) __NO_THROW { Mem::FillZ(aBase, aSize); return aBase; }\r
34         inline TAny* operator new(TUint aSize) __NO_THROW { return User::AllocZ(aSize); }\r
35         inline TAny* operator new(TUint aSize, TLeave) { return User::AllocZL(aSize); }\r
36         inline TAny* operator new(TUint aSize, TUint aExtraSize) { return User::AllocZ(aSize + aExtraSize); }\r
37         inline TAny* operator new(TUint aSize, TLeave, TUint aExtraSize) { return User::AllocZL(aSize + aExtraSize); }\r
38         IMPORT_C static void Delete(CBase* aPtr);\r
39 protected:\r
40         IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1);\r
41 private:\r
42         CBase(const CBase&);\r
43         CBase& operator=(const CBase&);\r
44 private:\r
45         };\r
46 \r
47 \r
48 class TRequestStatusFaked\r
49         {\r
50 public:\r
51         inline TRequestStatusFaked() : iFlags(0) {};\r
52         inline TRequestStatusFaked(TInt aVal) : iStatus(aVal), iFlags(aVal==KRequestPending ? TRequestStatusFaked::ERequestPending : 0) {}\r
53 /*      inline TInt operator=(TInt aVal);\r
54         inline TBool operator==(TInt aVal) const;\r
55 */\r
56         inline TBool operator!=(TInt aVal) const {return(iStatus!=aVal);}\r
57 /*\r
58         inline TBool operator>=(TInt aVal) const;\r
59         inline TBool operator<=(TInt aVal) const;\r
60         inline TBool operator>(TInt aVal) const;\r
61         inline TBool operator<(TInt aVal) const;\r
62         inline TInt Int() const;\r
63 private:\r
64 */\r
65         enum\r
66                 {\r
67                 EActive                         = 1,  //bit0\r
68                 ERequestPending         = 2,  //bit1\r
69                 };\r
70         TInt iStatus;\r
71         TUint iFlags;\r
72         friend class CActive;\r
73         friend class CActiveScheduler;\r
74         friend class CServer2;\r
75         };\r
76 \r
77 \r
78 class CActive : public CBase\r
79         {\r
80 public:\r
81 enum TPriority\r
82         {\r
83         EPriorityIdle=-100,\r
84         EPriorityLow=-20,\r
85         EPriorityStandard=0,\r
86         EPriorityUserInput=10,\r
87         EPriorityHigh=20,\r
88         };\r
89 public:\r
90         IMPORT_C ~CActive();\r
91         IMPORT_C void Cancel();\r
92         IMPORT_C void Deque();\r
93         IMPORT_C void SetPriority(TInt aPriority);\r
94         inline TBool IsActive() const {return(iStatus.iFlags&TRequestStatus::EActive);}\r
95         inline TBool IsAdded() const {return(iLink.iNext!=NULL);}\r
96         inline TInt Priority() const {return iLink.iPriority;}\r
97 protected:\r
98         IMPORT_C CActive(TInt aPriority);\r
99         IMPORT_C void SetActive();\r
100         virtual void DoCancel() =0;\r
101         virtual void RunL() =0;\r
102         IMPORT_C virtual TInt RunError(TInt aError);\r
103 protected:\r
104         IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1);\r
105 public:\r
106         TRequestStatusFaked iStatus; // hope this will work\r
107 private:\r
108 //      TBool iActive;\r
109         TPriQueLink iLink;\r
110         TAny* iSpare;\r
111         friend class CActiveScheduler;\r
112         friend class CServer;\r
113         friend class CServer2;\r
114         friend class CPrivatePolledActiveScheduler; // added\r
115         };\r
116 \r
117 \r
118 \r
119 class CActiveScheduler : public CBase\r
120         {\r
121         friend class CActiveSchedulerWait;\r
122 public:\r
123         struct TLoop;\r
124         typedef TLoop* TLoopOwner;\r
125 public:\r
126         IMPORT_C CActiveScheduler();\r
127         IMPORT_C ~CActiveScheduler();\r
128         IMPORT_C static void Install(CActiveScheduler* aScheduler);\r
129         IMPORT_C static CActiveScheduler* Current();\r
130         IMPORT_C static void Add(CActive* aActive);\r
131         IMPORT_C static void Start();\r
132         IMPORT_C static void Stop();\r
133         IMPORT_C static TBool RunIfReady(TInt& aError, TInt aMinimumPriority);\r
134         IMPORT_C static CActiveScheduler* Replace(CActiveScheduler* aNewActiveScheduler);\r
135         IMPORT_C virtual void WaitForAnyRequest();\r
136         IMPORT_C virtual void Error(TInt aError) const;\r
137         IMPORT_C void Halt(TInt aExitCode) const;\r
138         IMPORT_C TInt StackDepth() const;\r
139 private:\r
140         static void Start(TLoopOwner* aOwner);\r
141         IMPORT_C virtual void OnStarting();\r
142         IMPORT_C virtual void OnStopping();\r
143         IMPORT_C virtual void Reserved_1();\r
144         IMPORT_C virtual void Reserved_2();\r
145         void Run(TLoopOwner* const volatile& aLoop);\r
146         void DoRunL(TLoopOwner* const volatile& aLoop, CActive* volatile & aCurrentObj);\r
147         friend class CPrivatePolledActiveScheduler; // added\r
148 protected:\r
149         IMPORT_C virtual TInt Extension_(TUint aExtensionId, TAny*& a0, TAny* a1);\r
150 protected:\r
151         inline TInt Level() const {return StackDepth();}        // deprecated\r
152 private:\r
153         TLoop* iStack;\r
154         TPriQue<CActive> iActiveQ;\r
155         TAny* iSpare;\r
156         };\r
157 \r
158 \r
159 \r
160 class TCleanupItem;\r
161 class CleanupStack\r
162         {\r
163 public:\r
164         IMPORT_C static void PushL(TAny* aPtr);\r
165         IMPORT_C static void PushL(CBase* aPtr);\r
166         IMPORT_C static void PushL(TCleanupItem anItem);\r
167         IMPORT_C static void Pop();\r
168         IMPORT_C static void Pop(TInt aCount);\r
169         IMPORT_C static void PopAndDestroy();\r
170         IMPORT_C static void PopAndDestroy(TInt aCount);\r
171         IMPORT_C static void Check(TAny* aExpectedItem);\r
172         inline static void Pop(TAny* aExpectedItem);\r
173         inline static void Pop(TInt aCount, TAny* aLastExpectedItem);\r
174         inline static void PopAndDestroy(TAny* aExpectedItem);\r
175         inline static void PopAndDestroy(TInt aCount, TAny* aLastExpectedItem);\r
176         };\r
177 \r
178 \r
179 /*\r
180  * This will declare CPrivatePolledActiveScheduler as a friend\r
181  * of all classes that define a friend. CPrivatePolledActiveScheduler needs to\r
182  * be a friend of CActive\r
183  */\r
184 //#define friend friend class CPrivatePolledActiveScheduler; friend\r
185 \r
186 \r
187 /*\r
188  * This will change the:\r
189  *               void DoStart();\r
190  * method in CActiveScheduler to:\r
191  *               void DoStart(); friend class CPrivatePolledActiveScheduler;\r
192  * We need this to access the private datamembers in CActiveScheduler.\r
193  */\r
194 //#define DoStart() DoStart(); friend class CPrivatePolledActiveScheduler;\r
195 //#include <e32base.h>\r
196 #include "PolledAS.h"\r
197 \r
198 \r
199 class CPrivatePolledActiveScheduler : public CActiveScheduler\r
200 {\r
201 public:\r
202         void Schedule();\r
203 };\r
204 \r
205 \r
206 void CPrivatePolledActiveScheduler::Schedule()\r
207 {\r
208         TDblQueIter<CActive> q(iActiveQ);\r
209         q.SetToFirst();\r
210         FOREVER\r
211         {\r
212                 CActive *pR=q++;\r
213                 if (pR)\r
214                 {\r
215                         //TRequestStatus::EActive                               = 1,  //bit0\r
216                         //TRequestStatus::ERequestPending               = 2,  //bit1\r
217                         if (pR->IsActive() && pR->iStatus!=KRequestPending)\r
218                         {\r
219 //                              pR->iActive=EFalse; // won't this cause trouble?\r
220                                 pR->iStatus.iFlags&=~TRequestStatusFaked::EActive;\r
221                                 //debugPrintFile(_L("as: %08x"), pR);\r
222                                 TRAPD(r,pR->RunL());\r
223                                 //pR->iStatus=TRequestStatus::ERequestPending;\r
224                                 break;\r
225                         }\r
226                 }\r
227                 else\r
228                         break;\r
229         }\r
230 }\r
231 \r
232 \r
233 static CPolledActiveScheduler* sPolledActiveScheduler = NULL;\r
234 \r
235 CPolledActiveScheduler::~CPolledActiveScheduler()\r
236 {\r
237         sPolledActiveScheduler = NULL;\r
238         delete iPrivatePolledActiveScheduler;\r
239 }\r
240 \r
241 CPolledActiveScheduler* CPolledActiveScheduler::NewL()\r
242 {\r
243         // if (sPolledActiveScheduler == NULL)\r
244         {\r
245                 sPolledActiveScheduler = new(ELeave)CPolledActiveScheduler;\r
246                 CleanupStack::PushL(sPolledActiveScheduler);\r
247                 sPolledActiveScheduler->ConstructL();\r
248                 CleanupStack::Pop();\r
249         }\r
250         return sPolledActiveScheduler;\r
251 }\r
252 \r
253 void CPolledActiveScheduler::ConstructL()\r
254 {\r
255         iPrivatePolledActiveScheduler = new(ELeave) CPrivatePolledActiveScheduler;\r
256         iPrivatePolledActiveScheduler->Install(iPrivatePolledActiveScheduler);\r
257 }\r
258 \r
259 \r
260 void CPolledActiveScheduler::Schedule()\r
261 {\r
262         iPrivatePolledActiveScheduler->Schedule();\r
263 }\r
264 \r
265 CPolledActiveScheduler* CPolledActiveScheduler::Instance()\r
266 {\r
267 //      return (CPolledActiveScheduler*) CActiveScheduler::Current();\r
268         return sPolledActiveScheduler;\r
269 }\r