void * MultiLockUnsafeThread( void * p )
{

    const unsigned int value = reinterpret_cast< unsigned int >( p );
    Thing * thing = nullptr;
    unsigned int jj = 0;
    unsigned int tests = 0;
    unsigned int fails = 0;
    unsigned int randomIndex = 0;
    try
    {
        for ( unsigned int ii = 0; ii < thingCount; ++ii )
        {
            for ( jj = 0; jj < thingCount; ++jj )
            {
                thing = const_cast< Thing * >( Thing::GetFromPool( jj ) );
                assert( nullptr != thing );
                thing->SetValue( value );
            }
            ::GoToSleep( 2 );

            if ( WillRedoSingleTests() )
            {
                SingleThreadSimpleTest();
                SingleThreadReentrantTest();
                SingleThreadSimpleMultiLockTest();
                SingleThreadComplexMultiLockTest( false );
                SingleThreadExceptionTest();
            }

            thing = const_cast< Thing * >( Thing::GetFromPool( ii ) );
            assert( nullptr != thing );
            thing->Print( value, ii, 7 );
            randomIndex = ( ::rand() % thingCount );
            thing = const_cast< Thing * >( Thing::GetFromPool( randomIndex ) );
            assert( nullptr != thing );
            thing->Print( value, ii, 7 );

            for ( jj = 0; jj < thingCount; ++jj )
            {
                thing = const_cast< Thing * >( Thing::GetFromPool( jj ) );
                assert( nullptr != thing );
                if ( thing->GetValue() != value )
                    fails++;
                tests++;
            }

            ::GoToSleep( 2 );
        }
    }
    catch ( ... )
    {
        assert( false );
    }

    TestResults::GetIt()->SetResult( value, tests, fails );

    return nullptr;
}
void * MultiLockRandomUnsafeThread( void * p )
{
    const unsigned int value = reinterpret_cast< unsigned int >( p );
    unsigned int testCount = 0;
    unsigned int failCount = 0;
    Thing * thing = nullptr;
    UnsafeThingPool pool;

    unsigned int jj = 0;
    unsigned int place = 0;
    try
    {
        for ( unsigned int ii = 0; ii < thingCount; ++ii )
        {

            pool.clear();
            pool.reserve( thingCount );
            for ( place = 0; place < thingCount; ++place )
            {
                place += ::rand() % 3;
                if ( thingCount <= place )
                    break;
                thing = const_cast< Thing * >( Thing::GetFromPool( place ) );
                assert( nullptr != thing );
                pool.push_back( thing );
            }
            const unsigned int poolCount = pool.size();

            for ( jj = 0; jj < poolCount; ++jj )
            {
                thing = pool[ jj ];
                assert( nullptr != thing );
                thing->SetValue( value );
            }
            ::GoToSleep( 3 );

            for ( jj = 0; jj < poolCount; ++jj )
            {
                thing = pool[ jj ];
                assert( nullptr != thing );
                if ( thing->GetValue() != value )
                    failCount++;
                testCount++;
            }
        }
    }
    catch ( ... )
    {
        assert( false );
    }

    TestResults::GetIt()->SetResult( value, testCount, failCount );

    return nullptr;
}