diff -r 000000000000 -r 5d03bc08d59c graphicshwdrivers/surfacemgr/test/src/tsurfacemanagermultithread.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graphicshwdrivers/surfacemgr/test/src/tsurfacemanagermultithread.cpp Tue Feb 02 01:47:50 2010 +0200 @@ -0,0 +1,1849 @@ +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Surface manager multi-threaded test code +// +// + +/** + @file + @test + @internalComponent - Internal Symbian test code +*/ + +#include "tsurfacemanagermultithread.h" +#include +#include +#include +#include +#include +#include + +static TSurfaceId globalSurfaceId; +static TInt testResult; + +typedef CTSurfaceManagerMultiThread::TInfo TInfo; + +CTSurfaceManagerMultiThread::CTSurfaceManagerMultiThread(CTestStep* aStep): + CTGraphicsBase(aStep) + { + + } + +CTSurfaceManagerMultiThread::~CTSurfaceManagerMultiThread() + { + iSurfaceManager.Close(); + } + +void CTSurfaceManagerMultiThread::RunTestCaseL(TInt aCurTestCase) + { + TInt procHandles1 =0; + TInt threadHandles1=0; + RThread().HandleCount(procHandles1, threadHandles1); + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(KUnknownSYMTestCaseIDName); + switch(aCurTestCase) + { +/** +@SYMTestCaseID GRAPHICS-SURFACEMANAGER-0078 +@SYMPREQ PREQ1879, PREQ1007 +@SYMREQ REQ8222,REQ8223 +@SYMTestPriority High +@SYMTestCaseDesc Test accessing surface in another thread without opening it + Thread 1: Create Surface + Thread 2: Map Surface - KErrNone (still accessible) + Thread 2: SurfaceInfo - KErrNone (still accessible) +@SYMTestStatus Implemented +@SYMTestActions Call CreateSurface(),MapSurface(), SurfaceInfo() +@SYMTestExpectedResults The surface can be successfully accessed in other threads without first opening it. +*/ + case 1: + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0078")); + TestAccessSurfaceWithoutOpeningL(); + break; +/** +@SYMTestCaseID GRAPHICS-SURFACEMANAGER-0079 +@SYMPREQ PREQ1879, PREQ1007 +@SYMREQ REQ8222,REQ8223 +@SYMTestPriority High +@SYMTestCaseDesc Test accessing a surface created in the existing shared chunk in another thread without opening it. + Thread 1: Create a Surface in the new chunk with valid creation attributes + Thread 1: Map the surface in the current process to get the chunk handle + Thread 1: Create a new surface in the existing chunk with valid creation attributes + Thread 2: Map the second Surface – KErrNone (still accessible) + Thread 2: SurfaceInfo – KErrNone (still accessible) +@SYMTestStatus Implemented +@SYMTestActions Call CreateSurface(),MapSurface(), SurfaceInfo() +@SYMTestExpectedResults MapSurface, SurfaceInfo return KerrNone +*/ + case 2: + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0079")); + TestAccessSurfaceInExistingSharedChunkL(); + break; +/** +@SYMTestCaseID GRAPHICS-SURFACEMANAGER-0080 +@SYMPREQ PREQ1879, PREQ1007 +@SYMREQ REQ8222,REQ8223 +@SYMTestPriority High +@SYMTestCaseDesc Test closing surface in another thread without opening it + Thread 1: Create Surface + Thread 2: Close Surface - KErrNone +@SYMTestStatus Implemented +@SYMTestActions Call CreateSurface(),CloseSurface() +@SYMTestExpectedResults The surface can be successfully closed in other threads without first opening it. +*/ + case 3: + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0080")); + TestCloseSurfaceWithoutOpeningL(); + break; +/** +@SYMTestCaseID GRAPHICS-SURFACEMANAGER-0081 +@SYMPREQ PREQ1879, PREQ1007 +@SYMREQ REQ8222,REQ8223 +@SYMTestPriority High +@SYMTestCaseDesc Test accessing an surface which is created in another thread but closed in current thread + Thread 2: Create Surface + Thread 1: Close Surface - KerrNone + Thread 2: Map Surface - KErrArgument + Thread 2: SurfaceInfo - KErrArgument +@SYMTestStatus Implemented +@SYMTestActions Call CreateSurface(),CloseSurface(), MapSurface(), SurfaceInfo() +@SYMTestExpectedResults The surface cant be accessd even after it is closed in other threads. +*/ + case 4: + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0081")); + TestAccessSurfaceClosedThreadL(); + break; +/** +@SYMTestCaseID GRAPHICS-SURFACEMANAGER-0067 +@SYMPREQ PREQ1879, PREQ1007 +@SYMREQ REQ8222,REQ8223 +@SYMTestPriority High +@SYMTestCaseDesc Test closing surface created in the existing chunk in another thread without opening it + Thread 1: Create a Surface in a new shared chunk with valid attributes + Thread 1: Map the surface in the process to get the shared chunk handle + Thread 1: Create a new surface in the existing shared chunk + Thread 2: Close the second surface – KErrNone (the second surface is deleted) + Thread 2: Call SurfaceInfo to the first surface and it returns KErrNone, but it returns KErrArgument to the second surface. + Thread 2: Close the first surface and check it returns KErrNone (the first surface is deleted). + Thread 1: Call SurfaceInfo to both surfaces and return KErrArgument + Thread 1: Check the chunk is still accessible by calling RChunk::Base() + Thread 1: Close the chunk handle +@SYMTestStatus Implemented +@SYMTestActions Call CreateSurface(),CloseSurface() +@SYMTestExpectedResults CloseSurface returns KErrNone. The chunk handle is not closed even when both surfaces are deleted. +*/ + case 5: + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0067")); + TestCloseSurfaceExistingSharedChunkL(); + break; + +/** +@SYMTestCaseID GRAPHICS-SURFACEMANAGER-0068 +@SYMPREQ PREQ1007 +@SYMREQ REQ8222,REQ8223 +@SYMTestPriority High +@SYMTestCaseDesc Test closing an surface which is already closed in other thread return KErrArgument + Thread 2: Create Surface + Thread 1: Close Surface - KerrNone + Thread 2: Close Surface - KErrArgument +@SYMTestStatus Implemented +@SYMTestActions Call CreateSurface(),CloseSurface() +@SYMTestExpectedResults The surface cant be closed again. +*/ + case 6: + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0068")); + TestCloseSurfaceClosedThreadL(); + break; +/** +@SYMTestCaseID GRAPHICS-SURFACEMANAGER-0069 +@SYMPREQ PREQ1007 +@SYMREQ REQ8222,REQ8223 +@SYMTestPriority High +@SYMTestCaseDesc Test accessing an surface which is already opened and closed in another thread, given that the process still owns the surface + Thread 1: Create Surface + Thread 2: Open Surface -- KErrNone + Thread 2: Close Surface -- KErrNone + Thread 1: Map Surface - KErrNone + Thread 1: SurfaceInfo - KErrNone +@SYMTestStatus Implemented +@SYMTestActions Call CreateSurface(),CloseSurface(), MapSurface(), SurfaceInfo, OpenSurface() +@SYMTestExpectedResults The surface is still accessible in the thread residing the owning process +*/ + case 7: + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0069")); + TestAccessSurfaceOpenedClosedThreadL(); + break; +/** +@SYMTestCaseID GRAPHICS-SURFACEMANAGER-0070 +@SYMPREQ PREQ1007 +@SYMREQ REQ8222,REQ8223 +@SYMTestPriority High +@SYMTestCaseDesc Test closing an surface which is already opened and closed in another thread, given that the process still owns the surface + Thread 1: Create Surface + Thread 2: Open Surface + Thread 2: Close Surface + Thread 1: Close Surface - KErrNone +@SYMTestStatus Implemented +@SYMTestActions Call CreateSurface(),CloseSurface(), OpenSurface() +@SYMTestExpectedResults The surface is still closible in the thread residing in the owning process +*/ + case 8: + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0070")); + TestCloseSurfaceOpenedClosedThreadL(); + break; +/** +@SYMTestCaseID GRAPHICS-SURFACEMANAGER-0071 +@SYMPREQ PREQ1007 +@SYMREQ REQ8222,REQ8223 +@SYMTestPriority High +@SYMTestCaseDesc Test accessing surface in another thread when the opening thread is killed + Thread 1: Create Surface + Thread 2: Open Surface + Thread 2: Kill the thread + Thread 1: Map Surface - KErrNone + Thread 1: Surface Info -- KErrNone +@SYMTestStatus Implemented +@SYMTestActions Call CreateSurface(),CloseSurface(), MapSurface(), SurfaceInfo(), OpenSurface() +@SYMTestExpectedResults The surface is accessible when the opening thread is killed +*/ + case 9: + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0071")); + TestAccessSurfaceOpenedKilledThreadL(); + break; +/** +@SYMTestCaseID GRAPHICS-SURFACEMANAGER-0072 +@SYMPREQ PREQ1007 +@SYMREQ REQ8222,REQ8223 +@SYMTestPriority High +@SYMTestCaseDesc Test closing surface in another thread when the opening thread is killed + Thread 1: Create Surface + Thread 2: Open Surface + Thread 2: Kill the thread + Thread 1: Close Surface - KErrNone +@SYMTestStatus Implemented +@SYMTestActions Call CreateSurface(),CloseSurface(), OpenSurface() +@SYMTestExpectedResults The surface is closible when the opening thread is killed +*/ + case 10: + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0072")); + TestCloseSurfaceOpenedKilledThreadL(); + break; +/** +@SYMTestCaseID GRAPHICS-SURFACEMANAGER-0073 +@SYMPREQ PREQ1007 +@SYMREQ REQ8222,REQ8223 +@SYMTestPriority High +@SYMTestCaseDesc Test accessing surface in another thread when the creating thread is killed and it is closed in other threads + Thread 2: Create Surface + Thread 1: Close Surface + Thread 2: Kill Thread + Thread 1: Map Surface - KErrArgument + Thread 1: Surface Info - KErrArgument +@SYMTestStatus Implemented +@SYMTestActions Call CreateSurface(),CloseSurface(), MapSurface(), SurfaceInfo(), +@SYMTestExpectedResults The surface is accessible when the creating thread is killed and it is closed in other threads +*/ + case 11: + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0073")); + TestAccessSurfaceCreateKilledThreadL(); + break; +/** +@SYMTestCaseID GRAPHICS-SURFACEMANAGER-0074 +@SYMPREQ PREQ1007 +@SYMREQ REQ8222,REQ8223 +@SYMTestPriority High +@SYMTestCaseDesc Test accessing surface in another thread when the creating thread is killed and it is closed in other threads + Thread 2: Create Surface + Thread 1: Close Surface + Thread 2: Kill Thread + Thread 1: Close Surface - KErrArgument +@SYMTestStatus Implemented +@SYMTestActions Call CreateSurface(),CloseSurface() +@SYMTestExpectedResults The surface is accessible when the creating thread is killed and it is closed in other threads +*/ + case 12: + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0074")); + TestCloseSurfaceCreateKilledThreadL(); + break; +/** +@SYMTestCaseID GRAPHICS-SURFACEMANAGER-0075 +@SYMPREQ PREQ1007 +@SYMREQ REQ8222,REQ8223 +@SYMTestPriority High +@SYMTestCaseDesc Test closing on one thread doesn't prevent opening on other Threads, provided one Thread still owns surface + Thread 1: Create Surface + Thread 2: Open Surface + Thread 2: Close Surface + Thread 3: Open Surface - KerrNone + Thread 3: Map Surface - KerrNone + Thread 3: SurfaceInfo -- KErrNone +@SYMTestStatus Implemented +@SYMTestActions Call CreateSurface(),CloseSurface(), MapSurface(), SurfaceInfo(), +@SYMTestExpectedResults It is expected that closing on one thread doesn't prevent opening on other Threads, provided one Thread still owns surface +*/ + case 13: + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0075")); + TestAccessSurfaceThreeThreadsL(); + break; +/** +@SYMTestCaseID GRAPHICS-SURFACEMANAGER-0076 +@SYMPREQ PREQ1007 +@SYMREQ REQ8222,REQ8223 +@SYMTestPriority High +@SYMTestCaseDesc Test surface can be accessed from third thread when creating thread dies and second thread closes + Thread 2: Create Surface + Thread 1: Open Surface + Thread 3: Open Surface + Thread 1: Close Surface + Thread 2: Kill Thread + Thread 3: Close Surface + Thread 3: Map Surface - KerrNone + Thread 3: SurfaceInfo -- KErrNone +@SYMTestStatus Implemented +@SYMTestActions Call CreateSurface(),CloseSurface(), MapSurface(), SurfaceInfo(), OpenSurface() +@SYMTestExpectedResults It is expected that surface can be accessed from third thread when creating thread dies and second thread closes +*/ + case 14: + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0076")); + TestAccessSurfaceDieCloseOtherThreadsL(); + break; +/** +@SYMTestCaseID GRAPHICS-SURFACEMANAGER-0077 +@SYMPREQ PREQ1007 +@SYMREQ REQ8222,REQ8223 +@SYMTestPriority High +@SYMTestCaseDesc Test that the surface can be opened from the third Thread after creating thread dies and second and third thread close the surface + Thread 2: Create Surface + Thread 1: Open Surface + Thread 3: Open Surface + Thread 1: Close Surface + Thread 2: Kill Thread + Thread 3: Close Surface + Thread 3: Open Surface - KerrNone +@SYMTestStatus Implemented +@SYMTestActions Call CreateSurface(),CloseSurface(), OpenSurface() +@SYMTestExpectedResults It is expected that the surface can be opened from the third Thread after creating thread dies and second and third thread close the surface +*/ + case 15: + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(_L("GRAPHICS-SURFACEMANAGER-0077")); + TestOpenSurfaceDieCloseOtherThreadsL(); + break; + default: + ((CTSurfaceManagerMultiThreadStep*)iStep)->SetTestStepID(KNotATestSYMTestCaseIDName); + ((CTSurfaceManagerMultiThreadStep*)iStep)->CloseTMSGraphicsStep(); + TestComplete(); + break; + } + ((CTSurfaceManagerMultiThreadStep*)iStep)->RecordTestResultL(); + // Handle check + TInt procHandles2 =0; + TInt threadHandles2=0; + RThread().HandleCount(procHandles2,threadHandles2); + if (threadHandles1 != threadHandles2) + { + User::Leave(KErrGeneral); // Thread-owned handles not closed + } + } + +void CTSurfaceManagerMultiThread::CloseSurfaceWhenLeave(TAny* aInfo) + { + TInt err1 = ((TInfo*)aInfo)->iSurfaceManager.CloseSurface(((TInfo*)aInfo)->iSurfaceId); + TInt err2 = ((TInfo*)aInfo)->iSurfaceManager.CloseSurface(((TInfo*)aInfo)->iSurfaceIdNew); + if (err1!=KErrNone || err2!=KErrNone) + RDebug::Print(_L("Error closing surfaces err1= %d, err2= %d\n"),err1,err2); + } + +void CTSurfaceManagerMultiThread::TestAccessSurfaceWithoutOpeningL() + { + User::LeaveIfError(iSurfaceManager.Open()); + + // Setup attributes + RSurfaceManager::TSurfaceCreationAttributesBuf buf; + RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); + attributes.iSize = TSize(480,16); + attributes.iBuffers = 2; // number of buffers in the surface + attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp + attributes.iStride = 1013; // Number of bytes between start of one line and start of next + attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data + attributes.iAlignment = RSurfaceManager::EPageAligned; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned + + RSurfaceManager::THintPair hints[2]; // two hint pairs specified + attributes.iHintCount = 2; + attributes.iSurfaceHints = hints; + hints[0].Set(TUid::Uid(0x124578), 25, ETrue); + hints[1].Set(TUid::Uid(0x237755), 50, ETrue); + + attributes.iContiguous = ETrue; + attributes.iCacheAttrib = RSurfaceManager::ECached; + attributes.iMappable = ETrue; + + // Test create surface doesn't return an error + TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId)); + // Logging info + INFO_PRINTF1(_L("Test accessing surface in another thread without opening it\r\n")); + // Create a semaphore + RSemaphore sem; + TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0)); + CleanupClosePushL(sem); + + // Create a second thread in the current process and opens the handle + iInfo.iSurfaceManager = iSurfaceManager; + iInfo.iSurfaceId = iSurfaceId; + iInfo.iSurfaceIdNew = TSurfaceId::CreateNullId(); + iInfo.iThreadTestCase = EMapSurfaceInfo; + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo)); + + RThread thread1; + _LIT(KNameThreadSecond1, "Test_SurfaceManager_ThreadSecond1"); + User::LeaveIfError(thread1.Create(KNameThreadSecond1,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo)); + CleanupStack::Pop(); + // Launch second thread + TRequestStatus statusThreadSecond; + thread1.Logon(statusThreadSecond); + thread1.SetPriority(EPriorityLess); + thread1.Resume(); + testResult = EAllZero; + // Passes control to the second process + sem.Wait(); + thread1.Suspend(); + + // Test results in second thread + TEST (testResult = (EMapSurfaceTestPassed | ESurfaceInfoTestPassed)); + + // Pass control off to the second process again + thread1.Resume(); + + // Wait for a second for the second thread to terminate + User::WaitForRequest(statusThreadSecond); + + //Close the handles + CleanupStack::PopAndDestroy(1, &sem); //invoke surface manager to close the surface also close the handle to RSemaphore + thread1.Close(); + iSurfaceManager.Close(); + } + +void CTSurfaceManagerMultiThread::TestAccessSurfaceInExistingSharedChunkL() + { + // Logging info + INFO_PRINTF1(_L("Test accessing a surface created in the existing shared chunk in another thread without opening it\r\n")); + + User::LeaveIfError(iSurfaceManager.Open()); + + // Setup attributes + + RSurfaceManager::TSurfaceCreationAttributesBuf buf; + RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); + + attributes.iSize = TSize(100,100); + attributes.iBuffers = 1; // number of buffers in the surface + attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar; // 2bpp + attributes.iStride = 400; // Number of bytes between start of one line and start of next + attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data + attributes.iAlignment = 2; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned + + RSurfaceManager::THintPair hints[2]; // two hint pairs specified + attributes.iHintCount = 2; + attributes.iSurfaceHints = hints; + hints[0].Set(TUid::Uid(0x124578), 25, ETrue); + hints[1].Set(TUid::Uid(0x237755), 50, ETrue); + + attributes.iContiguous = ETrue; + attributes.iCacheAttrib = RSurfaceManager::ECached; + attributes.iOffsetBetweenBuffers = 0; + attributes.iMappable = ETrue; + + // Test create surface doesn't return an error + TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId)); + + //Map the surface in the current processs + RChunk handle; + TEST(KErrNone == iSurfaceManager.MapSurface(iSurfaceId,handle)); + + // Cache, Contiguous and Alignment attributes are ignored for the already existing chunks + RSurfaceManager::TSurfaceCreationAttributesBuf buff; + RSurfaceManager::TSurfaceCreationAttributes& attributesNew = buff(); + + attributesNew.iSize = TSize(480,16); + attributesNew.iBuffers = 2; // number of buffers in the surface + attributesNew.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp + attributesNew.iStride = 1013; // Number of bytes between start of one line and start of next + attributesNew.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data + + attributesNew.iHintCount = 1; + attributesNew.iSurfaceHints = hints; + hints[0].Set(TUid::Uid(0x124545), 50, EFalse); + + attributesNew.iAlignment = 2; + attributesNew.iOffsetBetweenBuffers = 0; + attributes.iMappable = ETrue; + + // Test create surface doesn't return an error + // For the time being KErrArgument will be returned as the core codes are + // not ready to check the passed in shared chunk handle. + TEST(KErrNone == iSurfaceManager.CreateSurface(buff, iSurfaceIdNew, handle)); + + + // Create a semaphore + RSemaphore sem; + TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0)); + CleanupClosePushL(sem); + + // Create a second thread in the current process and opens the handle + iInfo.iSurfaceManager = iSurfaceManager; + iInfo.iSurfaceId = iSurfaceIdNew; + iInfo.iSurfaceIdNew = iSurfaceId; + iInfo.iThreadTestCase = EMapSurfaceInfo; + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo)); + + RThread thread2; + _LIT(KNameThreadSecond2, "Test_SurfaceManager_ThreadSecond2"); + User::LeaveIfError(thread2.Create(KNameThreadSecond2,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo)); + + CleanupStack::Pop(); + // Launch second thread + TRequestStatus statusThreadSecond; + thread2.Logon(statusThreadSecond); + thread2.SetPriority(EPriorityLess); + thread2.Resume(); + testResult = EAllZero; + // Passes control to the second process + sem.Wait(); + thread2.Suspend(); + + // Test results in second thread + TEST (testResult = (EMapSurfaceTestPassed | ESurfaceInfoTestPassed)); + + // Pass control off to the second process again + thread2.Resume(); + + // Wait for a second for the second thread to terminate + User::WaitForRequest(statusThreadSecond); + + //Close the handles + CleanupStack::PopAndDestroy(1, &sem); //invoke surface manager to close the surface also close the handle to RSemaphore + handle.Close(); + thread2.Close(); + iSurfaceManager.Close(); + + } + +void CTSurfaceManagerMultiThread::TestCloseSurfaceWithoutOpeningL() + { + User::LeaveIfError(iSurfaceManager.Open()); + + // Setup attributes + RSurfaceManager::TSurfaceCreationAttributesBuf buf; + RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); + + attributes.iSize = TSize(480,16); + attributes.iBuffers = 2; // number of buffers in the surface + attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp + attributes.iStride = 1013; // Number of bytes between start of one line and start of next + attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data + attributes.iAlignment = RSurfaceManager::EPageAligned; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned + + RSurfaceManager::THintPair hints[2]; // two hint pairs specified + attributes.iHintCount = 2; + attributes.iSurfaceHints = hints; + hints[0].Set(TUid::Uid(0x124578), 25, ETrue); + hints[1].Set(TUid::Uid(0x237755), 50, ETrue); + + attributes.iContiguous = ETrue; + attributes.iCacheAttrib = RSurfaceManager::ECached; + attributes.iMappable = ETrue; + + // Test create surface doesn't return an error + TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId)); + + INFO_PRINTF1(_L("Test closing surface in another thread without opening it\r\n")); + + // Create a semaphore + RSemaphore sem; + TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0)); + CleanupClosePushL(sem); + + // Creates a second thread in the current process and opens the handle + iInfo.iSurfaceManager = iSurfaceManager; + iInfo.iSurfaceId = iSurfaceId; + iInfo.iThreadTestCase = ECloseSurfaces; + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo)); + + RThread thread3; + _LIT(KNameThreadSecond3, "Test_SurfaceManager_ThreadSecond3"); + User::LeaveIfError(thread3.Create(KNameThreadSecond3,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo)); + CleanupStack::Pop(); + // Launch second thread to close the surface + TRequestStatus statusThreadSecond; + thread3.Logon(statusThreadSecond); + thread3.SetPriority(EPriorityLess); + thread3.Resume(); + testResult = EAllZero; + // Passes control to the second thread + sem.Wait(); + thread3.Suspend(); + + // Test the results in the second thread + TEST(testResult == ECloseSurfaceTestPassed); + + thread3.Resume(); + // Wait for a second for the second process to terminate + User::WaitForRequest(statusThreadSecond); + + //Close the handle + CleanupStack::PopAndDestroy(1, &sem); + thread3.Close(); + iSurfaceManager.Close(); + } + +void CTSurfaceManagerMultiThread::TestAccessSurfaceClosedThreadL() + { + User::LeaveIfError(iSurfaceManager.Open()); + // Logging info + INFO_PRINTF1(_L("Test accessing an surface which is created in another thread but closed in current thread\r\n")); + + // Create a semaphore + RSemaphore sem; + RSemaphore semMain; + + TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0)); + CleanupClosePushL(sem); + TEST(KErrNone == semMain.CreateGlobal(KMainThreadSemaphore, 0)); + CleanupClosePushL(semMain); + + // Creates a second thread in the current process and opens the handle + iInfo.iSurfaceManager = iSurfaceManager; + iInfo.iSurfaceId = iSurfaceId; + iInfo.iThreadTestCase = ECreateSurfaceMapInfo; + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo)); + + RThread thread4; + _LIT(KNameThreadSecond4, "Test_SurfaceManager_ThreadSecond4"); + User::LeaveIfError(thread4.Create(KNameThreadSecond4,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo)); + CleanupStack::Pop(); + // Launch the second trhead + TRequestStatus statusThreadSecond; + thread4.Logon(statusThreadSecond); + thread4.SetPriority(EPriorityLess); + thread4.Resume(); + + testResult = EAllZero; + // Passes control to the second process + sem.Wait(); + // Test creating surface in second thread + TEST(testResult == ECreateSurfaceTestPassed); + // Reset testResult + testResult = EAllZero; + // Test closing surface + iSurfaceId = globalSurfaceId; + TEST(KErrNone == iSurfaceManager.CloseSurface(globalSurfaceId)); + semMain.Signal(); + // Wait the second thread to terminate + User::WaitForRequest(statusThreadSecond); + + // Test mapsurface and surfaceinfo executed in the second thread + TEST(testResult == (EMapSurfaceTestFailed|ESurfaceInfoTestFailed)); + // Close all the handles + CleanupStack::PopAndDestroy(2, &sem); + thread4.Close(); + iSurfaceManager.Close(); + + } + +void CTSurfaceManagerMultiThread::TestCloseSurfaceExistingSharedChunkL() + { + // Logging info + INFO_PRINTF1(_L("Test closing surface created in the existing chunk in another thread without opening it\r\n")); + + User::LeaveIfError(iSurfaceManager.Open()); + // Setup attributes + + RSurfaceManager::TSurfaceCreationAttributesBuf buf; + RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); + + attributes.iSize = TSize(100,100); + attributes.iBuffers = 1; // number of buffers in the surface + attributes.iPixelFormat = EUidPixelFormatYUV_422SemiPlanar; // 2bpp + attributes.iStride = 400; // Number of bytes between start of one line and start of next + attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data + attributes.iAlignment = 2; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned + + RSurfaceManager::THintPair hints[2]; // two hint pairs specified + attributes.iHintCount = 2; + attributes.iSurfaceHints = hints; + hints[0].Set(TUid::Uid(0x124578), 25, ETrue); + hints[1].Set(TUid::Uid(0x237755), 50, ETrue); + + attributes.iContiguous = ETrue; + attributes.iCacheAttrib = RSurfaceManager::ECached; + attributes.iOffsetBetweenBuffers = 0; + attributes.iMappable = ETrue; + + // Test create surface doesn't return an error + TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId)); + + //Map the surface in the current processs + RChunk handle; + TEST(KErrNone == iSurfaceManager.MapSurface(iSurfaceId,handle)); + + // Cache, Contiguous and Alignment attributes are ignored for the already existing chunks + RSurfaceManager::TSurfaceCreationAttributesBuf buff; + RSurfaceManager::TSurfaceCreationAttributes& attributesNew = buff(); + + attributesNew.iSize = TSize(480,16); + attributesNew.iBuffers = 2; // number of buffers in the surface + attributesNew.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp + attributesNew.iStride = 1013; // Number of bytes between start of one line and start of next + attributesNew.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data + + attributesNew.iHintCount = 1; + attributesNew.iSurfaceHints = hints; + hints[0].Set(TUid::Uid(0x124545), 50, EFalse); + + attributesNew.iAlignment = 2; + attributesNew.iOffsetBetweenBuffers = 0; + attributesNew.iMappable = ETrue; + + // Test create surface doesn't return an error + // For the time being KErrArgument will be returned as the core codes are + // not ready to check the passed in shared chunk handle. + TEST(KErrNone == iSurfaceManager.CreateSurface(buff, iSurfaceIdNew, handle)); + + // Create a semaphore + RSemaphore sem; + TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0)); + CleanupClosePushL(sem); + + // Create a second thread in the current process and opens the handle + iInfo.iSurfaceManager = iSurfaceManager; + iInfo.iSurfaceId = iSurfaceId; + iInfo.iSurfaceIdNew = iSurfaceIdNew; + iInfo.iThreadTestCase = ECloseBothSurfaces; + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo)); + + RThread thread5; + _LIT(KNameThreadSecond5, "Test_SurfaceManager_ThreadSecond5"); + User::LeaveIfError(thread5.Create(KNameThreadSecond5,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo)); + CleanupStack::Pop(); + // Launch second thread + TRequestStatus statusThreadSecond; + thread5.Logon(statusThreadSecond); + thread5.SetPriority(EPriorityLess); + thread5.Resume(); + testResult = EAllZero; + // Passes control to the second process + sem.Wait(); + thread5.Suspend(); + + // Test results in second thread + TEST (testResult = (ECloseSurfaceTestPassed | ESurfaceInfoTestPassed | ESurfaceInfoTestPassed2)); + RSurfaceManager::TInfoBuf infoBuf; + TEST (KErrArgument == iSurfaceManager.SurfaceInfo(iSurfaceId, infoBuf)); + TEST (KErrArgument == iSurfaceManager.SurfaceInfo(iSurfaceIdNew, infoBuf)); + + // Pass control off to the second process again + thread5.Resume(); + + // Wait for a second for the second thread to terminate + User::WaitForRequest(statusThreadSecond); + + CleanupStack::PopAndDestroy(1, &sem); //invoke surface manager to close the surface also close the handle to RSemaphore + handle.Close(); + thread5.Close(); + iSurfaceManager.Close(); + } + +void CTSurfaceManagerMultiThread::TestCloseSurfaceClosedThreadL() + { + User::LeaveIfError(iSurfaceManager.Open()); + + // Setup attributes + RSurfaceManager::TSurfaceCreationAttributesBuf buf; + RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); + + attributes.iSize = TSize(480,16); + attributes.iBuffers = 2; // number of buffers in the surface + attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp + attributes.iStride = 1013; // Number of bytes between start of one line and start of next + attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data + attributes.iAlignment = RSurfaceManager::EPageAligned; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned + + RSurfaceManager::THintPair hints[2]; // two hint pairs specified + attributes.iHintCount = 2; + attributes.iSurfaceHints = hints; + hints[0].Set(TUid::Uid(0x124578), 25, ETrue); + hints[1].Set(TUid::Uid(0x237755), 50, ETrue); + + attributes.iContiguous = ETrue; + attributes.iCacheAttrib = RSurfaceManager::ECached; + attributes.iOffsetBetweenBuffers = 0; + attributes.iMappable = ETrue; + // Logging info + INFO_PRINTF1(_L("Test closing an surface which is already closed in other thread return KErrArgument\r\n")); + // Create a semaphore + RSemaphore sem; + RSemaphore semMain; + TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0)); + CleanupClosePushL(sem); + TEST(KErrNone == semMain.CreateGlobal(KMainThreadSemaphore, 0)); + CleanupClosePushL(semMain); + + // Creates a second thread in the current process and opens the handle + iInfo.iSurfaceManager = iSurfaceManager; + iInfo.iSurfaceId = iSurfaceId; + iInfo.iThreadTestCase = ECreateSurfaceClose; + + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo)); + + RThread thread6; + _LIT(KNameThreadSecond6, "Test_SurfaceManager_ThreadSecond6"); + User::LeaveIfError(thread6.Create(KNameThreadSecond6,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo)); + CleanupStack::Pop(); + // Launch second thread + TRequestStatus statusThreadSecond; + thread6.Logon(statusThreadSecond); + thread6.SetPriority(EPriorityLess); + thread6.Resume(); + testResult = EAllZero; + // Passes control to the second thread + sem.Wait(); + // Test creating surface in second thread + TEST(testResult == ECreateSurfaceTestPassed); + testResult = EAllZero; + // Test closing surface + iSurfaceId = globalSurfaceId; + TEST(KErrNone == iSurfaceManager.CloseSurface(globalSurfaceId)); + + semMain.Signal(); + // Wait for a second for the second process to terminate + User::WaitForRequest(statusThreadSecond); + + TEST(testResult == ECloseSurfaceTestFailed); + // Close all the handles + CleanupStack::PopAndDestroy(2, &sem); + thread6.Close(); + iSurfaceManager.Close(); + } + +void CTSurfaceManagerMultiThread::TestAccessSurfaceOpenedClosedThreadL() + { + User::LeaveIfError(iSurfaceManager.Open()); + + // Setup attributes + RSurfaceManager::TSurfaceCreationAttributesBuf buf; + RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); + + attributes.iSize = TSize(480,16); + attributes.iBuffers = 2; // number of buffers in the surface + attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp + attributes.iStride = 1013; // Number of bytes between start of one line and start of next + attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data + attributes.iAlignment = RSurfaceManager::EPageAligned; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned + + RSurfaceManager::THintPair hints[2]; // two hint pairs specified + attributes.iHintCount = 2; + attributes.iSurfaceHints = hints; + hints[0].Set(TUid::Uid(0x124578), 25, ETrue); + hints[1].Set(TUid::Uid(0x237755), 50, ETrue); + + attributes.iContiguous = ETrue; + attributes.iCacheAttrib = RSurfaceManager::ECached; + attributes.iOffsetBetweenBuffers = 0; + attributes.iMappable = ETrue; + + // Test create surface doesn't return an error + TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId)); + // Logging info + INFO_PRINTF1(_L("Test accessing an surface which is already opened and closed in another thread, given that the process still owns the surface\r\n")); + // Create a semaphore + RSemaphore sem; + TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0)); + CleanupClosePushL(sem); + + // Creates a second thread in the current process and opens the handle + iInfo.iSurfaceManager = iSurfaceManager; + iInfo.iSurfaceId = iSurfaceId; + iInfo.iThreadTestCase = EOpenCloseSurface; + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo)); + + RThread thread7; + _LIT(KNameThreadSecond7, "Test_SurfaceManager_ThreadSecond7"); + User::LeaveIfError(thread7.Create(KNameThreadSecond7,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo)); + CleanupStack::Pop(); + + // Launch the second thread + TRequestStatus statusThreadSecond; + thread7.Logon(statusThreadSecond); + thread7.SetPriority(EPriorityLess); + thread7.Resume(); + testResult = EAllZero; + sem.Wait(); + + thread7.Suspend(); + // Test open and close surface in the second thread + TEST(testResult == (EOpenSurfaceTestPassed|ECloseSurfaceTestPassed)); + + RChunk handle; + // To prove killing threads doesnt affect the ref count... + TEST(KErrNone == iSurfaceManager.MapSurface(iSurfaceId, handle)); + handle.Close(); + + RSurfaceManager::TInfoBuf infoBuf; + TEST(KErrNone ==iSurfaceManager.SurfaceInfo(iSurfaceId, infoBuf)); + + thread7.Resume(); + + // Wait for a second for the second process to terminate + User::WaitForRequest(statusThreadSecond); + + // Close all the handles + CleanupStack::PopAndDestroy(1, &sem); + thread7.Close(); + iSurfaceManager.Close(); + } + +void CTSurfaceManagerMultiThread::TestCloseSurfaceOpenedClosedThreadL() + { + User::LeaveIfError(iSurfaceManager.Open()); + + // Setup attributes + RSurfaceManager::TSurfaceCreationAttributesBuf buf; + RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); + + attributes.iSize = TSize(480,16); + attributes.iBuffers = 2; // number of buffers in the surface + attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp + attributes.iStride = 1013; // Number of bytes between start of one line and start of next + attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data + attributes.iAlignment = RSurfaceManager::EPageAligned; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned + + RSurfaceManager::THintPair hints[2]; // two hint pairs specified + attributes.iHintCount = 2; + attributes.iSurfaceHints = hints; + hints[0].Set(TUid::Uid(0x124578), 25, ETrue); + hints[1].Set(TUid::Uid(0x237755), 50, ETrue); + + attributes.iContiguous = ETrue; + attributes.iCacheAttrib = RSurfaceManager::ECached; + attributes.iOffsetBetweenBuffers = 0; + attributes.iMappable = ETrue; + + // Test create surface doesn't return an error + TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId)); + + INFO_PRINTF1(_L("Test closing an surface which is already opened and closed in another thread, given that the process still owns the surface\r\n")); + RSemaphore sem; + TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0)); + CleanupClosePushL(sem); + + // Creates a second thread in the current process and opens the handle + iInfo.iSurfaceManager = iSurfaceManager; + iInfo.iSurfaceId = iSurfaceId; + iInfo.iThreadTestCase = EOpenCloseSurface; + + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo)); + + RThread thread8; + _LIT(KNameThreadSecond8, "Test_SurfaceManager_ThreadSecond8"); + User::LeaveIfError(thread8.Create(KNameThreadSecond8,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo)); + CleanupStack::Pop(); + TRequestStatus statusThreadSecond; + thread8.Logon(statusThreadSecond); + thread8.SetPriority(EPriorityLess); + thread8.Resume(); + testResult = EAllZero; + sem.Wait(); + thread8.Suspend(); + // Test open and close surface in the second thread + TEST(testResult == (EOpenSurfaceTestPassed|ECloseSurfaceTestPassed)); + + thread8.Resume(); + // Wait for a second for the second process to terminate + User::WaitForRequest(statusThreadSecond); + + // Close all the handles + CleanupStack::PopAndDestroy(1, &sem); + thread8.Close(); + iSurfaceManager.Close(); + } + +void CTSurfaceManagerMultiThread::TestAccessSurfaceOpenedKilledThreadL() + { + User::LeaveIfError(iSurfaceManager.Open()); + + // Setup attributes + RSurfaceManager::TSurfaceCreationAttributesBuf buf; + RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); + attributes.iSize = TSize(480,16); + attributes.iBuffers = 2; // number of buffers in the surface + attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp + attributes.iStride = 1013; // Number of bytes between start of one line and start of next + attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data + attributes.iAlignment = RSurfaceManager::EPageAligned; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned + + RSurfaceManager::THintPair hints[2]; // two hint pairs specified + attributes.iHintCount = 2; + attributes.iSurfaceHints = hints; + hints[0].Set(TUid::Uid(0x124578), 25, ETrue); + hints[1].Set(TUid::Uid(0x237755), 50, ETrue); + + attributes.iContiguous = ETrue; + attributes.iCacheAttrib = RSurfaceManager::ECached; + attributes.iOffsetBetweenBuffers = 0; + attributes.iMappable = ETrue; + + // Test create surface doesn't return an error + TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId)); + + INFO_PRINTF1(_L("Test accessing surface in another thread when the opening thread is killed\r\n")); + // Create a semaphore + RSemaphore sem; + TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0)); + CleanupClosePushL(sem); + + // Creates a second thread in the current process and opens the handle + iInfo.iSurfaceManager = iSurfaceManager; + iInfo.iSurfaceId = iSurfaceId; + iInfo.iThreadTestCase = EOpenKillSurface; + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo)); + + RThread thread9; + _LIT(KNameThreadSecond9, "Test_SurfaceManager_ThreadSecond9"); + User::LeaveIfError(thread9.Create(KNameThreadSecond9,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo)); + CleanupStack::Pop(); + // Launch the second thraed + TRequestStatus statusThreadSecond; + thread9.Logon(statusThreadSecond); + thread9.SetPriority(EPriorityLess); + thread9.Resume(); + // Waiting the second thread to terminate + User::WaitForRequest(statusThreadSecond); + + RChunk handle; + // Test the surface is still accessible + TEST(KErrNone == iSurfaceManager.MapSurface(iSurfaceId, handle)); + handle.Close(); + + RSurfaceManager::TInfoBuf infoBuf; + TEST(KErrNone ==iSurfaceManager.SurfaceInfo(iSurfaceId, infoBuf)); + + // Close all the handles + CleanupStack::PopAndDestroy(1, &sem); + thread9.Close(); + iSurfaceManager.Close(); + } + +void CTSurfaceManagerMultiThread::TestCloseSurfaceOpenedKilledThreadL() + { + User::LeaveIfError(iSurfaceManager.Open()); + + // Setup attributes + RSurfaceManager::TSurfaceCreationAttributesBuf buf; + RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); + attributes.iSize = TSize(480,16); + attributes.iBuffers = 2; // number of buffers in the surface + attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp + attributes.iStride = 1013; // Number of bytes between start of one line and start of next + attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data + attributes.iAlignment = RSurfaceManager::EPageAligned; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned + + RSurfaceManager::THintPair hints[2]; // two hint pairs specified + attributes.iHintCount = 2; + attributes.iSurfaceHints = hints; + hints[0].Set(TUid::Uid(0x124578), 25, ETrue); + hints[1].Set(TUid::Uid(0x237755), 50, ETrue); + + attributes.iContiguous = ETrue; + attributes.iCacheAttrib = RSurfaceManager::ECached; + attributes.iOffsetBetweenBuffers = 0; + attributes.iMappable = ETrue; + + // Create a semaphore + RSemaphore sem; + TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0)); + CleanupClosePushL(sem); + + // Test create surface doesn't return an error + TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId)); + // Logging info + INFO_PRINTF1(_L("Test closing surface in another thread when the opening thread is killed\r\n")); + // Creates a second thread in the current process and opens the handle + iInfo.iSurfaceManager = iSurfaceManager; + iInfo.iSurfaceId = iSurfaceId; + iInfo.iThreadTestCase = EOpenKillSurface; + + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo)); + + RThread thread10; + _LIT(KNameThreadSecond10, "Test_SurfaceManager_ThreadSecond10"); + User::LeaveIfError(thread10.Create(KNameThreadSecond10,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo)); + CleanupStack::Pop(); + // Launch the second thread + TRequestStatus statusThreadSecond; + thread10.Logon(statusThreadSecond); + thread10.SetPriority(EPriorityLess); + thread10.Resume(); + // Waiting the second thread to terminate + User::WaitForRequest(statusThreadSecond); + + // Test closing surface + TEST(KErrNone ==iSurfaceManager.CloseSurface(iSurfaceId)); + + // Close all the handles + CleanupStack::PopAndDestroy(1, &sem); + thread10.Close(); + iSurfaceManager.Close(); + } + +void CTSurfaceManagerMultiThread::TestAccessSurfaceCreateKilledThreadL() + { + User::LeaveIfError(iSurfaceManager.Open()); + + // Setup attributes + RSurfaceManager::TSurfaceCreationAttributesBuf buf; + RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); + attributes.iSize = TSize(480,16); + attributes.iBuffers = 2; // number of buffers in the surface + attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp + attributes.iStride = 1013; // Number of bytes between start of one line and start of next + attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data + attributes.iAlignment = RSurfaceManager::EPageAligned; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned + + RSurfaceManager::THintPair hints[2]; // two hint pairs specified + attributes.iHintCount = 2; + attributes.iSurfaceHints = hints; + hints[0].Set(TUid::Uid(0x124578), 25, ETrue); + hints[1].Set(TUid::Uid(0x237755), 50, ETrue); + + attributes.iContiguous = ETrue; + attributes.iCacheAttrib = RSurfaceManager::ECached; + attributes.iOffsetBetweenBuffers = 0; + attributes.iMappable = ETrue; + + // Logging info + INFO_PRINTF1(_L("Test accessing surface in another thread when the creating thread is killed\r\n")); + // Create a semaphore + RSemaphore sem; + TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0)); + CleanupClosePushL(sem); + + // Creates a second thread in the current process and opens the handle + iInfo.iSurfaceManager = iSurfaceManager; + iInfo.iSurfaceId = iSurfaceId; + iInfo.iThreadTestCase = ECreateKillSurface; + + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo)); + + RThread thread11; + _LIT(KNameThreadSecond11, "Test_SurfaceManager_ThreadSecond11"); + User::LeaveIfError(thread11.Create(KNameThreadSecond11,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo)); + CleanupStack::Pop(); + // Launch the second thread + TRequestStatus statusThreadSecond; + thread11.Logon(statusThreadSecond); + thread11.SetPriority(EPriorityLess); + thread11.Resume(); + testResult = EAllZero; + sem.Wait(); + // Test creating surface in the second thread + TEST(testResult = ECreateSurfaceTestPassed); + // Test closing surface + TEST(KErrNone == iSurfaceManager.CloseSurface(globalSurfaceId)); + // Wait the second thread to terminate + User::WaitForRequest(statusThreadSecond); + + // Test the surface is not accessible any more + RChunk handle; + TEST(KErrArgument == iSurfaceManager.MapSurface(globalSurfaceId, handle)); + handle.Close(); + RSurfaceManager::TInfoBuf infoBuf; + TEST(KErrArgument ==iSurfaceManager.SurfaceInfo(globalSurfaceId, infoBuf)); + // Close all the handles + CleanupStack::PopAndDestroy(1, &sem); + thread11.Close(); + iSurfaceManager.Close(); + } + +/** + 210 Test closing surface in another thread when the creating thread is killed + Thread 2: Create Surface + Thread 1: Close Surface + Thread 2: Kill the thread + Thread 1: Close Surface - KErrArgument +*/ +void CTSurfaceManagerMultiThread::TestCloseSurfaceCreateKilledThreadL() + { + User::LeaveIfError(iSurfaceManager.Open()); + + // Setup attributes + RSurfaceManager::TSurfaceCreationAttributesBuf buf; + RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); + attributes.iSize = TSize(480,16); + attributes.iBuffers = 2; // number of buffers in the surface + attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp + attributes.iStride = 1013; // Number of bytes between start of one line and start of next + attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data + attributes.iAlignment = RSurfaceManager::EPageAligned; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned + + RSurfaceManager::THintPair hints[2]; // two hint pairs specified + attributes.iHintCount = 2; + attributes.iSurfaceHints = hints; + hints[0].Set(TUid::Uid(0x124578), 25, ETrue); + hints[1].Set(TUid::Uid(0x237755), 50, ETrue); + + attributes.iContiguous = ETrue; + attributes.iCacheAttrib = RSurfaceManager::ECached; + attributes.iOffsetBetweenBuffers = 0; + attributes.iMappable = ETrue; + + // Logging info + INFO_PRINTF1(_L("Test closing surface in another thread when the creating thread is killed\r\n")); + // Create a semaphore + RSemaphore sem; + TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0)); + CleanupClosePushL(sem); + + // Creates a second thread in the current process and opens the handle + iInfo.iSurfaceManager = iSurfaceManager; + iInfo.iSurfaceId = iSurfaceId; + iInfo.iThreadTestCase = ECreateKillSurface; + + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo)); + + RThread thread12; + _LIT(KNameThreadSecond12, "Test_SurfaceManager_ThreadSecond12"); + User::LeaveIfError(thread12.Create(KNameThreadSecond12,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo)); + CleanupStack::Pop(); + // Launch the second thread + TRequestStatus statusThreadSecond; + thread12.Logon(statusThreadSecond); + thread12.SetPriority(EPriorityLess); + thread12.Resume(); + sem.Wait(); + // Test creating surface in the second thread + TEST(testResult = ECreateSurfaceTestPassed); + // Test closing surface + TEST(KErrNone == iSurfaceManager.CloseSurface(globalSurfaceId)); + // Wait the second thread to terminate + User::WaitForRequest(statusThreadSecond); + + // Test the surface is removed and not closable + TEST(KErrArgument ==iSurfaceManager.CloseSurface(globalSurfaceId)); + // Close the handles + CleanupStack::PopAndDestroy(1, &sem); + thread12.Close(); + iSurfaceManager.Close(); + } + +void CTSurfaceManagerMultiThread::TestAccessSurfaceThreeThreadsL() + { + User::LeaveIfError(iSurfaceManager.Open()); + + // Setup attributes + RSurfaceManager::TSurfaceCreationAttributesBuf buf; + RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); + attributes.iSize = TSize(480,16); + attributes.iBuffers = 2; // number of buffers in the surface + attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp + attributes.iStride = 1013; // Number of bytes between start of one line and start of next + attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data + attributes.iAlignment = RSurfaceManager::EPageAligned; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned + + RSurfaceManager::THintPair hints[2]; // two hint pairs specified + attributes.iHintCount = 2; + attributes.iSurfaceHints = hints; + hints[0].Set(TUid::Uid(0x124578), 25, ETrue); + hints[1].Set(TUid::Uid(0x237755), 50, ETrue); + + attributes.iContiguous = ETrue; + attributes.iCacheAttrib = RSurfaceManager::ECached; + attributes.iOffsetBetweenBuffers = 0; + attributes.iMappable = ETrue; + + // Test create surface doesn't return an error + TEST(KErrNone == iSurfaceManager.CreateSurface(buf, iSurfaceId)); + // Logging info + INFO_PRINTF1(_L("Test closing on one thread doesn't prevent opening on other Threads, provided one Thread still owns surface\r\n")); + // Create a semaphore + RSemaphore sem; + TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore,0)); + CleanupClosePushL(sem); + + // Creates a second thread in the current process and opens the handle + iInfo.iSurfaceManager = iSurfaceManager; + iInfo.iSurfaceId = iSurfaceId; + iInfo.iThreadTestCase = EOpenCloseSurfaceMultiThread; + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo)); + + RThread thread13; + _LIT(KNameThreadSecond13, "Test_SurfaceManager_ThreadSecond13"); + User::LeaveIfError(thread13.Create(KNameThreadSecond13,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo)); + CleanupStack::Pop(); + // Launch the second thread + TRequestStatus statusThreadSecond; + thread13.Logon(statusThreadSecond); + thread13.SetPriority(EPriorityLess); + thread13.Resume(); + testResult = EAllZero; + sem.Wait(); + TEST(testResult == EOpenSurfaceTestPassed); + testResult = EAllZero; + + // Create a third thread in the same process and opens the handle + iInfo2 = iInfo; + iInfo2.iThreadTestCase = EOpenMapSurfaceInfoMultiThread; + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); + + RThread thread13_2; + _LIT(KNameThreadSecond13_2, "Test_SurfaceManager_ThreadSecond13_2"); + User::LeaveIfError(thread13_2.Create(KNameThreadSecond13_2,ThreadThirdStart, KDefaultStackSize, &User::Heap(), &iInfo2)); + CleanupStack::Pop(); + // Launch the third thread + TRequestStatus statusThreadThird; + thread13_2.Logon(statusThreadThird); + thread13_2.SetPriority(EPriorityLess); + thread13_2.Resume(); + sem.Wait(); + TEST(testResult == EOpenSurfaceTestPassed); + testResult = EAllZero; + thread13.Resume(); + User::WaitForRequest(statusThreadSecond); + + TEST(testResult == ECloseSurfaceTestPassed); + testResult = EAllZero; + + thread13_2.Resume(); + User::WaitForRequest(statusThreadThird); + + TEST(testResult == (EMapSurfaceTestPassed|ESurfaceInfoTestPassed)); + + // Close all the handles + CleanupStack::PopAndDestroy(1, &sem); + + thread13.Close(); + thread13_2.Close(); + iSurfaceManager.Close(); + } + +void CTSurfaceManagerMultiThread::TestAccessSurfaceDieCloseOtherThreadsL() + { + User::LeaveIfError(iSurfaceManager.Open()); + + // Logging info + INFO_PRINTF1(_L("Test surface can be accessed from third thread when creating thread dies and second thread closes\r\n")); + // Create a semaphore + RSemaphore sem; + TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0)); + CleanupClosePushL(sem); + + // Create a second thread and opens the handle + iInfo.iSurfaceManager = iSurfaceManager; + iInfo.iSurfaceId = iSurfaceId; + iInfo.iThreadTestCase = ECreateKillSurface; + + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo)); + + RThread thread14; + _LIT(KNameThreadSecond14, "Test_SurfaceManager_ThreadSecond14"); + User::LeaveIfError(thread14.Create(KNameThreadSecond14,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo)); + CleanupStack::Pop(); + // Launch the second thread + TRequestStatus statusThreadSecond; + thread14.Logon(statusThreadSecond); + thread14.SetPriority(EPriorityLess); + thread14.Resume(); + testResult = EAllZero; + sem.Wait(); + //suspend the 2nd thread + thread14.Suspend(); + + TEST(testResult == ECreateSurfaceTestPassed); + testResult = EAllZero; + + TEST(KErrNone == iSurfaceManager.OpenSurface(globalSurfaceId)); + + // Create a third thread in the current process and opens the handle + iInfo2.iSurfaceManager = iSurfaceManager; + iInfo2.iSurfaceId = globalSurfaceId; + iInfo2.iSurfaceIdNew = iSurfaceId; + iInfo2.iThreadTestCase = EOpenCloseMapSurfaceInfoMultiThread; + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); + + RThread thread14_2; + _LIT(KNameThreadSecond14_2, "Test_SurfaceManager_ThreadSecond14_2"); + User::LeaveIfError(thread14_2.Create(KNameThreadSecond14_2,ThreadThirdStart, KDefaultStackSize, &User::Heap(), &iInfo2)); + CleanupStack::Pop(); + // Launch the third thread + TRequestStatus statusThreadThird; + thread14_2.Logon(statusThreadThird); + thread14_2.SetPriority(EPriorityLess); + thread14_2.Resume(); + sem.Wait(); + // Test opening the surface in the second thread + TEST(testResult == EOpenSurfaceTestPassed); + testResult = EAllZero; + // Test closing the surface in the main thread + TEST(KErrNone == iSurfaceManager.CloseSurface(globalSurfaceId)); + + thread14.Resume(); + User::WaitForRequest(statusThreadSecond); + + thread14_2.Resume(); + User::WaitForRequest(statusThreadThird); + + // Test the execution results in the third thread + TEST(testResult == (ECloseSurfaceTestPassed|EMapSurfaceTestPassed|ESurfaceInfoTestPassed)); + + // Close all the handles + CleanupStack::PopAndDestroy(1, &sem); + thread14.Close(); + thread14_2.Close(); + iSurfaceManager.Close(); + + } + +void CTSurfaceManagerMultiThread::TestOpenSurfaceDieCloseOtherThreadsL() + { + User::LeaveIfError(iSurfaceManager.Open()); + + // Setup attributes + RSurfaceManager::TSurfaceCreationAttributesBuf buf; + RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); + attributes.iSize = TSize(480,16); + attributes.iBuffers = 2; // number of buffers in the surface + attributes.iPixelFormat = EUidPixelFormatYUV_422Reversed; // 2bpp + attributes.iStride = 1013; // Number of bytes between start of one line and start of next + attributes.iOffsetToFirstBuffer = 0; // way of reserving space before the surface pixel data + attributes.iAlignment = RSurfaceManager::EPageAligned; // alignment, 1,2,4,8,16,32,64 byte aligned or EPageAligned + + RSurfaceManager::THintPair hints[2]; // two hint pairs specified + attributes.iHintCount = 2; + attributes.iSurfaceHints = hints; + hints[0].Set(TUid::Uid(0x124578), 25, ETrue); + hints[1].Set(TUid::Uid(0x237755), 50, ETrue); + + attributes.iContiguous = ETrue; + attributes.iCacheAttrib = RSurfaceManager::ECached; + attributes.iOffsetBetweenBuffers = 0; + attributes.iMappable = ETrue; + + // Logging info + INFO_PRINTF1(_L("Test that the surface can be opened from the third Thread after creating thread dies and second and third thread close the surface\r\n")); + // Create a semaphore + RSemaphore sem; + TEST(KErrNone == sem.CreateGlobal(KMultiThreadSemaphore, 0)); + CleanupClosePushL(sem); + + // Create a second thread and opens the handle + iInfo.iSurfaceManager = iSurfaceManager; + iInfo.iSurfaceId = iSurfaceId; + iInfo.iThreadTestCase = ECreateKillSurface; + + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo)); + RThread thread15; + _LIT(KNameThreadSecond15, "Test_SurfaceManager_ThreadSecond15"); + User::LeaveIfError(thread15.Create(KNameThreadSecond15,ThreadSecondStart, KDefaultStackSize, &User::Heap(), &iInfo)); + CleanupStack::Pop(); + // Launch the second thread + TRequestStatus statusThreadSecond; + thread15.Logon(statusThreadSecond); + thread15.SetPriority(EPriorityLess); + thread15.Resume(); + testResult = EAllZero; + sem.Wait(); + + thread15.Suspend(); //suspend the 2nd thread + + TEST(testResult == ECreateSurfaceTestPassed); + testResult = EAllZero; + // Test creating the surface in the second thread + TEST(KErrNone == iSurfaceManager.OpenSurface(globalSurfaceId)); + + // Create a third thread and opens the handle + iInfo2.iSurfaceManager = iSurfaceManager; + iInfo2.iSurfaceId = globalSurfaceId; + iInfo2.iSurfaceIdNew = iSurfaceId; + iInfo2.iThreadTestCase = EOpenCloseOpenMultiThread; + + // Create a TCleanupItem object + CleanupStack::PushL(TCleanupItem((TCleanupOperation)CloseSurfaceWhenLeave, &iInfo2)); + RThread thread15_2; + _LIT(KNameThreadSecond15_2, "Test_SurfaceManager_ThreadSecond15_2"); + User::LeaveIfError(thread15_2.Create(KNameThreadSecond15_2,ThreadThirdStart, KDefaultStackSize, &User::Heap(), &iInfo2)); + CleanupStack::Pop(); + // Launch the third thread + TRequestStatus statusThreadThird; + thread15_2.Logon(statusThreadThird); + thread15_2.SetPriority(EPriorityLess); + thread15_2.Resume(); + sem.Wait(); + // Test opening the surface in the third thread + TEST(testResult == EOpenSurfaceTestPassed); + // Test closing the surface in the main thread + TEST(KErrNone == iSurfaceManager.CloseSurface(globalSurfaceId)); + thread15.Resume(); + User::WaitForRequest(statusThreadSecond); + + thread15_2.Resume(); + User::WaitForRequest(statusThreadThird); + + // Test the surface is still accessible in the third thread + TEST(testResult == (ECloseSurfaceTestPassed | EOpenSurfaceTestPassed)); + // Close the handles + CleanupStack::PopAndDestroy(1, &sem); + thread15.Close(); + thread15_2.Close(); + iSurfaceManager.Close(); + + } + + +/** +The second thread entry point +*/ +TInt CTSurfaceManagerMultiThread::ThreadSecondStart(TAny* aInfo) + { + TInt procHandles1 =0; + TInt threadHandles1=0; + RThread().HandleCount(procHandles1, threadHandles1); + __UHEAP_MARK; + + CChildThreadWrapper* newThread = new CChildThreadWrapper(aInfo); + if (newThread==NULL) + { + return KErrNoMemory; + } + + RSemaphore sem; + RSemaphore semMain; + TInt ret = sem.OpenGlobal(KMultiThreadSemaphore); + if (ret == KErrNone) + { + TThreadTestCase testCase = newThread->iThreadTestCase; + switch (testCase) + { + case ECreateSurfaceMapInfo: + User::LeaveIfError(semMain.OpenGlobal(KMainThreadSemaphore)); + newThread->CreateSurfaceThread(); + sem.Signal(); + semMain.Wait(); + newThread->MapSurfaceInfo(); + delete newThread; + semMain.Close(); + break; + case ECreateSurfaceClose: + User::LeaveIfError(semMain.OpenGlobal(KMainThreadSemaphore)); + newThread->CreateSurfaceThread(); + sem.Signal(); + semMain.Wait(); + newThread->CloseSurface(); + delete newThread; + semMain.Close(); + break; + case EMapSurfaceInfo: + newThread->MapSurfaceInfo(); + sem.Signal(); + delete newThread; + break; + case ECloseSurfaces: + newThread->CloseSurface(); + sem.Signal(); + delete newThread; + break; + case EOpenCloseSurface: + newThread->OpenSurface(); + newThread->CloseSurface(); + sem.Signal(); + delete newThread; + break; + case EOpenKillSurface: + newThread->OpenSurface(); + delete newThread; + sem.Close(); + RThread().Kill(ret); + break; + case ECreateKillSurface: + newThread->CreateSurfaceThread(); + sem.Signal(); + delete newThread; + sem.Close(); + RThread().Kill(ret); + break; + case EOpenCloseSurfaceMultiThread: + newThread->OpenSurface(); + sem.Signal(); + RThread().Suspend(); + newThread->CloseSurface(); + delete newThread; + sem.Close(); + return ret; + case ECloseBothSurfaces: + newThread->CloseBothSurfaces(); + sem.Signal(); + delete newThread; + break; + default: + break; + } + + } + + __UHEAP_MARKEND; + + sem.Close(); + TInt procHandles2 =0; + TInt threadHandles2=0; + RThread().HandleCount(procHandles2,threadHandles2); + if (threadHandles1 != threadHandles2) + { + ret = KErrGeneral; // Thread-owned handles not closed + } + + return ret; + } + +// Implementation of CChildThreadWrapper class +CChildThreadWrapper::CChildThreadWrapper(TAny* aInfo) : + iSurfaceManager (((TInfo*)aInfo)->iSurfaceManager), + iSurfaceId(((TInfo*)aInfo)->iSurfaceId), + iSurfaceIdNew(((TInfo*)aInfo)->iSurfaceIdNew), + iThreadTestCase(((TInfo*)aInfo)->iThreadTestCase) + { + } + +CChildThreadWrapper::~CChildThreadWrapper() + { + } + +void CChildThreadWrapper::CreateSurfaceThread() + { + // Setup attributes + RSurfaceManager::TSurfaceCreationAttributesBuf buf; + RSurfaceManager::TSurfaceCreationAttributes& attributes = buf(); + + attributes.iSize = TSize(200,200); + attributes.iBuffers = 1; + attributes.iPixelFormat = EUidPixelFormatARGB_1555; + attributes.iStride = 1024; + attributes.iOffsetToFirstBuffer = 80; + attributes.iAlignment = 8; + attributes.iContiguous=ETrue; + + RSurfaceManager::THintPair hints[2]; // two hint pairs specified + attributes.iHintCount = 2; + attributes.iSurfaceHints = hints; + hints[0].Set(TUid::Uid(0x124578), 25, ETrue); + hints[1].Set(TUid::Uid(0x237755), 50, ETrue); + + attributes.iCacheAttrib = RSurfaceManager::ECached; + attributes.iOffsetBetweenBuffers = 0; + attributes.iMappable = ETrue; + + if (KErrNone == iSurfaceManager.CreateSurface(buf,iSurfaceId)) + { + testResult |= ECreateSurfaceTestPassed; + } + else + { + testResult |= ECreateSurfaceTestFailed; + } + + // record the surfaceId as a global variable + globalSurfaceId = iSurfaceId; + } + +void CChildThreadWrapper::MapSurfaceInfo() + { + // Access the surface and pass back the test results to the main thread + RChunk handle; + // Call Map Surface + if (iSurfaceManager.MapSurface(iSurfaceId,handle)== KErrNone) + { + testResult |= EMapSurfaceTestPassed; + } + else + { + testResult |= EMapSurfaceTestFailed; + } + handle.Close(); + + RSurfaceManager::TInfoBuf infoBuf; + // Call Surface Info + if (iSurfaceManager.SurfaceInfo(iSurfaceId, infoBuf) == KErrNone) + { + testResult |= ESurfaceInfoTestPassed; + } + else + { + testResult |= ESurfaceInfoTestFailed; + } + } + +void CChildThreadWrapper::CloseSurface() + { + // Call close surface and pass back the results to the main thread + if (iSurfaceManager.CloseSurface(iSurfaceId) == KErrNone) + { + testResult |= ECloseSurfaceTestPassed; + } + else + { + testResult |= ECloseSurfaceTestFailed; + } + } + +void CChildThreadWrapper::OpenSurface() + { + // Call close surface and pass back the results to the main thread + if (iSurfaceManager.OpenSurface(iSurfaceId) == KErrNone) + { + testResult |= EOpenSurfaceTestPassed; + } + else + { + testResult |= EOpenSurfaceTestFailed; + } + } + +void CChildThreadWrapper::CloseBothSurfaces() + { + // Call close surface and pass back the results to the main thread + if (iSurfaceManager.CloseSurface(iSurfaceIdNew) == KErrNone) + { + testResult |= ECloseSurfaceTestPassed; + } + else + { + testResult |= ECloseSurfaceTestFailed; + } + RSurfaceManager::TInfoBuf infoBuf; + // Call Surface Info + if (iSurfaceManager.SurfaceInfo(iSurfaceId, infoBuf) == KErrNone) + { + testResult |= ESurfaceInfoTestPassed; + } + else + { + testResult |= ESurfaceInfoTestFailed; + } + + if (iSurfaceManager.SurfaceInfo(iSurfaceIdNew, infoBuf) == KErrArgument) + { + testResult |= ESurfaceInfoTestPassed2; + } + else + { + testResult |= ESurfaceInfoTestFailed2; + } + iSurfaceManager.CloseSurface(iSurfaceId); + } +/** +The third thread entry point +*/ +TInt CTSurfaceManagerMultiThread::ThreadThirdStart(TAny* aInfo) + { + TInt procHandles1 =0; + TInt threadHandles1=0; + RThread().HandleCount(procHandles1, threadHandles1); + __UHEAP_MARK; + CTrapCleanup* cleanupStack=CTrapCleanup::New(); + if (cleanupStack==NULL) + { + return KErrNoMemory; + } + + CChildThreadWrapper* newThread = new CChildThreadWrapper(aInfo); + if (newThread==NULL) + { + delete cleanupStack; + return KErrNoMemory; + } + + // Pass control back to the first process + RSemaphore sem; + TInt ret = sem.OpenGlobal(KMultiThreadSemaphore); + if (ret!=KErrNone) + return ret; + + TInt err = KErrNone; + TThreadTestCase testCase = newThread->iThreadTestCase; + switch (testCase) + { + case EOpenMapSurfaceInfoMultiThread: + newThread->OpenSurface(); + sem.Signal(); + RThread().Suspend(); + newThread->MapSurfaceInfo(); + break; + case EOpenCloseMapSurfaceInfoMultiThread: + newThread->OpenSurface(); + sem.Signal(); + RThread().Suspend(); + newThread->CloseSurface(); + newThread->MapSurfaceInfo(); + break; + case EOpenCloseOpenMultiThread: + newThread->OpenSurface(); + sem.Signal(); + RThread().Suspend(); + newThread->CloseSurface(); + newThread->OpenSurface(); + break; + default: + break; + } + + delete newThread; + delete cleanupStack; + __UHEAP_MARKEND; + + sem.Close(); + TInt procHandles2 =0; + TInt threadHandles2=0; + RThread().HandleCount(procHandles2,threadHandles2); + if (threadHandles1 != threadHandles2) + { + err = KErrGeneral; // Thread-owned handles not closed + } + + return err; + } + + + +//-------------- +__CONSTRUCT_STEP__(SurfaceManagerMultiThread) + +void CTSurfaceManagerMultiThreadStep::TestSetupL() + { + } + +void CTSurfaceManagerMultiThreadStep::TestClose() + { + }