sl@0
|
1 |
// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
|
sl@0
|
2 |
// All rights reserved.
|
sl@0
|
3 |
// This component and the accompanying materials are made available
|
sl@0
|
4 |
// under the terms of the License "Eclipse Public License v1.0"
|
sl@0
|
5 |
// which accompanies this distribution, and is available
|
sl@0
|
6 |
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
sl@0
|
7 |
//
|
sl@0
|
8 |
// Initial Contributors:
|
sl@0
|
9 |
// Nokia Corporation - initial contribution.
|
sl@0
|
10 |
//
|
sl@0
|
11 |
// Contributors:
|
sl@0
|
12 |
//
|
sl@0
|
13 |
// Description:
|
sl@0
|
14 |
// e32\euser\cbase\ub_cln.cpp
|
sl@0
|
15 |
//
|
sl@0
|
16 |
//
|
sl@0
|
17 |
|
sl@0
|
18 |
#include "ub_std.h"
|
sl@0
|
19 |
#include "us_data.h"
|
sl@0
|
20 |
|
sl@0
|
21 |
const TInt KCleanupGranularity=4;
|
sl@0
|
22 |
const TInt KCleanupInitialSlots=8;
|
sl@0
|
23 |
|
sl@0
|
24 |
LOCAL_C void doDelete(CBase *aPtr)
|
sl@0
|
25 |
//
|
sl@0
|
26 |
// Delete the CBase pointer
|
sl@0
|
27 |
//
|
sl@0
|
28 |
{
|
sl@0
|
29 |
|
sl@0
|
30 |
delete aPtr;
|
sl@0
|
31 |
}
|
sl@0
|
32 |
|
sl@0
|
33 |
LOCAL_C CCleanup &cleanup()
|
sl@0
|
34 |
//
|
sl@0
|
35 |
// Return the CTrapHandler's cleanup list.
|
sl@0
|
36 |
//
|
sl@0
|
37 |
{
|
sl@0
|
38 |
|
sl@0
|
39 |
TCleanupTrapHandler *pH=(TCleanupTrapHandler *)GetTrapHandler();
|
sl@0
|
40 |
__ASSERT_ALWAYS(pH!=NULL,Panic(EClnNoTrapHandlerInstalled));
|
sl@0
|
41 |
return(pH->Cleanup());
|
sl@0
|
42 |
}
|
sl@0
|
43 |
|
sl@0
|
44 |
|
sl@0
|
45 |
|
sl@0
|
46 |
|
sl@0
|
47 |
TCleanupTrapHandler::TCleanupTrapHandler()
|
sl@0
|
48 |
: iCleanup(NULL)
|
sl@0
|
49 |
/**
|
sl@0
|
50 |
Default constructor.
|
sl@0
|
51 |
*/
|
sl@0
|
52 |
{}
|
sl@0
|
53 |
|
sl@0
|
54 |
|
sl@0
|
55 |
|
sl@0
|
56 |
|
sl@0
|
57 |
void TCleanupTrapHandler::Trap()
|
sl@0
|
58 |
/**
|
sl@0
|
59 |
Deals with the invocation of a call to TRAP.
|
sl@0
|
60 |
*/
|
sl@0
|
61 |
{
|
sl@0
|
62 |
|
sl@0
|
63 |
iCleanup->NextLevel();
|
sl@0
|
64 |
}
|
sl@0
|
65 |
|
sl@0
|
66 |
|
sl@0
|
67 |
|
sl@0
|
68 |
|
sl@0
|
69 |
void TCleanupTrapHandler::UnTrap()
|
sl@0
|
70 |
/**
|
sl@0
|
71 |
Deals with a function exiting a TRAP without leaving.
|
sl@0
|
72 |
*/
|
sl@0
|
73 |
{
|
sl@0
|
74 |
|
sl@0
|
75 |
iCleanup->PreviousLevel();
|
sl@0
|
76 |
}
|
sl@0
|
77 |
|
sl@0
|
78 |
|
sl@0
|
79 |
|
sl@0
|
80 |
|
sl@0
|
81 |
void TCleanupTrapHandler::Leave(TInt /*aValue*/)
|
sl@0
|
82 |
/**
|
sl@0
|
83 |
Deals with a function within a TRAP leaving.
|
sl@0
|
84 |
|
sl@0
|
85 |
@param aValue The leave value.
|
sl@0
|
86 |
*/
|
sl@0
|
87 |
{
|
sl@0
|
88 |
|
sl@0
|
89 |
iCleanup->PopAndDestroyAll();
|
sl@0
|
90 |
}
|
sl@0
|
91 |
|
sl@0
|
92 |
|
sl@0
|
93 |
|
sl@0
|
94 |
|
sl@0
|
95 |
class TCleanupStackItem
|
sl@0
|
96 |
{
|
sl@0
|
97 |
public:
|
sl@0
|
98 |
void Set(const TCleanupItem &aItem);
|
sl@0
|
99 |
inline void Cleanup();
|
sl@0
|
100 |
inline TBool IsLevelMarker() const;
|
sl@0
|
101 |
inline void MarkLevel();
|
sl@0
|
102 |
inline void PushLevel();
|
sl@0
|
103 |
inline TInt PopLevel();
|
sl@0
|
104 |
inline TBool Check(TAny* aExpectedItem) const;
|
sl@0
|
105 |
private:
|
sl@0
|
106 |
TCleanupOperation iOperation;
|
sl@0
|
107 |
union
|
sl@0
|
108 |
{
|
sl@0
|
109 |
TAny *iPtr;
|
sl@0
|
110 |
TInt iLevelCount; // may stack >1 level on this entry
|
sl@0
|
111 |
};
|
sl@0
|
112 |
};
|
sl@0
|
113 |
inline void TCleanupStackItem::MarkLevel()
|
sl@0
|
114 |
{ iOperation=NULL; iLevelCount=1; }
|
sl@0
|
115 |
inline TBool TCleanupStackItem::IsLevelMarker() const
|
sl@0
|
116 |
{ return (iOperation==NULL); }
|
sl@0
|
117 |
inline void TCleanupStackItem::Cleanup()
|
sl@0
|
118 |
{ (*iOperation)(iPtr); }
|
sl@0
|
119 |
inline void TCleanupStackItem::PushLevel()
|
sl@0
|
120 |
{ ++iLevelCount; }
|
sl@0
|
121 |
inline TInt TCleanupStackItem::PopLevel()
|
sl@0
|
122 |
{ return (--iLevelCount); }
|
sl@0
|
123 |
inline TBool TCleanupStackItem::Check(TAny* aExpectedItem) const
|
sl@0
|
124 |
{ return (iOperation && iPtr==aExpectedItem); }
|
sl@0
|
125 |
|
sl@0
|
126 |
void TCleanupStackItem::Set(const TCleanupItem &anItem)
|
sl@0
|
127 |
//
|
sl@0
|
128 |
// Initialise an entry as a cleanup item.
|
sl@0
|
129 |
//
|
sl@0
|
130 |
{
|
sl@0
|
131 |
|
sl@0
|
132 |
__ASSERT_ALWAYS(anItem.iOperation!=NULL,Panic(EClnNoCleanupOperation));
|
sl@0
|
133 |
iOperation=anItem.iOperation;
|
sl@0
|
134 |
iPtr=anItem.iPtr;
|
sl@0
|
135 |
}
|
sl@0
|
136 |
|
sl@0
|
137 |
|
sl@0
|
138 |
|
sl@0
|
139 |
|
sl@0
|
140 |
EXPORT_C CCleanup *CCleanup::New()
|
sl@0
|
141 |
/**
|
sl@0
|
142 |
Creates a new cleanup stack object.
|
sl@0
|
143 |
|
sl@0
|
144 |
The cleanup stack itself is allocated with enough space initially to hold
|
sl@0
|
145 |
a number of stack items.
|
sl@0
|
146 |
|
sl@0
|
147 |
@return A pointer to the new cleanup stack object. This is Null if there is
|
sl@0
|
148 |
insufficient memory.
|
sl@0
|
149 |
*/
|
sl@0
|
150 |
{
|
sl@0
|
151 |
|
sl@0
|
152 |
CCleanup *pC=new CCleanup;
|
sl@0
|
153 |
if (pC!=NULL)
|
sl@0
|
154 |
{
|
sl@0
|
155 |
TCleanupStackItem *base=(TCleanupStackItem *)User::Alloc(KCleanupInitialSlots*sizeof(TCleanupStackItem));
|
sl@0
|
156 |
if (base!=NULL)
|
sl@0
|
157 |
{
|
sl@0
|
158 |
pC->iBase=base;
|
sl@0
|
159 |
pC->iNext=base;
|
sl@0
|
160 |
pC->iTop=base+KCleanupInitialSlots;
|
sl@0
|
161 |
}
|
sl@0
|
162 |
else
|
sl@0
|
163 |
{
|
sl@0
|
164 |
delete pC;
|
sl@0
|
165 |
pC=NULL;
|
sl@0
|
166 |
}
|
sl@0
|
167 |
}
|
sl@0
|
168 |
return(pC);
|
sl@0
|
169 |
}
|
sl@0
|
170 |
|
sl@0
|
171 |
|
sl@0
|
172 |
|
sl@0
|
173 |
|
sl@0
|
174 |
EXPORT_C CCleanup *CCleanup::NewL()
|
sl@0
|
175 |
/**
|
sl@0
|
176 |
Creates a new cleanup stack object, and leaves if there is insufficient memory
|
sl@0
|
177 |
to create it.
|
sl@0
|
178 |
|
sl@0
|
179 |
The cleanup stack itself is allocated with enough space initially to hold
|
sl@0
|
180 |
a number of stack items.
|
sl@0
|
181 |
|
sl@0
|
182 |
@return A pointer to the new cleanup stack object. This is Null if there is
|
sl@0
|
183 |
nsufficient memory.
|
sl@0
|
184 |
*/
|
sl@0
|
185 |
{
|
sl@0
|
186 |
|
sl@0
|
187 |
CCleanup *pC=New();
|
sl@0
|
188 |
User::LeaveIfNull(pC);
|
sl@0
|
189 |
return(pC);
|
sl@0
|
190 |
}
|
sl@0
|
191 |
|
sl@0
|
192 |
|
sl@0
|
193 |
|
sl@0
|
194 |
|
sl@0
|
195 |
EXPORT_C CCleanup::CCleanup()
|
sl@0
|
196 |
/**
|
sl@0
|
197 |
Default constructor.
|
sl@0
|
198 |
*/
|
sl@0
|
199 |
{
|
sl@0
|
200 |
|
sl@0
|
201 |
// iBase=NULL;
|
sl@0
|
202 |
// iTop=NULL;
|
sl@0
|
203 |
// iNext=NULL;
|
sl@0
|
204 |
}
|
sl@0
|
205 |
|
sl@0
|
206 |
|
sl@0
|
207 |
|
sl@0
|
208 |
|
sl@0
|
209 |
EXPORT_C CCleanup::~CCleanup()
|
sl@0
|
210 |
/**
|
sl@0
|
211 |
Destructor.
|
sl@0
|
212 |
|
sl@0
|
213 |
Pops and destroys all items from the cleanup stack and then destroys
|
sl@0
|
214 |
the cleanup stack itself.
|
sl@0
|
215 |
*/
|
sl@0
|
216 |
{
|
sl@0
|
217 |
|
sl@0
|
218 |
while (iNext>iBase)
|
sl@0
|
219 |
PopAndDestroyAll();
|
sl@0
|
220 |
User::Free(iBase);
|
sl@0
|
221 |
}
|
sl@0
|
222 |
|
sl@0
|
223 |
|
sl@0
|
224 |
|
sl@0
|
225 |
|
sl@0
|
226 |
EXPORT_C void CCleanup::NextLevel()
|
sl@0
|
227 |
/**
|
sl@0
|
228 |
Goes to the next cleanup level.
|
sl@0
|
229 |
*/
|
sl@0
|
230 |
{
|
sl@0
|
231 |
|
sl@0
|
232 |
if (iNext>iBase && (iNext-1)->IsLevelMarker())
|
sl@0
|
233 |
(iNext-1)->PushLevel();
|
sl@0
|
234 |
else
|
sl@0
|
235 |
{
|
sl@0
|
236 |
iNext->MarkLevel();
|
sl@0
|
237 |
++iNext;
|
sl@0
|
238 |
}
|
sl@0
|
239 |
}
|
sl@0
|
240 |
|
sl@0
|
241 |
|
sl@0
|
242 |
|
sl@0
|
243 |
|
sl@0
|
244 |
EXPORT_C void CCleanup::PreviousLevel()
|
sl@0
|
245 |
/**
|
sl@0
|
246 |
Goes to the previous cleanup level.
|
sl@0
|
247 |
|
sl@0
|
248 |
@panic E32USER-CBase 71 If the previous stack item does not represent a cleanup
|
sl@0
|
249 |
level.
|
sl@0
|
250 |
*/
|
sl@0
|
251 |
{
|
sl@0
|
252 |
|
sl@0
|
253 |
TCleanupStackItem *item=iNext;
|
sl@0
|
254 |
--item;
|
sl@0
|
255 |
// current level must be empty
|
sl@0
|
256 |
__ASSERT_ALWAYS(item->IsLevelMarker(), Panic(EClnLevelNotEmpty));
|
sl@0
|
257 |
if (item->PopLevel())
|
sl@0
|
258 |
++item;
|
sl@0
|
259 |
iNext=item;
|
sl@0
|
260 |
}
|
sl@0
|
261 |
|
sl@0
|
262 |
|
sl@0
|
263 |
|
sl@0
|
264 |
|
sl@0
|
265 |
EXPORT_C void CCleanup::PushL(TAny *aPtr)
|
sl@0
|
266 |
/**
|
sl@0
|
267 |
Pushes a cleanup item onto the cleanup stack.
|
sl@0
|
268 |
|
sl@0
|
269 |
The cleanup item represents an operation that frees the specified heap cell.
|
sl@0
|
270 |
|
sl@0
|
271 |
@param aPtr A pointer to a heap cell that will be freed by
|
sl@0
|
272 |
the cleanup operation.
|
sl@0
|
273 |
*/
|
sl@0
|
274 |
{
|
sl@0
|
275 |
|
sl@0
|
276 |
PushL(TCleanupItem(User::Free,aPtr));
|
sl@0
|
277 |
}
|
sl@0
|
278 |
|
sl@0
|
279 |
|
sl@0
|
280 |
|
sl@0
|
281 |
|
sl@0
|
282 |
EXPORT_C void CCleanup::PushL(CBase *anObject)
|
sl@0
|
283 |
/**
|
sl@0
|
284 |
Pushes a cleanup item onto the cleanup stack.
|
sl@0
|
285 |
|
sl@0
|
286 |
The cleanup item represents an operation that deletes the specified CBase
|
sl@0
|
287 |
derived object.
|
sl@0
|
288 |
|
sl@0
|
289 |
@param anObject A pointer to CBase derived object that will be deleted by
|
sl@0
|
290 |
the cleanup operation.
|
sl@0
|
291 |
*/
|
sl@0
|
292 |
{
|
sl@0
|
293 |
|
sl@0
|
294 |
PushL(TCleanupItem(TCleanupOperation(doDelete),anObject));
|
sl@0
|
295 |
}
|
sl@0
|
296 |
|
sl@0
|
297 |
|
sl@0
|
298 |
|
sl@0
|
299 |
|
sl@0
|
300 |
EXPORT_C void CCleanup::PushL(TCleanupItem anItem)
|
sl@0
|
301 |
/**
|
sl@0
|
302 |
Pushes a cleanup item onto the cleanup stack.
|
sl@0
|
303 |
|
sl@0
|
304 |
The cleanup item represents a call back operation that performs the required
|
sl@0
|
305 |
cleanup.
|
sl@0
|
306 |
|
sl@0
|
307 |
@param anItem Encapsulates a cleanup operation and an object on which the
|
sl@0
|
308 |
cleanup operation is to be performed.
|
sl@0
|
309 |
|
sl@0
|
310 |
@see CleanupClosePushL
|
sl@0
|
311 |
@see CleanupReleasePushL
|
sl@0
|
312 |
@see CleanupDeletePushL
|
sl@0
|
313 |
*/
|
sl@0
|
314 |
{
|
sl@0
|
315 |
|
sl@0
|
316 |
TCleanupStackItem *item=iNext;
|
sl@0
|
317 |
__ASSERT_ALWAYS(item>iBase,Panic(EClnPushAtLevelZero));
|
sl@0
|
318 |
__ASSERT_ALWAYS(item<iTop,Panic(EClnNoFreeSlotItem));
|
sl@0
|
319 |
item->Set(anItem);
|
sl@0
|
320 |
iNext=++item;
|
sl@0
|
321 |
//
|
sl@0
|
322 |
// We always try and make sure that there are two free slots in the cleanup array.
|
sl@0
|
323 |
// one for a level marker and one for an item to follow it
|
sl@0
|
324 |
// If this fails its o.k. as we have already added the entry to the list, so
|
sl@0
|
325 |
// it will be cleaned up o.k.
|
sl@0
|
326 |
//
|
sl@0
|
327 |
if (item+1>=iTop)
|
sl@0
|
328 |
{
|
sl@0
|
329 |
TInt size=(TUint8 *)(iTop+KCleanupGranularity)-(TUint8 *)iBase;
|
sl@0
|
330 |
TCleanupStackItem *base=(TCleanupStackItem *)User::ReAllocL(iBase,size);
|
sl@0
|
331 |
iNext=PtrAdd(base,(TUint8 *)item-(TUint8 *)iBase);
|
sl@0
|
332 |
iBase=base;
|
sl@0
|
333 |
iTop=PtrAdd(base,size);
|
sl@0
|
334 |
}
|
sl@0
|
335 |
}
|
sl@0
|
336 |
|
sl@0
|
337 |
|
sl@0
|
338 |
|
sl@0
|
339 |
|
sl@0
|
340 |
EXPORT_C void CCleanup::DoPop(TInt aCount,TBool aDestroy)
|
sl@0
|
341 |
/**
|
sl@0
|
342 |
Provides an implementation for Pop() and PopAndDestroy().
|
sl@0
|
343 |
|
sl@0
|
344 |
@param aCount The number of cleanup items to be popped from
|
sl@0
|
345 |
the cleanup stack.
|
sl@0
|
346 |
@param aDestroy ETrue, if cleanup is to be performed; EFalse, otherwise.
|
sl@0
|
347 |
*/
|
sl@0
|
348 |
{
|
sl@0
|
349 |
|
sl@0
|
350 |
__ASSERT_ALWAYS(aCount>=0,Panic(EClnPopCountNegative));
|
sl@0
|
351 |
__ASSERT_ALWAYS((iNext-aCount)>=iBase,Panic(EClnPopUnderflow));
|
sl@0
|
352 |
while (aCount--)
|
sl@0
|
353 |
{
|
sl@0
|
354 |
--iNext;
|
sl@0
|
355 |
__ASSERT_ALWAYS(!iNext->IsLevelMarker(),Panic(EClnPopAcrossLevels));
|
sl@0
|
356 |
if (aDestroy)
|
sl@0
|
357 |
{
|
sl@0
|
358 |
TInt offset = iNext - iBase;
|
sl@0
|
359 |
iNext->Cleanup();
|
sl@0
|
360 |
// Check that there are no extra items on the cleanup stack
|
sl@0
|
361 |
// (if there are, we will not be deleting the right aCount items)
|
sl@0
|
362 |
__ASSERT_ALWAYS((iNext - iBase) == offset,Panic(EClnStackModified));
|
sl@0
|
363 |
}
|
sl@0
|
364 |
}
|
sl@0
|
365 |
}
|
sl@0
|
366 |
|
sl@0
|
367 |
|
sl@0
|
368 |
|
sl@0
|
369 |
|
sl@0
|
370 |
EXPORT_C void CCleanup::DoPopAll(TBool aDestroy)
|
sl@0
|
371 |
/**
|
sl@0
|
372 |
Provides an implementation for PopAll() and PopAndDestroyAll().
|
sl@0
|
373 |
|
sl@0
|
374 |
@param aDestroy ETrue, if cleanup is to be performed; EFalse, otherwise.
|
sl@0
|
375 |
*/
|
sl@0
|
376 |
{
|
sl@0
|
377 |
|
sl@0
|
378 |
__ASSERT_ALWAYS(iNext>iBase,Panic(EClnLevelUnderflow));
|
sl@0
|
379 |
while (!(--iNext)->IsLevelMarker())
|
sl@0
|
380 |
{
|
sl@0
|
381 |
if (aDestroy)
|
sl@0
|
382 |
iNext->Cleanup();
|
sl@0
|
383 |
}
|
sl@0
|
384 |
if (iNext->PopLevel())
|
sl@0
|
385 |
++iNext; // still marks a level
|
sl@0
|
386 |
}
|
sl@0
|
387 |
|
sl@0
|
388 |
|
sl@0
|
389 |
|
sl@0
|
390 |
|
sl@0
|
391 |
EXPORT_C void CCleanup::Pop()
|
sl@0
|
392 |
/**
|
sl@0
|
393 |
Pops a single cleanup item from the cleanup stack.
|
sl@0
|
394 |
|
sl@0
|
395 |
@panic E32USER-CBase 64 If there are no items on the cleanup stack.
|
sl@0
|
396 |
@panic E32USER-CBase 63 If a cleanup level is crossed.
|
sl@0
|
397 |
*/
|
sl@0
|
398 |
{
|
sl@0
|
399 |
|
sl@0
|
400 |
DoPop(1,EFalse);
|
sl@0
|
401 |
}
|
sl@0
|
402 |
|
sl@0
|
403 |
|
sl@0
|
404 |
|
sl@0
|
405 |
|
sl@0
|
406 |
EXPORT_C void CCleanup::Pop(TInt aCount)
|
sl@0
|
407 |
/**
|
sl@0
|
408 |
Pops the specified number of cleanup items from the cleanup stack.
|
sl@0
|
409 |
|
sl@0
|
410 |
@param aCount The number of cleanup items to be popped from the cleanup stack.
|
sl@0
|
411 |
|
sl@0
|
412 |
@panic E32USER-CBase 70 If the specified number of cleanup items is negative.
|
sl@0
|
413 |
@panic E32USER-CBase 64 If the specifed number of items is greater than the
|
sl@0
|
414 |
number of items on the cleanup stack.
|
sl@0
|
415 |
@panic E32USER-CBase 63 If the specified number of items is such that it causes
|
sl@0
|
416 |
a cleanup level to be crossed.
|
sl@0
|
417 |
*/
|
sl@0
|
418 |
{
|
sl@0
|
419 |
|
sl@0
|
420 |
DoPop(aCount,EFalse);
|
sl@0
|
421 |
}
|
sl@0
|
422 |
|
sl@0
|
423 |
|
sl@0
|
424 |
|
sl@0
|
425 |
|
sl@0
|
426 |
EXPORT_C void CCleanup::PopAll()
|
sl@0
|
427 |
/**
|
sl@0
|
428 |
Pops all cleanup items at the current level, and then decrements the level.
|
sl@0
|
429 |
*/
|
sl@0
|
430 |
{
|
sl@0
|
431 |
|
sl@0
|
432 |
DoPopAll(EFalse);
|
sl@0
|
433 |
}
|
sl@0
|
434 |
|
sl@0
|
435 |
|
sl@0
|
436 |
|
sl@0
|
437 |
|
sl@0
|
438 |
EXPORT_C void CCleanup::PopAndDestroy()
|
sl@0
|
439 |
/**
|
sl@0
|
440 |
Pops a single cleanup item from the cleanup stack, and invokes its cleanup
|
sl@0
|
441 |
operation.
|
sl@0
|
442 |
|
sl@0
|
443 |
@panic E32USER-CBase 64 If there are no items on the cleanup stack.
|
sl@0
|
444 |
@panic E32USER-CBase 63 If a cleanup level is crossed.
|
sl@0
|
445 |
*/
|
sl@0
|
446 |
{
|
sl@0
|
447 |
|
sl@0
|
448 |
DoPop(1,ETrue);
|
sl@0
|
449 |
}
|
sl@0
|
450 |
|
sl@0
|
451 |
|
sl@0
|
452 |
|
sl@0
|
453 |
|
sl@0
|
454 |
EXPORT_C void CCleanup::PopAndDestroy(TInt aCount)
|
sl@0
|
455 |
/**
|
sl@0
|
456 |
Pops the specified number of cleanup items from the cleanup stack, and invokes
|
sl@0
|
457 |
their cleanup operations.
|
sl@0
|
458 |
|
sl@0
|
459 |
@param aCount The number of cleanup items to be popped from the cleanup stack.
|
sl@0
|
460 |
|
sl@0
|
461 |
@panic E32USER-CBase 70 If the specified number of cleanup items is negative.
|
sl@0
|
462 |
@panic E32USER-CBase 64 If the specifed number of items is greater than the
|
sl@0
|
463 |
number of items on the cleanup stack.
|
sl@0
|
464 |
@panic E32USER-CBase 63 If the specified number of items is such that it causes
|
sl@0
|
465 |
a cleanup level to be crossed.
|
sl@0
|
466 |
*/
|
sl@0
|
467 |
{
|
sl@0
|
468 |
|
sl@0
|
469 |
DoPop(aCount,ETrue);
|
sl@0
|
470 |
}
|
sl@0
|
471 |
|
sl@0
|
472 |
|
sl@0
|
473 |
|
sl@0
|
474 |
|
sl@0
|
475 |
EXPORT_C void CCleanup::PopAndDestroyAll()
|
sl@0
|
476 |
/**
|
sl@0
|
477 |
Pops all cleanup items at the current level, invokes their cleanup operations
|
sl@0
|
478 |
and then decrements the level.
|
sl@0
|
479 |
*/
|
sl@0
|
480 |
{
|
sl@0
|
481 |
|
sl@0
|
482 |
DoPopAll(ETrue);
|
sl@0
|
483 |
}
|
sl@0
|
484 |
|
sl@0
|
485 |
|
sl@0
|
486 |
|
sl@0
|
487 |
|
sl@0
|
488 |
EXPORT_C void CCleanup::Check(TAny* aExpectedItem)
|
sl@0
|
489 |
/**
|
sl@0
|
490 |
Checks that the cleanup item at the top of the cleanup stack
|
sl@0
|
491 |
represents a cleanup operation for the specified object.
|
sl@0
|
492 |
|
sl@0
|
493 |
@param aExpectedItem The object which is the subject of the test.
|
sl@0
|
494 |
*/
|
sl@0
|
495 |
{
|
sl@0
|
496 |
|
sl@0
|
497 |
TCleanupStackItem* last=iNext-1;
|
sl@0
|
498 |
__ASSERT_ALWAYS(last>=iBase && last->Check(aExpectedItem), Panic(EClnCheckFailed));
|
sl@0
|
499 |
}
|
sl@0
|
500 |
|
sl@0
|
501 |
|
sl@0
|
502 |
|
sl@0
|
503 |
|
sl@0
|
504 |
EXPORT_C CTrapCleanup *CTrapCleanup::New()
|
sl@0
|
505 |
/**
|
sl@0
|
506 |
Allocates and constructs a cleanup stack.
|
sl@0
|
507 |
|
sl@0
|
508 |
If successfully constructed, this cleanup stack becomes
|
sl@0
|
509 |
the current cleanup stack.
|
sl@0
|
510 |
|
sl@0
|
511 |
@return A pointer to the new cleanup stack. This pointer is NULL, if allocation
|
sl@0
|
512 |
fails.
|
sl@0
|
513 |
*/
|
sl@0
|
514 |
{
|
sl@0
|
515 |
|
sl@0
|
516 |
CTrapCleanup *pT=new CTrapCleanup;
|
sl@0
|
517 |
if (pT!=NULL)
|
sl@0
|
518 |
{
|
sl@0
|
519 |
CCleanup *pC=CCleanup::New();
|
sl@0
|
520 |
if (pC!=NULL)
|
sl@0
|
521 |
{
|
sl@0
|
522 |
pT->iHandler.iCleanup=pC;
|
sl@0
|
523 |
pT->iOldHandler=User::SetTrapHandler(&pT->iHandler);
|
sl@0
|
524 |
}
|
sl@0
|
525 |
else
|
sl@0
|
526 |
{
|
sl@0
|
527 |
delete pT;
|
sl@0
|
528 |
pT=NULL;
|
sl@0
|
529 |
}
|
sl@0
|
530 |
}
|
sl@0
|
531 |
return(pT);
|
sl@0
|
532 |
}
|
sl@0
|
533 |
|
sl@0
|
534 |
|
sl@0
|
535 |
|
sl@0
|
536 |
|
sl@0
|
537 |
EXPORT_C CTrapCleanup::CTrapCleanup()
|
sl@0
|
538 |
/**
|
sl@0
|
539 |
Default constructor.
|
sl@0
|
540 |
*/
|
sl@0
|
541 |
// : iHandler()
|
sl@0
|
542 |
{
|
sl@0
|
543 |
}
|
sl@0
|
544 |
|
sl@0
|
545 |
|
sl@0
|
546 |
|
sl@0
|
547 |
|
sl@0
|
548 |
EXPORT_C CTrapCleanup::~CTrapCleanup()
|
sl@0
|
549 |
/**
|
sl@0
|
550 |
Destructor.
|
sl@0
|
551 |
|
sl@0
|
552 |
Frees resources owned by the object, prior to its destruction. This cleanup
|
sl@0
|
553 |
stack ceases to be the current cleanup stack.
|
sl@0
|
554 |
|
sl@0
|
555 |
If there is a stack of cleanup stacks, then the next cleanup stack becomes
|
sl@0
|
556 |
the current cleanup stack.
|
sl@0
|
557 |
*/
|
sl@0
|
558 |
{
|
sl@0
|
559 |
|
sl@0
|
560 |
if (iHandler.iCleanup!=NULL)
|
sl@0
|
561 |
{
|
sl@0
|
562 |
User::SetTrapHandler(iOldHandler);
|
sl@0
|
563 |
delete iHandler.iCleanup;
|
sl@0
|
564 |
}
|
sl@0
|
565 |
}
|
sl@0
|
566 |
|
sl@0
|
567 |
|
sl@0
|
568 |
|
sl@0
|
569 |
|
sl@0
|
570 |
EXPORT_C void CleanupStack::PushL(TAny *aPtr)
|
sl@0
|
571 |
/**
|
sl@0
|
572 |
Pushes a pointer to an object onto the cleanup stack.
|
sl@0
|
573 |
|
sl@0
|
574 |
If a leave occurs while an object is on the stack, it is cleaned
|
sl@0
|
575 |
up automatically. Untyped objects are cleaned up with User::Free()
|
sl@0
|
576 |
(a rather limited form of cleanup, not even the C++ destructor is called).
|
sl@0
|
577 |
|
sl@0
|
578 |
Typically, when an object has been fully constructed and it can be guaranteed
|
sl@0
|
579 |
that a pointer to this new object is stored in some other object before a leave
|
sl@0
|
580 |
occurs, issue CleanupStack::Pop() to pop it back off the stack.
|
sl@0
|
581 |
|
sl@0
|
582 |
If no cleanup stack has been allocated, a panic occurs.
|
sl@0
|
583 |
|
sl@0
|
584 |
It is guaranteed that the object is pushed onto the cleanup stack. However,
|
sl@0
|
585 |
this function may leave if a stack frame for the next PushL() cannot be
|
sl@0
|
586 |
allocated. In this case, the cleanup stack will be cleaned up as normal, and
|
sl@0
|
587 |
no extra programmer intervention is needed.
|
sl@0
|
588 |
|
sl@0
|
589 |
@param aPtr Pointer to any object. If cleanup is necessary, the object will be
|
sl@0
|
590 |
freed by User::Free(), which does not invoke any destructor: it
|
sl@0
|
591 |
simply frees its memory
|
sl@0
|
592 |
|
sl@0
|
593 |
@panic E32USER-CBase 66 if a call to this function is made when no prior
|
sl@0
|
594 |
call to TRAP has been made.
|
sl@0
|
595 |
*/
|
sl@0
|
596 |
{
|
sl@0
|
597 |
|
sl@0
|
598 |
cleanup().PushL(aPtr);
|
sl@0
|
599 |
}
|
sl@0
|
600 |
|
sl@0
|
601 |
|
sl@0
|
602 |
|
sl@0
|
603 |
|
sl@0
|
604 |
EXPORT_C void CleanupStack::PushL(CBase *aPtr)
|
sl@0
|
605 |
/**
|
sl@0
|
606 |
Pushes a pointer to an object onto the cleanup stack.
|
sl@0
|
607 |
|
sl@0
|
608 |
If a leave occurs while an object is on the stack, it is cleaned
|
sl@0
|
609 |
up automatically. CBase derived objects are cleaned up with delete.
|
sl@0
|
610 |
|
sl@0
|
611 |
Typically, when an object has been fully constructed and it can be guaranteed
|
sl@0
|
612 |
that a pointer to this new object is stored in some other object before a leave
|
sl@0
|
613 |
occurs, issue CleanupStack::Pop() to pop it back off the stack.
|
sl@0
|
614 |
|
sl@0
|
615 |
If no cleanup stack has been allocated, a panic occurs.
|
sl@0
|
616 |
|
sl@0
|
617 |
It is guaranteed that the object is pushed onto the cleanup stack. However,
|
sl@0
|
618 |
this function may leave if a stack frame for the next PushL() cannot be
|
sl@0
|
619 |
allocated. In this case, the cleanup stack will be cleaned up as normal,
|
sl@0
|
620 |
and no extra programmer intervention is needed.
|
sl@0
|
621 |
|
sl@0
|
622 |
@param aPtr Pointer to a CBase-derived object. If cleanup is necessary, the
|
sl@0
|
623 |
object will be freed by delete, thus invoking its destructor,
|
sl@0
|
624 |
and freeing its memory.
|
sl@0
|
625 |
|
sl@0
|
626 |
@panic E32USER-CBase 66 if a call to this function is made when no prior
|
sl@0
|
627 |
call to TRAP has been made.
|
sl@0
|
628 |
*/
|
sl@0
|
629 |
{
|
sl@0
|
630 |
|
sl@0
|
631 |
cleanup().PushL(aPtr);
|
sl@0
|
632 |
}
|
sl@0
|
633 |
|
sl@0
|
634 |
|
sl@0
|
635 |
|
sl@0
|
636 |
|
sl@0
|
637 |
EXPORT_C void CleanupStack::PushL(TCleanupItem anItem)
|
sl@0
|
638 |
/**
|
sl@0
|
639 |
Pushes a cleanup item onto the cleanup stack.
|
sl@0
|
640 |
|
sl@0
|
641 |
If a leave occurs while a cleanup item is on the stack, the cleanup operation
|
sl@0
|
642 |
defined in the construction of the TCleanupItem, is invoked.
|
sl@0
|
643 |
|
sl@0
|
644 |
Typically, when an object has been fully constructed and it can be guaranteed
|
sl@0
|
645 |
that a pointer to this new object is stored in some other object before a leave
|
sl@0
|
646 |
occurs, issue CleanupStack::Pop() to pop it back off the stack.
|
sl@0
|
647 |
|
sl@0
|
648 |
If no cleanup stack has been allocated, a panic occurs.
|
sl@0
|
649 |
|
sl@0
|
650 |
It is guaranteed that the object is pushed onto the cleanup stack. However,
|
sl@0
|
651 |
this function may leave if a stack frame for the next PushL() cannot be
|
sl@0
|
652 |
allocated. In this case, the cleanup stack will be cleaned up as normal,
|
sl@0
|
653 |
and no extra programmer intervention is needed.
|
sl@0
|
654 |
|
sl@0
|
655 |
@param anItem A cleanup item. If cleanup is necessary, the cleanup operation
|
sl@0
|
656 |
defined in the construction of anItem is called.
|
sl@0
|
657 |
|
sl@0
|
658 |
@panic E32USER-CBase 66 if a call to this function is made when no prior
|
sl@0
|
659 |
call to TRAP has been made.
|
sl@0
|
660 |
*/
|
sl@0
|
661 |
{
|
sl@0
|
662 |
|
sl@0
|
663 |
cleanup().PushL(anItem);
|
sl@0
|
664 |
}
|
sl@0
|
665 |
|
sl@0
|
666 |
|
sl@0
|
667 |
|
sl@0
|
668 |
|
sl@0
|
669 |
EXPORT_C void CleanupStack::Pop()
|
sl@0
|
670 |
/**
|
sl@0
|
671 |
Pops an object previously pushed onto the cleanup stack
|
sl@0
|
672 |
by CleanupStack::PushL().
|
sl@0
|
673 |
|
sl@0
|
674 |
After an object has been successfully constructed and stored within
|
sl@0
|
675 |
another object, it cannot be orphaned and, therefore, the object
|
sl@0
|
676 |
(i.e. a pointer or a cleanup item) can be popped from the cleanup stack.
|
sl@0
|
677 |
|
sl@0
|
678 |
If no cleanup stack has been allocated, or there is nothing on the stack,
|
sl@0
|
679 |
a panic is raised.
|
sl@0
|
680 |
*/
|
sl@0
|
681 |
{
|
sl@0
|
682 |
|
sl@0
|
683 |
cleanup().Pop();
|
sl@0
|
684 |
}
|
sl@0
|
685 |
|
sl@0
|
686 |
|
sl@0
|
687 |
|
sl@0
|
688 |
|
sl@0
|
689 |
EXPORT_C void CleanupStack::Pop(TInt aCount)
|
sl@0
|
690 |
/**
|
sl@0
|
691 |
Pops a specified number of objects previously pushed onto the
|
sl@0
|
692 |
cleanup stack by CleanupStack::PushL().
|
sl@0
|
693 |
|
sl@0
|
694 |
After an object has been successfully constructed and stored within another
|
sl@0
|
695 |
object, it cannot be orphaned and, therefore, the object(s), that is, pointers
|
sl@0
|
696 |
and cleanup items can be popped from the cleanup stack.
|
sl@0
|
697 |
|
sl@0
|
698 |
If no cleanup stack has been allocated, or there is nothing on the stack,
|
sl@0
|
699 |
a panic is raised.
|
sl@0
|
700 |
|
sl@0
|
701 |
@param aCount The number of objects to be popped off the cleanup stack.
|
sl@0
|
702 |
*/
|
sl@0
|
703 |
{
|
sl@0
|
704 |
|
sl@0
|
705 |
cleanup().Pop(aCount);
|
sl@0
|
706 |
}
|
sl@0
|
707 |
|
sl@0
|
708 |
|
sl@0
|
709 |
|
sl@0
|
710 |
|
sl@0
|
711 |
EXPORT_C void CleanupStack::PopAndDestroy()
|
sl@0
|
712 |
/**
|
sl@0
|
713 |
Pops and cleans up an item pushed onto the stack.
|
sl@0
|
714 |
|
sl@0
|
715 |
If the item on the stack is a CBase* pointer, the pointer is removed from
|
sl@0
|
716 |
the stack and the object is destroyed with delete.
|
sl@0
|
717 |
|
sl@0
|
718 |
If the item on the stack is a TAny* pointer, the pointer is removed from
|
sl@0
|
719 |
the stack and the memory occupied by the object is freed with User::Free().
|
sl@0
|
720 |
|
sl@0
|
721 |
If the item on the stack is a cleanup item, i.e. an object of
|
sl@0
|
722 |
type TCleanupItem, the item is removed from the stack and the cleanup
|
sl@0
|
723 |
operation defined during construction of the TCleanupItem object is invoked.
|
sl@0
|
724 |
|
sl@0
|
725 |
If no cleanup stack has been allocated, or there is nothing on the stack,
|
sl@0
|
726 |
a panic occurs.
|
sl@0
|
727 |
*/
|
sl@0
|
728 |
{
|
sl@0
|
729 |
|
sl@0
|
730 |
cleanup().PopAndDestroy();
|
sl@0
|
731 |
}
|
sl@0
|
732 |
|
sl@0
|
733 |
|
sl@0
|
734 |
|
sl@0
|
735 |
|
sl@0
|
736 |
EXPORT_C void CleanupStack::PopAndDestroy(TInt aCount)
|
sl@0
|
737 |
/**
|
sl@0
|
738 |
Pops and cleans up the specified number of items pushed onto the stack.
|
sl@0
|
739 |
|
sl@0
|
740 |
If an item on the stack is a CBase* pointer, the pointer is removed from
|
sl@0
|
741 |
the stack and the object is destroyed with delete.
|
sl@0
|
742 |
|
sl@0
|
743 |
If an item on the stack is a TAny* pointer, the pointer is removed from the
|
sl@0
|
744 |
stack and the memory occupied by the object is freed with User::Free().
|
sl@0
|
745 |
|
sl@0
|
746 |
If an item on the stack is a cleanup item, i.e. an object of type TCleanupItem,
|
sl@0
|
747 |
the item is removed from the stack and the cleanup operation defined during
|
sl@0
|
748 |
construction of the TCleanupItem object is invoked.
|
sl@0
|
749 |
|
sl@0
|
750 |
If no cleanup stack has been allocated, or there is nothing on the stack,
|
sl@0
|
751 |
a panic occurs.
|
sl@0
|
752 |
|
sl@0
|
753 |
@param aCount The number of objects to be popped off the cleanup stack and
|
sl@0
|
754 |
destroyed.
|
sl@0
|
755 |
*/
|
sl@0
|
756 |
{
|
sl@0
|
757 |
|
sl@0
|
758 |
cleanup().PopAndDestroy(aCount);
|
sl@0
|
759 |
}
|
sl@0
|
760 |
|
sl@0
|
761 |
|
sl@0
|
762 |
|
sl@0
|
763 |
|
sl@0
|
764 |
EXPORT_C void CleanupStack::Check(TAny* aExpectedItem)
|
sl@0
|
765 |
/**
|
sl@0
|
766 |
Checks that the specified object is at the top of the cleanup stack.
|
sl@0
|
767 |
|
sl@0
|
768 |
If the specified item is not at the top of the cleanup stack, then the function
|
sl@0
|
769 |
raises an E32USER-CBase 90 panic.
|
sl@0
|
770 |
|
sl@0
|
771 |
The function is part of Symbian OS in both debug and release builds, and is
|
sl@0
|
772 |
an aid to debugging.
|
sl@0
|
773 |
|
sl@0
|
774 |
@param aExpectedItem A pointer to the item expected to be at the top of the
|
sl@0
|
775 |
cleanup stack.
|
sl@0
|
776 |
*/
|
sl@0
|
777 |
{
|
sl@0
|
778 |
|
sl@0
|
779 |
cleanup().Check(aExpectedItem);
|
sl@0
|
780 |
}
|