void testReclaimResourceNonSecure() {
        Vector<MediaResource> resources;
        resources.push_back(MediaResource(String8(kResourceNonSecureCodec), 1));
        resources.push_back(MediaResource(String8(kResourceGraphicMemory), 150));

        // ### secure codec can't coexist with non-secure codec ###
        {
            addResource();
            mService->mSupportsSecureWithNonSecureCodec = false;

            // priority too low
            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
            EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources));

            // reclaim all secure codecs
            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);

            // call again should reclaim one graphic memory from lowest process
            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);

            // nothing left
            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
        }


        // ### secure codec can coexist with non-secure codec ###
        {
            addResource();
            mService->mSupportsSecureWithNonSecureCodec = true;

            // priority too low
            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));

            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            // one largest graphic memory from lowest process got reclaimed
            verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);

            // call again should reclaim another graphic memory from lowest process
            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);

            // call again should reclaim another graphic memory from lowest process
            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);

            // nothing left
            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
        }

        // ### secure codec can coexist with non-secure codec ###
        {
            addResource();
            mService->mSupportsSecureWithNonSecureCodec = true;

            Vector<MediaResource> resources;
            resources.push_back(MediaResource(String8(kResourceNonSecureCodec), 1));

            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            // one non secure codec from lowest process got reclaimed
            verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);

            // no more non-secure codec, secure codec from lowest priority process will be reclaimed
            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);

            // clean up client 3 which still left
            mService->removeResource(kTestPid2, getId(mTestClient3));
        }
    }
Пример #2
0
/*
 * register_new_client()
 */
