equal
deleted
inserted
replaced
37 // closed when it goes out of scope, push it on the cleanup stack, |
37 // closed when it goes out of scope, push it on the cleanup stack, |
38 // verify cleanup results are as expected. |
38 // verify cleanup results are as expected. |
39 // - Test that the Cleanup stack can go re-entrant. |
39 // - Test that the Cleanup stack can go re-entrant. |
40 // - Ensure that the stack is properly balanced with and without |
40 // - Ensure that the stack is properly balanced with and without |
41 // leaving. |
41 // leaving. |
42 // - Test creating cleanup with CCleanup::NewL in normal |
|
43 // memory conditions and condition where heap is full (panic) |
|
44 // Platforms/Drives/Compatibility: |
42 // Platforms/Drives/Compatibility: |
45 // All. |
43 // All. |
46 // Assumptions/Requirement/Pre-requisites: |
44 // Assumptions/Requirement/Pre-requisites: |
47 // Failures and causes: |
45 // Failures and causes: |
48 // Base Port information: |
46 // Base Port information: |
55 #include <e32panic.h> |
53 #include <e32panic.h> |
56 #include <e32debug.h> |
54 #include <e32debug.h> |
57 #include <e32def.h> |
55 #include <e32def.h> |
58 #include <e32def_private.h> |
56 #include <e32def_private.h> |
59 |
57 |
60 #if defined(_DEBUG) |
58 |
61 const TInt KInitialCount=2; |
59 const TInt KInitialCount=2; |
62 const TInt KInitialCountAll=3; |
60 const TInt KInitialCountAll=3; |
63 #endif |
|
64 |
|
65 const TInt KLeaveValue=0x12345678; |
61 const TInt KLeaveValue=0x12345678; |
66 const TInt KMaxAlloc=6; |
62 const TInt KMaxAlloc=6; |
67 const TInt KTableSize = 1000; |
|
68 |
63 |
69 static const TInt KHeapSize = 0x2000; |
64 static const TInt KHeapSize = 0x2000; |
70 |
|
71 |
65 |
72 enum TWhat {EPop,EPopAndDestroy,EMulti,ENull}; |
66 enum TWhat {EPop,EPopAndDestroy,EMulti,ENull}; |
73 |
67 |
74 class CTest : public CBase |
68 class CTest : public CBase |
75 { |
69 { |
110 LOCAL_D CBufFlat* gP2; |
104 LOCAL_D CBufFlat* gP2; |
111 |
105 |
112 |
106 |
113 LOCAL_C void ReallocateStackL() |
107 LOCAL_C void ReallocateStackL() |
114 { |
108 { |
|
109 TInt n = 0; |
115 for(TInt i = 0; i < KMaxAlloc; ++i) |
110 for(TInt i = 0; i < KMaxAlloc; ++i) |
116 { |
111 { |
117 (void)HBufC::NewLC(4); //Stack re-allocation will be performed due to the additional objects pushed |
112 HBufC *p1 = HBufC::NewLC(4); //Stack re-allocation will be performed due to the additional objects pushed |
118 //into the cleanup stack |
113 //into the cleanup stack |
|
114 n = p1->Length(); //include this line to avoid warnigs for unused "p1" variable |
119 } |
115 } |
120 test.Printf(_L("ReallocateStackL(): PopAndDestroy KMaxAlloc pointers\n")); |
116 test.Printf(_L("ReallocateStackL(): PopAndDestroy KMaxAlloc pointers\n")); |
121 CleanupStack::PopAndDestroy(KMaxAlloc); |
117 CleanupStack::PopAndDestroy(KMaxAlloc); |
122 } |
118 } |
123 |
119 |
132 |
128 |
133 CTest3::~CTest3() |
129 CTest3::~CTest3() |
134 { |
130 { |
135 RDebug::Printf("~CTest3(): Modify Cleanup stack by pushing items"); |
131 RDebug::Printf("~CTest3(): Modify Cleanup stack by pushing items"); |
136 |
132 |
|
133 TInt n = 0; |
137 for(TInt i = 0; i < KMaxAlloc; ++i) |
134 for(TInt i = 0; i < KMaxAlloc; ++i) |
138 { |
135 { |
139 HBufC::NewLC(4); //Stack re-allocation will be performed due to the additional objects pushed |
136 HBufC *p1 = HBufC::NewLC(4); //Stack re-allocation will be performed due to the additional objects pushed |
140 //into the cleanup stack |
137 //into the cleanup stack |
|
138 n = p1->Length(); //include this line to avoid warnigs for unused "p1" variable |
141 } |
139 } |
142 } |
140 } |
143 |
141 |
144 LOCAL_C void ModifyStack() |
142 LOCAL_C void ModifyStack() |
145 { |
143 { |
148 |
146 |
149 RDebug::Printf("ModifyStack(): PopAndDestroy ptr6"); |
147 RDebug::Printf("ModifyStack(): PopAndDestroy ptr6"); |
150 CleanupStack::PopAndDestroy(); |
148 CleanupStack::PopAndDestroy(); |
151 } |
149 } |
152 |
150 |
153 LOCAL_C TInt PanicStackModifiedFn(TAny* /*aNopFn*/) |
151 LOCAL_C TInt PanicStackModifiedFn(TAny* aNopFn) |
154 { |
152 { |
155 __UHEAP_MARK; |
153 __UHEAP_MARK; |
156 CTrapCleanup* cleanup = CTrapCleanup::New(); |
154 CTrapCleanup* cleanup = CTrapCleanup::New(); |
|
155 |
|
156 aNopFn = NULL; //avoid warnings for unused "aNopFn" variable |
157 |
157 |
158 TInt err = KErrNoMemory; |
158 TInt err = KErrNoMemory; |
159 |
159 |
160 RDebug::Printf("PanicStackModifiedFn(): call TRAP(err, ModifyStack())"); |
160 RDebug::Printf("PanicStackModifiedFn(): call TRAP(err, ModifyStack())"); |
161 |
161 |
1089 // since room is always made for a free slot. We set the allocator |
1089 // since room is always made for a free slot. We set the allocator |
1090 // to fail so that we can test that the free slot is re-established |
1090 // to fail so that we can test that the free slot is re-established |
1091 // when we do the cleanup. This test only works in debug mode. |
1091 // when we do the cleanup. This test only works in debug mode. |
1092 // |
1092 // |
1093 __UHEAP_FAILNEXT(1); |
1093 __UHEAP_FAILNEXT(1); |
|
1094 TRAPD(r,pC->PushL(p6)); |
1094 #if defined(_DEBUG) |
1095 #if defined(_DEBUG) |
1095 TRAPD(r,pC->PushL(p6)); |
|
1096 test(r==KErrNoMemory); |
1096 test(r==KErrNoMemory); |
1097 #else |
|
1098 TRAP_IGNORE(pC->PushL(p6)); |
|
1099 #endif |
1097 #endif |
1100 __UHEAP_CHECK(KInitialCount+6); |
1098 __UHEAP_CHECK(KInitialCount+6); |
1101 pC->PopAndDestroyAll(); |
1099 pC->PopAndDestroyAll(); |
1102 __UHEAP_CHECK(KInitialCount); |
1100 __UHEAP_CHECK(KInitialCount); |
1103 // |
1101 // |
1300 LOCAL_C void reentrantCleanup(TAny*) |
1298 LOCAL_C void reentrantCleanup(TAny*) |
1301 // |
1299 // |
1302 // A cleanup operation which uses a trap harness and the cleanup stack |
1300 // A cleanup operation which uses a trap harness and the cleanup stack |
1303 // |
1301 // |
1304 { |
1302 { |
1305 TRAP_IGNORE(useCleanupStackL()); |
1303 TRAPD(ignore,useCleanupStackL()) |
1306 } |
1304 } |
1307 |
1305 |
1308 LOCAL_C void addReentrantItemL() |
1306 LOCAL_C void addReentrantItemL() |
1309 { |
1307 { |
1310 CleanupStack::PushL(TCleanupItem(reentrantCleanup)); |
1308 CleanupStack::PushL(TCleanupItem(reentrantCleanup)); |
1424 test.Next(_L("Let it fall out of scope")); |
1422 test.Next(_L("Let it fall out of scope")); |
1425 } |
1423 } |
1426 test.Next(_L("Check the object has closed")); |
1424 test.Next(_L("Check the object has closed")); |
1427 __KHEAP_CHECK(0); |
1425 __KHEAP_CHECK(0); |
1428 |
1426 |
1429 TRAP_IGNORE(testAutoCloseL()); |
1427 TRAPD(r, testAutoCloseL()); |
1430 test.Next(_L("Check object has been closed and cleaned up after leave")); |
1428 test.Next(_L("Check object has been closed and cleaned up after leave")); |
1431 __KHEAP_MARKEND; |
1429 __KHEAP_MARKEND; |
1432 test.End(); |
1430 test.End(); |
1433 } |
1431 } |
1434 |
1432 |
1537 User::Leave(KErrGeneral); |
1535 User::Leave(KErrGeneral); |
1538 ); |
1536 ); |
1539 test(count==1); |
1537 test(count==1); |
1540 |
1538 |
1541 delete pC; |
1539 delete pC; |
1542 test.End(); |
|
1543 } |
|
1544 |
|
1545 void testCCleanupNewL() |
|
1546 { |
|
1547 // don't want just in time debugging as we trap panics |
|
1548 TBool justInTime=User::JustInTime(); |
|
1549 User::SetJustInTime(EFalse); |
|
1550 |
|
1551 // no need to test otherwise, since this calls only |
|
1552 // CCleanup::New and that has been tested. |
|
1553 test.Start(_L("Create cleanup NewL")); |
|
1554 CCleanup* pC=CCleanup::NewL(); |
|
1555 test(pC!=NULL); |
|
1556 delete pC; |
|
1557 |
|
1558 TAny* ptrTable[KTableSize]; |
|
1559 TInt allocSize=sizeof(CCleanup); |
|
1560 TAny* ptr=0; |
|
1561 |
|
1562 __UHEAP_MARK; |
|
1563 |
|
1564 TInt i=0; |
|
1565 // first alloc 4Kb bits |
|
1566 do |
|
1567 { |
|
1568 ptr=User::Alloc(0x1000); |
|
1569 if(ptr!=NULL) |
|
1570 { |
|
1571 ptrTable[i]=ptr; |
|
1572 i++; |
|
1573 } |
|
1574 } |
|
1575 while (ptr!=NULL && i<KTableSize); |
|
1576 |
|
1577 // then eat memory with size of CCleanup object granurality |
|
1578 do |
|
1579 { |
|
1580 ptr=User::Alloc(allocSize); |
|
1581 if(ptr!=NULL) |
|
1582 { |
|
1583 ptrTable[i]=ptr; |
|
1584 i++; |
|
1585 } |
|
1586 } |
|
1587 while (ptr!=NULL && i<KTableSize); |
|
1588 |
|
1589 i--; // last one failed, so lets adjust this to last successfull entry |
|
1590 |
|
1591 TInt r=KErrNone; |
|
1592 test.Next(_L("Create cleanup NewL while no room in heap")); |
|
1593 TRAP(r,pC=CCleanup::NewL()); |
|
1594 test_Equal(KErrNoMemory,r); |
|
1595 |
|
1596 for (;i>=0;i--) |
|
1597 { |
|
1598 User::Free(ptrTable[i]); |
|
1599 } |
|
1600 |
|
1601 __UHEAP_MARKEND; |
|
1602 |
|
1603 //restore settings |
|
1604 User::SetJustInTime(justInTime); |
|
1605 |
|
1606 test.End(); |
1540 test.End(); |
1607 } |
1541 } |
1608 |
1542 |
1609 GLDEF_C TInt E32Main() |
1543 GLDEF_C TInt E32Main() |
1610 { |
1544 { |
1663 testStackBalance(); |
1597 testStackBalance(); |
1664 |
1598 |
1665 test.Next(_L("Test TRAP_IGNORE")); |
1599 test.Next(_L("Test TRAP_IGNORE")); |
1666 testTrapIgnore(); |
1600 testTrapIgnore(); |
1667 |
1601 |
1668 test.Next(_L("Test CCleanup::NewL")); |
|
1669 testCCleanupNewL(); |
|
1670 |
|
1671 delete pT; |
|
1672 |
|
1673 test.End(); |
1602 test.End(); |
1674 return(0); |
1603 return(0); |
1675 } |
1604 } |
1676 |
1605 |