--- a/kerneltest/e32test/dma/d_dma.cpp Tue Feb 02 01:24:03 2010 +0200
+++ b/kerneltest/e32test/dma/d_dma.cpp Fri Apr 16 16:24:37 2010 +0300
@@ -1,4 +1,4 @@
-// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
+// Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of the License "Eclipse Public License v1.0"
@@ -185,6 +185,8 @@
TInt Execute(const TDesC8& aDes);
static void Dfc(DDmaRequest::TResult aResult, TAny* aArg);
TInt DoGetInfo(TAny* aInfo);
+ void FreeDmaRequests();
+ void FreeClientRequests();
private:
TUint32 iCookie;
TBufferMgr iBufMgr;
@@ -193,6 +195,7 @@
DDmaRequest* iRequests[KMaxRequests];
TClientRequest* iClientRequests[KMaxRequests];
DDmaTestChannel* iMap[KMaxRequests];
+ TBool iCloseInCb[KMaxRequests];
TUint32 iMemMemPslInfo;
DThread* iClient;
TDynamicDfcQue* iDfcQ;
@@ -277,6 +280,8 @@
}
if (! iRequests[i])
return KErrNoMemory;
+
+ iCloseInCb[i] = EFalse;
}
return KErrNone;
}
@@ -288,13 +293,10 @@
if (iChannel)
{
iChannel->CancelAll();
- TInt i;
- for (i=0; i<KMaxRequests; ++i)
- delete iRequests[i];
+ FreeDmaRequests();
iChannel->Close();
- for (i=0; i<KMaxRequests; ++i)
- Kern::DestroyClientRequest(iClientRequests[i]);
}
+ FreeClientRequests();
if (iDfcQ)
{
iDfcQ->Destroy();
@@ -302,6 +304,23 @@
iBufMgr.FreeAll();
}
+void DDmaTestChannel::FreeDmaRequests()
+ {
+ for (TInt i=0; i<KMaxRequests; ++i)
+ {
+ delete iRequests[i];
+ iRequests[i] = NULL;
+ }
+ }
+
+void DDmaTestChannel::FreeClientRequests()
+ {
+ for (TInt i=0; i<KMaxRequests; ++i)
+ {
+ Kern::DestroyClientRequest(iClientRequests[i]);
+ }
+ }
+
TInt DDmaTestChannel::Request(TInt aFunction, TAny* a1, TAny* a2)
{
@@ -401,14 +420,35 @@
{
case 'Q':
{
- TInt arg = *p++ - '0';
- __ASSERT_DEBUG(0 <= arg && arg < KMaxRequests, Kern::PanicCurrentThread(KClientPanicCat, __LINE__));
- iRequests[arg]->Queue();
+ __ASSERT_DEBUG(p < pEnd, Kern::PanicCurrentThread(KClientPanicCat, __LINE__));
+ TInt nextChar = *p++;
+ TInt channel = -1;
+
+ if(nextChar == 'X')
+ {
+ // Channel should be closed in callback
+ __ASSERT_DEBUG(p < pEnd, Kern::PanicCurrentThread(KClientPanicCat, __LINE__));
+ channel = *p++ - '0';
+ iCloseInCb[channel] = ETrue;
+ }
+ else
+ {
+ channel = nextChar - '0';
+ }
+ __ASSERT_DEBUG(0 <= channel && channel < KMaxRequests, Kern::PanicCurrentThread(KClientPanicCat, __LINE__));
+ iRequests[channel]->Queue();
break;
}
case 'C':
+ {
iChannel->CancelAll();
+ for(TInt i=0; i<KMaxRequests; ++i)
+ {
+ if(iClientRequests[i]->IsReady())
+ iClientRequests[i]->Reset();
+ }
break;
+ }
default:
Kern::PanicCurrentThread(KClientPanicCat, __LINE__);
}
@@ -424,6 +464,17 @@
TInt i = ppC - pC->iMap;
TClientRequest* req = pC->iClientRequests[i];
TInt r = (aResult==DDmaRequest::EOk) ? KErrNone : KErrGeneral;
+
+ if(pC->iCloseInCb[i])
+ {
+ pC->iCloseInCb[i] = EFalse;
+ __KTRACE_OPT(KDMA, Kern::Printf("Close channel in callback"));
+
+ pC->FreeDmaRequests();
+ pC->iChannel->Close();
+ pC->iChannel = NULL;
+ }
+
if (req->IsReady())
Kern::QueueRequestComplete(pC->iClient, req, r);
}