kerneltest/e32test/dma/d_dma.cpp
changeset 90 947f0dc9f7a8
parent 36 538db54a451d
child 243 c7a0ce20c48c
--- 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);
 	}