1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/prime/t_rwlock.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,623 @@
1.4 +// Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\prime\t_rwlock.cpp
1.18 +// Overview:
1.19 +// Test the RReadWriteLock type.
1.20 +// API Information:
1.21 +// RReadWriteLock
1.22 +// Details:
1.23 +// Test all functions individually and in combination.
1.24 +// Platforms/Drives/Compatibility:
1.25 +// All.
1.26 +// Assumptions/Requirement/Pre-requisites:
1.27 +// Failures and causes:
1.28 +// Base Port information:
1.29 +//
1.30 +//
1.31 +
1.32 +//! @SYMTestCaseID KBASE-T_RWLOCK-2444
1.33 +//! @SYMTestType UT
1.34 +//! @SYMTestCaseDesc Verify correct operation of RReadWriteLock
1.35 +//! @SYMPREQ PREQ2094
1.36 +//! @SYMTestPriority High
1.37 +//! @SYMTestActions Call all functions of RReadWriteLock in a variety
1.38 +//! of circumstances and verify correct results
1.39 +//! @SYMTestExpectedResults All tests pass
1.40 +
1.41 +#include <e32atomics.h>
1.42 +#include <e32test.h>
1.43 +#include <e32panic.h>
1.44 +#include <e32def.h>
1.45 +#include <e32def_private.h>
1.46 +
1.47 +RTest Test(_L("T_RWLOCK"));
1.48 +RReadWriteLock TheLock;
1.49 +volatile TInt ThreadsRunning;
1.50 +TInt LogIndex;
1.51 +TBool LogReaders[20];
1.52 +
1.53 +// Check creating, using and closing a lock doesn't leak memory
1.54 +void TestCreation()
1.55 + {
1.56 + Test.Next(_L("Creation"));
1.57 +
1.58 + __KHEAP_MARK;
1.59 + __UHEAP_MARK;
1.60 +
1.61 + Test(TheLock.CreateLocal() == KErrNone);
1.62 + TheLock.ReadLock();
1.63 + TheLock.Unlock();
1.64 + TheLock.WriteLock();
1.65 + TheLock.Unlock();
1.66 + TheLock.Close();
1.67 +
1.68 + __UHEAP_MARKEND;
1.69 + __KHEAP_MARKEND;
1.70 + }
1.71 +
1.72 +TInt ReadEntryPoint(TAny* aArg)
1.73 + {
1.74 + *(TBool*)aArg = ETrue;
1.75 + __e32_atomic_add_ord32(&ThreadsRunning, 1);
1.76 + TheLock.ReadLock();
1.77 + const TInt index = __e32_atomic_add_ord32(&LogIndex, 1);
1.78 + LogReaders[index] = ETrue;
1.79 + TheLock.Unlock();
1.80 + __e32_atomic_add_ord32(&ThreadsRunning, TUint32(-1));
1.81 + return KErrNone;
1.82 + }
1.83 +
1.84 +TInt WriteEntryPoint(TAny* aArg)
1.85 + {
1.86 + *(TBool*)aArg = ETrue;
1.87 + __e32_atomic_add_ord32(&ThreadsRunning, 1);
1.88 + TheLock.WriteLock();
1.89 + const TInt index = __e32_atomic_add_ord32(&LogIndex, 1);
1.90 + LogReaders[index] = EFalse;
1.91 + TheLock.Unlock();
1.92 + __e32_atomic_add_ord32(&ThreadsRunning, TUint32(-1));
1.93 + return KErrNone;
1.94 + }
1.95 +
1.96 +void Init()
1.97 + {
1.98 + __e32_atomic_store_ord32(&ThreadsRunning, 0);
1.99 + __e32_atomic_store_ord32(&LogIndex, 0);
1.100 + }
1.101 +
1.102 +void CreateThread(TBool aReader)
1.103 + {
1.104 + RThread newThread;
1.105 + TBool threadStarted = EFalse;
1.106 + TInt ret = newThread.Create(KNullDesC, aReader ? ReadEntryPoint : WriteEntryPoint, KDefaultStackSize, KMinHeapSize, KMinHeapSize, &threadStarted, EOwnerProcess);
1.107 + Test(ret == KErrNone, __LINE__);
1.108 + newThread.SetPriority(EPriorityMore);
1.109 + newThread.Resume();
1.110 + while (!threadStarted)
1.111 + User::After(1000);
1.112 + newThread.Close();
1.113 + }
1.114 +
1.115 +void WaitForThreadsToClose(TInt aThreads = 0)
1.116 + {
1.117 + while (ThreadsRunning > aThreads)
1.118 + {
1.119 + User::After(1000);
1.120 + }
1.121 + }
1.122 +
1.123 +// Check that queuing multiple reads and writes on a lock with writer priority
1.124 +// results in the correct type of client being released in the correct order
1.125 +// (can' predict exact client order on multi-processor systems though)
1.126 +void TestWriterPriority()
1.127 + {
1.128 + Test.Next(_L("Writer Priority"));
1.129 + TInt ret = TheLock.CreateLocal(RReadWriteLock::EWriterPriority);
1.130 + Test(ret == KErrNone, __LINE__);
1.131 + TheLock.WriteLock();
1.132 +
1.133 + Init();
1.134 + CreateThread(ETrue);
1.135 + CreateThread(ETrue);
1.136 + CreateThread(EFalse);
1.137 + CreateThread(ETrue);
1.138 + CreateThread(EFalse);
1.139 + CreateThread(ETrue);
1.140 + CreateThread(EFalse);
1.141 + CreateThread(ETrue);
1.142 + CreateThread(EFalse);
1.143 + CreateThread(ETrue);
1.144 +
1.145 + TheLock.Unlock();
1.146 + WaitForThreadsToClose();
1.147 + TheLock.ReadLock();
1.148 +
1.149 + CreateThread(EFalse);
1.150 + CreateThread(ETrue);
1.151 + CreateThread(ETrue);
1.152 + CreateThread(EFalse);
1.153 + CreateThread(ETrue);
1.154 +
1.155 + TheLock.Unlock();
1.156 + WaitForThreadsToClose();
1.157 +
1.158 + TheLock.Close();
1.159 +
1.160 + Test(LogIndex == 15, __LINE__);
1.161 + const TBool expected[] = { EFalse, EFalse, EFalse, EFalse, ETrue, ETrue, ETrue, ETrue, ETrue, ETrue, EFalse, EFalse, ETrue, ETrue, ETrue };
1.162 + for (TInt index = 0; index < LogIndex; index++)
1.163 + {
1.164 + Test(LogReaders[index] == expected[index], __LINE__);
1.165 + }
1.166 + }
1.167 +
1.168 +// Check that queuing multiple reads and writes on a lock with alternate priority
1.169 +// results in the correct type of client being released in the correct order
1.170 +// (can' predict exact client order on multi-processor systems though)
1.171 +void TestAlternatePriority()
1.172 + {
1.173 + Test.Next(_L("Alternate Priority"));
1.174 + TInt ret = TheLock.CreateLocal(RReadWriteLock::EAlternatePriority);
1.175 + Test(ret == KErrNone, __LINE__);
1.176 + TheLock.WriteLock();
1.177 +
1.178 + Init();
1.179 + CreateThread(ETrue);
1.180 + CreateThread(ETrue);
1.181 + CreateThread(ETrue);
1.182 + CreateThread(ETrue);
1.183 + CreateThread(ETrue);
1.184 + CreateThread(EFalse);
1.185 + CreateThread(EFalse);
1.186 + CreateThread(EFalse);
1.187 + CreateThread(EFalse);
1.188 + CreateThread(EFalse);
1.189 +
1.190 + TheLock.Unlock();
1.191 + WaitForThreadsToClose();
1.192 + TheLock.ReadLock();
1.193 +
1.194 + CreateThread(EFalse);
1.195 + CreateThread(ETrue);
1.196 + CreateThread(ETrue);
1.197 + CreateThread(EFalse);
1.198 + CreateThread(ETrue);
1.199 +
1.200 + TheLock.Unlock();
1.201 + WaitForThreadsToClose();
1.202 +
1.203 + TheLock.Close();
1.204 +
1.205 + Test(LogIndex == 15, __LINE__);
1.206 + const TInt expected[] = { ETrue, EFalse, ETrue, EFalse, ETrue, EFalse, ETrue, EFalse, ETrue, EFalse, EFalse, ETrue, EFalse, ETrue, ETrue };
1.207 + for (TInt index = 0; index < LogIndex; index++)
1.208 + {
1.209 + Test(LogReaders[index] == expected[index], __LINE__);
1.210 + }
1.211 + }
1.212 +
1.213 +// Check that queuing multiple reads and writes on a lock with reader priority
1.214 +// results in the correct type of client being released in the correct order
1.215 +// (can' predict exact client order on multi-processor systems though)
1.216 +void TestReaderPriority()
1.217 + {
1.218 + Test.Next(_L("Reader Priority"));
1.219 + TInt ret = TheLock.CreateLocal(RReadWriteLock::EReaderPriority);
1.220 + Test(ret == KErrNone, __LINE__);
1.221 + TheLock.WriteLock();
1.222 +
1.223 + Init();
1.224 + CreateThread(ETrue);
1.225 + CreateThread(ETrue);
1.226 + CreateThread(EFalse);
1.227 + CreateThread(ETrue);
1.228 + CreateThread(EFalse);
1.229 + CreateThread(ETrue);
1.230 + CreateThread(EFalse);
1.231 + CreateThread(ETrue);
1.232 + CreateThread(EFalse);
1.233 + CreateThread(ETrue);
1.234 +
1.235 + TheLock.Unlock();
1.236 + WaitForThreadsToClose();
1.237 + TheLock.WriteLock();
1.238 +
1.239 + CreateThread(EFalse);
1.240 + CreateThread(ETrue);
1.241 + CreateThread(ETrue);
1.242 + CreateThread(EFalse);
1.243 + CreateThread(ETrue);
1.244 +
1.245 + TheLock.Unlock();
1.246 + WaitForThreadsToClose();
1.247 +
1.248 + TheLock.Close();
1.249 +
1.250 + Test(LogIndex == 15, __LINE__);
1.251 + const TInt expected[] = { ETrue, ETrue, ETrue, ETrue, ETrue, ETrue, EFalse, EFalse, EFalse, EFalse, ETrue, ETrue, ETrue, EFalse, EFalse };
1.252 + for (TInt index = 0; index < LogIndex; index++)
1.253 + {
1.254 + Test(LogReaders[index] == expected[index], __LINE__);
1.255 + }
1.256 + }
1.257 +
1.258 +void DoTestTryLock(TBool aWriterFirst)
1.259 + {
1.260 + TheLock.ReadLock();
1.261 +
1.262 + TBool tryLock = TheLock.TryWriteLock();
1.263 + Test(!tryLock, __LINE__);
1.264 +
1.265 + tryLock = TheLock.TryReadLock();
1.266 + Test(tryLock, __LINE__);
1.267 + TheLock.Unlock();
1.268 +
1.269 + Init();
1.270 + CreateThread(EFalse);
1.271 + tryLock = TheLock.TryReadLock();
1.272 + if (tryLock)
1.273 + {
1.274 + Test(!aWriterFirst, __LINE__);
1.275 + TheLock.Unlock();
1.276 + }
1.277 + else
1.278 + {
1.279 + Test(aWriterFirst, __LINE__);
1.280 + }
1.281 + tryLock = TheLock.TryWriteLock();
1.282 + Test(!tryLock, __LINE__);
1.283 +
1.284 + TheLock.Unlock();
1.285 + WaitForThreadsToClose();
1.286 +
1.287 + TheLock.WriteLock();
1.288 +
1.289 + tryLock = TheLock.TryReadLock();
1.290 + Test(!tryLock, __LINE__);
1.291 + tryLock = TheLock.TryWriteLock();
1.292 + Test(!tryLock, __LINE__);
1.293 +
1.294 + TheLock.Unlock();
1.295 + TheLock.Close();
1.296 + }
1.297 +
1.298 +// Check that the TryReadLock and TryWriteLock functions block only when they
1.299 +// should for the different types of priority
1.300 +void TestTryLock()
1.301 + {
1.302 + Test.Next(_L("Try Lock"));
1.303 +
1.304 + TInt ret = TheLock.CreateLocal(RReadWriteLock::EWriterPriority);
1.305 + Test(ret == KErrNone, __LINE__);
1.306 + DoTestTryLock(ETrue);
1.307 +
1.308 + ret = TheLock.CreateLocal(RReadWriteLock::EAlternatePriority);
1.309 + Test(ret == KErrNone, __LINE__);
1.310 + DoTestTryLock(ETrue);
1.311 +
1.312 + ret = TheLock.CreateLocal(RReadWriteLock::EReaderPriority);
1.313 + Test(ret == KErrNone, __LINE__);
1.314 + DoTestTryLock(EFalse);
1.315 +
1.316 + TheLock.Close();
1.317 + }
1.318 +
1.319 +void DoTestUpgrade(RReadWriteLock::TReadWriteLockPriority aPriority)
1.320 + {
1.321 + TInt ret = TheLock.CreateLocal(aPriority);
1.322 + Test(ret == KErrNone, __LINE__);
1.323 + TheLock.ReadLock();
1.324 +
1.325 + TBool success = TheLock.TryUpgradeReadLock();
1.326 + Test(success, __LINE__);
1.327 + TheLock.Unlock();
1.328 +
1.329 + TheLock.ReadLock();
1.330 + TheLock.ReadLock();
1.331 + success = TheLock.TryUpgradeReadLock();
1.332 + Test(!success, __LINE__);
1.333 + TheLock.Unlock();
1.334 + TheLock.Unlock();
1.335 +
1.336 + TheLock.ReadLock();
1.337 + Init();
1.338 + CreateThread(EFalse);
1.339 + success = TheLock.TryUpgradeReadLock();
1.340 + Test(success || !(aPriority == RReadWriteLock::EReaderPriority), __LINE__);
1.341 +
1.342 + TheLock.Unlock();
1.343 + WaitForThreadsToClose();
1.344 + TheLock.Close();
1.345 + }
1.346 +
1.347 +// Check that upgrading a lock succeeds only when it should
1.348 +void TestUpgrade()
1.349 + {
1.350 + Test.Next(_L("Upgrade Lock"));
1.351 +
1.352 + DoTestUpgrade(RReadWriteLock::EWriterPriority);
1.353 + DoTestUpgrade(RReadWriteLock::EAlternatePriority);
1.354 + DoTestUpgrade(RReadWriteLock::EReaderPriority);
1.355 + }
1.356 +
1.357 +void DoTestDowngrade(RReadWriteLock::TReadWriteLockPriority aPriority)
1.358 + {
1.359 + TInt ret = TheLock.CreateLocal(aPriority);
1.360 + Test(ret == KErrNone, __LINE__);
1.361 + TheLock.WriteLock();
1.362 +
1.363 + Init();
1.364 + CreateThread(ETrue);
1.365 + CreateThread(EFalse);
1.366 + CreateThread(ETrue);
1.367 + CreateThread(EFalse);
1.368 +
1.369 + TheLock.DowngradeWriteLock();
1.370 +
1.371 + switch (aPriority)
1.372 + {
1.373 + case RReadWriteLock::EWriterPriority:
1.374 + case RReadWriteLock::EAlternatePriority:
1.375 + {
1.376 + Test(LogIndex == 0, __LINE__);
1.377 + break;
1.378 + }
1.379 + case RReadWriteLock::EReaderPriority:
1.380 + {
1.381 + WaitForThreadsToClose(2);
1.382 + Test(LogIndex == 2, __LINE__);
1.383 + Test(LogReaders[0], __LINE__);
1.384 + Test(LogReaders[1], __LINE__);
1.385 + break;
1.386 + }
1.387 + };
1.388 +
1.389 + CreateThread(ETrue);
1.390 + CreateThread(EFalse);
1.391 + CreateThread(ETrue);
1.392 + CreateThread(EFalse);
1.393 +
1.394 + TheLock.Unlock();
1.395 + WaitForThreadsToClose();
1.396 + TheLock.Close();
1.397 +
1.398 + Test(LogIndex == 8, __LINE__);
1.399 +
1.400 + switch (aPriority)
1.401 + {
1.402 + case RReadWriteLock::EWriterPriority:
1.403 + {
1.404 + const TInt expected[] = { EFalse, EFalse, EFalse, EFalse, ETrue, ETrue, ETrue, ETrue };
1.405 + for (TInt index = 0; index < LogIndex; index++)
1.406 + {
1.407 + Test(LogReaders[index] == expected[index], __LINE__);
1.408 + }
1.409 + break;
1.410 + }
1.411 + case RReadWriteLock::EAlternatePriority:
1.412 + {
1.413 + const TInt expected[] = { EFalse, ETrue, EFalse, ETrue, EFalse, ETrue, EFalse, ETrue };
1.414 + for (TInt index = 0; index < LogIndex; index++)
1.415 + {
1.416 + Test(LogReaders[index] == expected[index], __LINE__);
1.417 + }
1.418 + break;
1.419 + }
1.420 + case RReadWriteLock::EReaderPriority:
1.421 + {
1.422 + const TInt expected[] = { ETrue, ETrue, ETrue, ETrue, EFalse, EFalse, EFalse, EFalse };
1.423 + for (TInt index = 0; index < LogIndex; index++)
1.424 + {
1.425 + Test(LogReaders[index] == expected[index], __LINE__);
1.426 + }
1.427 + break;
1.428 + }
1.429 + };
1.430 + }
1.431 +
1.432 +// Check that downgrading a lock succeeds only when it should
1.433 +void TestDowngrade()
1.434 + {
1.435 + Test.Next(_L("Downgrade Lock"));
1.436 +
1.437 + DoTestDowngrade(RReadWriteLock::EWriterPriority);
1.438 + DoTestDowngrade(RReadWriteLock::EAlternatePriority);
1.439 + DoTestDowngrade(RReadWriteLock::EReaderPriority);
1.440 + }
1.441 +
1.442 +TInt PanicEntryPoint(TAny* aArg)
1.443 + {
1.444 + switch (TInt(aArg))
1.445 + {
1.446 + case 0: // Check priority lower bound
1.447 + TheLock.CreateLocal(RReadWriteLock::TReadWriteLockPriority(RReadWriteLock::EWriterPriority-1));
1.448 + break;
1.449 + case 1: // Check priority upper bound
1.450 + TheLock.CreateLocal(RReadWriteLock::TReadWriteLockPriority(RReadWriteLock::EReaderPriority+1));
1.451 + break;
1.452 + case 2: // Check close while holding read lock
1.453 + TheLock.CreateLocal(RReadWriteLock::TReadWriteLockPriority(RReadWriteLock::EAlternatePriority));
1.454 + TheLock.ReadLock();
1.455 + TheLock.Close();
1.456 + break;
1.457 + case 3: // Check close while holding write lock
1.458 + TheLock.CreateLocal(RReadWriteLock::TReadWriteLockPriority(RReadWriteLock::EAlternatePriority));
1.459 + TheLock.WriteLock();
1.460 + TheLock.Close();
1.461 + break;
1.462 + case 4: // Check max readers
1.463 + TheLock.CreateLocal(RReadWriteLock::TReadWriteLockPriority(RReadWriteLock::EReaderPriority));
1.464 + {
1.465 + for (TInt count = 0; count < RReadWriteLock::EReadWriteLockClientCategoryLimit; count++)
1.466 + TheLock.ReadLock();
1.467 + }
1.468 + TheLock.ReadLock();
1.469 + break;
1.470 + case 5: // Check max pending readers
1.471 + TheLock.CreateLocal(RReadWriteLock::TReadWriteLockPriority(RReadWriteLock::EReaderPriority));
1.472 + TheLock.WriteLock();
1.473 + {
1.474 + TUint16* hackLock = (TUint16*)&TheLock;
1.475 + hackLock[2] = KMaxTUint16; // Hack readers pending field
1.476 + }
1.477 + TheLock.ReadLock();
1.478 + break;
1.479 + case 6: // Check max pending writers
1.480 + TheLock.CreateLocal(RReadWriteLock::TReadWriteLockPriority(RReadWriteLock::EReaderPriority));
1.481 + TheLock.ReadLock();
1.482 + {
1.483 + TUint16* hackLock = (TUint16*)&TheLock;
1.484 + hackLock[3] = KMaxTUint16; // Hack writers pending field
1.485 + }
1.486 + TheLock.WriteLock();
1.487 + break;
1.488 + case 7: // Check lock held when unlocking
1.489 + TheLock.CreateLocal(RReadWriteLock::TReadWriteLockPriority(RReadWriteLock::EAlternatePriority));
1.490 + TheLock.Unlock();
1.491 + break;
1.492 + case 8: // Check lock held when unlocking after read lock/unlock
1.493 + TheLock.CreateLocal(RReadWriteLock::TReadWriteLockPriority(RReadWriteLock::EAlternatePriority));
1.494 + TheLock.ReadLock();
1.495 + TheLock.Unlock();
1.496 + TheLock.Unlock();
1.497 + break;
1.498 + case 9: // Check lock held when unlocking after write lock/unlock
1.499 + TheLock.CreateLocal(RReadWriteLock::TReadWriteLockPriority(RReadWriteLock::EAlternatePriority));
1.500 + TheLock.WriteLock();
1.501 + TheLock.Unlock();
1.502 + TheLock.Unlock();
1.503 + break;
1.504 + default:
1.505 + return KErrNone;
1.506 + };
1.507 +
1.508 + return KErrNotSupported;
1.509 + }
1.510 +
1.511 +TBool CreatePanicThread(TInt aTest)
1.512 + {
1.513 + User::SetJustInTime(EFalse);
1.514 + TBool finished = EFalse;
1.515 +
1.516 + RThread panicThread;
1.517 + TInt ret = panicThread.Create(KNullDesC, PanicEntryPoint, KDefaultStackSize, KMinHeapSize, KMinHeapSize, (TAny*)aTest, EOwnerThread);
1.518 + Test(ret == KErrNone, __LINE__);
1.519 + panicThread.Resume();
1.520 +
1.521 + TRequestStatus stat;
1.522 + panicThread.Logon(stat);
1.523 + User::WaitForRequest(stat);
1.524 + User::SetJustInTime(ETrue);
1.525 +
1.526 + if (panicThread.ExitType() == EExitPanic)
1.527 + {
1.528 + TInt panicValue = 0;
1.529 + switch (aTest)
1.530 + {
1.531 + case 0:
1.532 + case 1:
1.533 + panicValue = EReadWriteLockInvalidPriority;
1.534 + break;
1.535 + case 2:
1.536 + case 3:
1.537 + panicValue = EReadWriteLockStillPending;
1.538 + break;
1.539 + case 4:
1.540 + case 5:
1.541 + case 6:
1.542 + panicValue = EReadWriteLockTooManyClients;
1.543 + break;
1.544 + case 7:
1.545 + case 8:
1.546 + case 9:
1.547 + panicValue = EReadWriteLockBadLockState;
1.548 + break;
1.549 + default:
1.550 + Test(0, __LINE__);
1.551 + break;
1.552 + };
1.553 +
1.554 + Test(stat == panicValue, __LINE__);
1.555 + Test(panicThread.ExitReason() == panicValue, __LINE__);
1.556 + }
1.557 + else
1.558 + {
1.559 + Test(stat == KErrNone, __LINE__);
1.560 + finished = ETrue;
1.561 + }
1.562 +
1.563 + RTest::CloseHandleAndWaitForDestruction(panicThread);
1.564 +
1.565 + switch (aTest)
1.566 + {
1.567 + case 2: // Check close while holding read lock
1.568 + case 3: // Check close while holding write lock
1.569 + TheLock.Unlock();
1.570 + TheLock.Close();
1.571 + break;
1.572 + case 4: // Check max readers
1.573 + {
1.574 + for (TInt count = 0; count < RReadWriteLock::EReadWriteLockClientCategoryLimit; count++)
1.575 + TheLock.Unlock();
1.576 + }
1.577 + TheLock.Close();
1.578 + break;
1.579 + case 5: // Check max pending readers
1.580 + case 6: // Check max pending writers
1.581 + {
1.582 + TUint16* hackLock = (TUint16*)&TheLock;
1.583 + hackLock[2] = 0; // Reset readers pending field
1.584 + hackLock[3] = 0; // Reset writers pending field
1.585 + }
1.586 + TheLock.Unlock();
1.587 + TheLock.Close();
1.588 + break;
1.589 + case 7: // Check lock held when unlocking
1.590 + case 8: // Check lock held when unlocking after read lock/unlock
1.591 + case 9: // Check lock held when unlocking after write lock/unlock
1.592 + TheLock.Close();
1.593 + break;
1.594 + default:
1.595 + break;
1.596 + };
1.597 + return finished;
1.598 + }
1.599 +
1.600 +// Check that the various asserts guarding invalid conditions can be reached
1.601 +void TestPanics()
1.602 + {
1.603 + Test.Next(_L("Panics"));
1.604 +
1.605 + for (TInt testIndex = 0; !CreatePanicThread(testIndex); testIndex++) ;
1.606 + }
1.607 +
1.608 +TInt E32Main()
1.609 + {
1.610 + Test.Title();
1.611 + Test.Start(_L("RReadWriteLock Testing"));
1.612 +
1.613 + TestCreation();
1.614 + TestWriterPriority();
1.615 + TestAlternatePriority();
1.616 + TestReaderPriority();
1.617 + TestTryLock();
1.618 + TestUpgrade();
1.619 + TestDowngrade();
1.620 + TestPanics();
1.621 +
1.622 + Test.End();
1.623 + return KErrNone;
1.624 + }
1.625 +
1.626 +