static void register_new_client ( osiSockAddr & from, 
            tsFreeList < repeaterClient, 0x20 > & freeList )
{
    bool newClient = false;
    int status;

    if ( from.sa.sa_family != AF_INET ) {
        return;
    }

    /*
     * the repeater and its clients must be on the same host
     */
    if ( INADDR_LOOPBACK != ntohl ( from.ia.sin_addr.s_addr ) ) {
        static SOCKET testSock = INVALID_SOCKET;
        static bool init = false;

        if ( ! init ) {
            SOCKET sock;
            if ( ! makeSocket ( PORT_ANY, true, & sock ) ) {
                char sockErrBuf[64];
                epicsSocketConvertErrnoToString ( 
                    sockErrBuf, sizeof ( sockErrBuf ) );
                fprintf ( stderr, "%s: Unable to create repeater bind test socket because \"%s\"\n",
                    __FILE__, sockErrBuf );
            }
            else {
                testSock = sock;
            }
            init = true;
        }

        /*
         * Unfortunately on 3.13 beta 11 and before the
         * repeater would not always allow the loopback address
         * as a local client address so current clients alternate
         * between the address of the first non-loopback interface
         * found and the loopback addresss when subscribing with 
         * the CA repeater until all CA repeaters have been updated
         * to current code.
         */
        if ( testSock != INVALID_SOCKET ) {
            osiSockAddr addr;

            addr = from;
            addr.ia.sin_port = PORT_ANY;

            /* we can only bind to a local address */
            status = bind ( testSock, &addr.sa, sizeof ( addr ) );
            if ( status ) {
                return;
            }
        }
        else {
            return;
        }
    }

    tsDLIter < repeaterClient > pclient = client_list.firstIter ();
    while ( pclient.valid () ) {
        if ( pclient->identicalPort ( from ) ) {
            break;
        }
        pclient++;
    }      
    
    repeaterClient *pNewClient;
    if ( pclient.valid () ) {
        pNewClient = pclient.pointer ();
    }
    else {
        pNewClient = new ( freeList ) repeaterClient ( from );
        if ( ! pNewClient ) {
            fprintf ( stderr, "%s: no memory for new client\n", __FILE__ );
            return;
        }
        if ( ! pNewClient->connect () ) {
            pNewClient->~repeaterClient ();
            freeList.release ( pNewClient );
            return;
        }
        client_list.add ( *pNewClient ); 
        newClient = true;
    }

    if ( ! pNewClient->sendConfirm () ) {
        client_list.remove ( *pNewClient );
        pNewClient->~repeaterClient ();
        freeList.release ( pNewClient );
#       ifdef DEBUG
            epicsUInt16 port = ntohs ( from.ia.sin_port );
            debugPrintf ( ( "Deleted repeater client=%u (error while sending ack)\n",
                        port ) );
#       endif
    }

    /*
     * send a noop message to all other clients so that we dont 
     * accumulate sockets when there are no beacons
     */
    caHdr noop;
    memset ( (char *) &noop, '\0', sizeof ( noop ) );
    AlignedWireRef < epicsUInt16 > ( noop.m_cmmd ) = CA_PROTO_VERSION;
    fanOut ( from, &noop, sizeof ( noop ), freeList );

    if ( newClient ) {
        /*
         * For HPUX and Solaris we need to verify that the clients
         * have not gone away - because an ICMP error return does not
         * get through to send(), which returns no error code.
         *
         * This is done each time that a new client is created.
         * See also the note in the file header.
         *
         * This is done here in order to avoid deleting a client
         * prior to sending its confirm message.
         */
        verifyClients ( freeList );
    }
}
    void testReclaimResourceSecure() {
        Vector<MediaResource> resources;
        resources.push_back(MediaResource(String8(kResourceSecureCodec), 1));
        resources.push_back(MediaResource(String8(kResourceGraphicMemory), 150));

        // ### secure codec can't coexist and secure codec can coexist with non-secure codec ###
        {
            addResource();
            mService->mSupportsMultipleSecureCodecs = false;
            mService->mSupportsSecureWithNonSecureCodec = true;

            // priority too low
            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
            EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources));

            // reclaim all secure codecs
            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            verifyClients(true /* c1 */, false /* c2 */, true /* c3 */);

            // call again should reclaim one largest graphic memory from lowest process
            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);

            // nothing left
            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
        }

        // ### secure codecs can't coexist and secure codec can't coexist with non-secure codec ###
        {
            addResource();
            mService->mSupportsMultipleSecureCodecs = false;
            mService->mSupportsSecureWithNonSecureCodec = false;

            // priority too low
            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
            EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources));

            // reclaim all secure and non-secure codecs
            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            verifyClients(true /* c1 */, true /* c2 */, true /* c3 */);

            // nothing left
            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
        }


        // ### secure codecs can coexist but secure codec can't coexist with non-secure codec ###
        {
            addResource();
            mService->mSupportsMultipleSecureCodecs = true;
            mService->mSupportsSecureWithNonSecureCodec = false;

            // priority too low
            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));
            EXPECT_FALSE(mService->reclaimResource(kMidPriorityPid, resources));

            // reclaim all non-secure codecs
            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);

            // call again should reclaim one largest graphic memory from lowest process
            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);

            // call again should reclaim another largest graphic memory from lowest process
            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);

            // nothing left
            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
        }

        // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
        {
            addResource();
            mService->mSupportsMultipleSecureCodecs = true;
            mService->mSupportsSecureWithNonSecureCodec = true;

            // priority too low
            EXPECT_FALSE(mService->reclaimResource(kLowPriorityPid, resources));

            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            // one largest graphic memory from lowest process got reclaimed
            verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);

            // call again should reclaim another graphic memory from lowest process
            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);

            // call again should reclaim another graphic memory from lowest process
            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);

            // nothing left
            EXPECT_FALSE(mService->reclaimResource(kHighPriorityPid, resources));
        }

        // ### secure codecs can coexist and secure codec can coexist with non-secure codec ###
        {
            addResource();
            mService->mSupportsMultipleSecureCodecs = true;
            mService->mSupportsSecureWithNonSecureCodec = true;

            Vector<MediaResource> resources;
            resources.push_back(MediaResource(String8(kResourceSecureCodec), 1));

            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            // secure codec from lowest process got reclaimed
            verifyClients(true /* c1 */, false /* c2 */, false /* c3 */);

            // call again should reclaim another secure codec from lowest process
            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            verifyClients(false /* c1 */, false /* c2 */, true /* c3 */);

            // no more secure codec, non-secure codec will be reclaimed.
            EXPECT_TRUE(mService->reclaimResource(kHighPriorityPid, resources));
            verifyClients(false /* c1 */, true /* c2 */, false /* c3 */);
        }
    }