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) |
42 // Platforms/Drives/Compatibility: |
44 // Platforms/Drives/Compatibility: |
43 // All. |
45 // All. |
44 // Assumptions/Requirement/Pre-requisites: |
46 // Assumptions/Requirement/Pre-requisites: |
45 // Failures and causes: |
47 // Failures and causes: |
46 // Base Port information: |
48 // Base Port information: |
53 #include <e32panic.h> |
55 #include <e32panic.h> |
54 #include <e32debug.h> |
56 #include <e32debug.h> |
55 #include <e32def.h> |
57 #include <e32def.h> |
56 #include <e32def_private.h> |
58 #include <e32def_private.h> |
57 |
59 |
58 |
60 #if defined(_DEBUG) |
59 const TInt KInitialCount=2; |
61 const TInt KInitialCount=2; |
60 const TInt KInitialCountAll=3; |
62 const TInt KInitialCountAll=3; |
|
63 #endif |
|
64 |
61 const TInt KLeaveValue=0x12345678; |
65 const TInt KLeaveValue=0x12345678; |
62 const TInt KMaxAlloc=6; |
66 const TInt KMaxAlloc=6; |
|
67 const TInt KTableSize = 1000; |
63 |
68 |
64 static const TInt KHeapSize = 0x2000; |
69 static const TInt KHeapSize = 0x2000; |
|
70 |
65 |
71 |
66 enum TWhat {EPop,EPopAndDestroy,EMulti,ENull}; |
72 enum TWhat {EPop,EPopAndDestroy,EMulti,ENull}; |
67 |
73 |
68 class CTest : public CBase |
74 class CTest : public CBase |
69 { |
75 { |
104 LOCAL_D CBufFlat* gP2; |
110 LOCAL_D CBufFlat* gP2; |
105 |
111 |
106 |
112 |
107 LOCAL_C void ReallocateStackL() |
113 LOCAL_C void ReallocateStackL() |
108 { |
114 { |
109 TInt n = 0; |
|
110 for(TInt i = 0; i < KMaxAlloc; ++i) |
115 for(TInt i = 0; i < KMaxAlloc; ++i) |
111 { |
116 { |
112 HBufC *p1 = HBufC::NewLC(4); //Stack re-allocation will be performed due to the additional objects pushed |
117 (void)HBufC::NewLC(4); //Stack re-allocation will be performed due to the additional objects pushed |
113 //into the cleanup stack |
118 //into the cleanup stack |
114 n = p1->Length(); //include this line to avoid warnigs for unused "p1" variable |
|
115 } |
119 } |
116 test.Printf(_L("ReallocateStackL(): PopAndDestroy KMaxAlloc pointers\n")); |
120 test.Printf(_L("ReallocateStackL(): PopAndDestroy KMaxAlloc pointers\n")); |
117 CleanupStack::PopAndDestroy(KMaxAlloc); |
121 CleanupStack::PopAndDestroy(KMaxAlloc); |
118 } |
122 } |
119 |
123 |
128 |
132 |
129 CTest3::~CTest3() |
133 CTest3::~CTest3() |
130 { |
134 { |
131 RDebug::Printf("~CTest3(): Modify Cleanup stack by pushing items"); |
135 RDebug::Printf("~CTest3(): Modify Cleanup stack by pushing items"); |
132 |
136 |
133 TInt n = 0; |
|
134 for(TInt i = 0; i < KMaxAlloc; ++i) |
137 for(TInt i = 0; i < KMaxAlloc; ++i) |
135 { |
138 { |
136 HBufC *p1 = HBufC::NewLC(4); //Stack re-allocation will be performed due to the additional objects pushed |
139 HBufC::NewLC(4); //Stack re-allocation will be performed due to the additional objects pushed |
137 //into the cleanup stack |
140 //into the cleanup stack |
138 n = p1->Length(); //include this line to avoid warnigs for unused "p1" variable |
|
139 } |
141 } |
140 } |
142 } |
141 |
143 |
142 LOCAL_C void ModifyStack() |
144 LOCAL_C void ModifyStack() |
143 { |
145 { |
146 |
148 |
147 RDebug::Printf("ModifyStack(): PopAndDestroy ptr6"); |
149 RDebug::Printf("ModifyStack(): PopAndDestroy ptr6"); |
148 CleanupStack::PopAndDestroy(); |
150 CleanupStack::PopAndDestroy(); |
149 } |
151 } |
150 |
152 |
151 LOCAL_C TInt PanicStackModifiedFn(TAny* aNopFn) |
153 LOCAL_C TInt PanicStackModifiedFn(TAny* /*aNopFn*/) |
152 { |
154 { |
153 __UHEAP_MARK; |
155 __UHEAP_MARK; |
154 CTrapCleanup* cleanup = CTrapCleanup::New(); |
156 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 #if defined(_DEBUG) |
1094 TRAPD(r,pC->PushL(p6)); |
1095 TRAPD(r,pC->PushL(p6)); |
1095 #if defined(_DEBUG) |
|
1096 test(r==KErrNoMemory); |
1096 test(r==KErrNoMemory); |
|
1097 #else |
|
1098 TRAP_IGNORE(pC->PushL(p6)); |
1097 #endif |
1099 #endif |
1098 __UHEAP_CHECK(KInitialCount+6); |
1100 __UHEAP_CHECK(KInitialCount+6); |
1099 pC->PopAndDestroyAll(); |
1101 pC->PopAndDestroyAll(); |
1100 __UHEAP_CHECK(KInitialCount); |
1102 __UHEAP_CHECK(KInitialCount); |
1101 // |
1103 // |
1298 LOCAL_C void reentrantCleanup(TAny*) |
1300 LOCAL_C void reentrantCleanup(TAny*) |
1299 // |
1301 // |
1300 // A cleanup operation which uses a trap harness and the cleanup stack |
1302 // A cleanup operation which uses a trap harness and the cleanup stack |
1301 // |
1303 // |
1302 { |
1304 { |
1303 TRAPD(ignore,useCleanupStackL()) |
1305 TRAP_IGNORE(useCleanupStackL()); |
1304 } |
1306 } |
1305 |
1307 |
1306 LOCAL_C void addReentrantItemL() |
1308 LOCAL_C void addReentrantItemL() |
1307 { |
1309 { |
1308 CleanupStack::PushL(TCleanupItem(reentrantCleanup)); |
1310 CleanupStack::PushL(TCleanupItem(reentrantCleanup)); |
1422 test.Next(_L("Let it fall out of scope")); |
1424 test.Next(_L("Let it fall out of scope")); |
1423 } |
1425 } |
1424 test.Next(_L("Check the object has closed")); |
1426 test.Next(_L("Check the object has closed")); |
1425 __KHEAP_CHECK(0); |
1427 __KHEAP_CHECK(0); |
1426 |
1428 |
1427 TRAPD(r, testAutoCloseL()); |
1429 TRAP_IGNORE(testAutoCloseL()); |
1428 test.Next(_L("Check object has been closed and cleaned up after leave")); |
1430 test.Next(_L("Check object has been closed and cleaned up after leave")); |
1429 __KHEAP_MARKEND; |
1431 __KHEAP_MARKEND; |
1430 test.End(); |
1432 test.End(); |
1431 } |
1433 } |
1432 |
1434 |
1535 User::Leave(KErrGeneral); |
1537 User::Leave(KErrGeneral); |
1536 ); |
1538 ); |
1537 test(count==1); |
1539 test(count==1); |
1538 |
1540 |
1539 delete pC; |
1541 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 |
1540 test.End(); |
1606 test.End(); |
1541 } |
1607 } |
1542 |
1608 |
1543 GLDEF_C TInt E32Main() |
1609 GLDEF_C TInt E32Main() |
1544 { |
1610 { |
1597 testStackBalance(); |
1663 testStackBalance(); |
1598 |
1664 |
1599 test.Next(_L("Test TRAP_IGNORE")); |
1665 test.Next(_L("Test TRAP_IGNORE")); |
1600 testTrapIgnore(); |
1666 testTrapIgnore(); |
1601 |
1667 |
|
1668 test.Next(_L("Test CCleanup::NewL")); |
|
1669 testCCleanupNewL(); |
|
1670 |
|
1671 delete pT; |
|
1672 |
1602 test.End(); |
1673 test.End(); |
1603 return(0); |
1674 return(0); |
1604 } |
1675 } |
1605 |
1676 |