예제 #1
0
GLint PACKSPU_APIENTRY packspu_VBoxPackSetInjectThread(struct VBOXUHGSMI *pHgsmi)
{
    GLint con = 0;
    int i;
    GET_THREAD(thread);
    CRASSERT(!thread);
    crLockMutex(&_PackMutex);
    {
        CRASSERT(CRPACKSPU_IS_WDDM_CRHGSMI() || (pack_spu.numThreads>0));
        CRASSERT(pack_spu.numThreads<MAX_THREADS);
        for (i=0; i<MAX_THREADS; ++i)
        {
            if (!pack_spu.thread[i].inUse)
            {
                thread = &pack_spu.thread[i];
                break;
            }
        }
        CRASSERT(thread);

        thread->inUse = GL_TRUE;
        if (!CRPACKSPU_IS_WDDM_CRHGSMI())
            thread->id = crThreadID();
        else
            thread->id = THREAD_OFFSET_MAGIC + i;
        thread->currentContext = NULL;
        thread->bInjectThread = GL_TRUE;

        thread->netServer.name = crStrdup(pack_spu.name);
        thread->netServer.buffer_size = 64 * 1024;

        packspuConnectToServer(&(thread->netServer)
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
                , pHgsmi
#endif
        );
        CRASSERT(thread->netServer.conn);

        CRASSERT(thread->packer == NULL);
        thread->packer = crPackNewContext( pack_spu.swap );
        CRASSERT(thread->packer);
        crPackInitBuffer(&(thread->buffer), crNetAlloc(thread->netServer.conn),
                         thread->netServer.conn->buffer_size, thread->netServer.conn->mtu);
        thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE;

        crPackSetBuffer( thread->packer, &thread->buffer );
        crPackFlushFunc( thread->packer, packspuFlush );
        crPackFlushArg( thread->packer, (void *) thread );
        crPackSendHugeFunc( thread->packer, packspuHuge );
        crPackSetContext( thread->packer );

        crSetTSD(&_PackTSD, thread);

        pack_spu.numThreads++;
    }
    crUnlockMutex(&_PackMutex);

    if (CRPACKSPU_IS_WDDM_CRHGSMI())
    {
        CRASSERT(thread->id - THREAD_OFFSET_MAGIC < RT_ELEMENTS(pack_spu.thread)
                && GET_THREAD_VAL_ID(thread->id) == thread);
        con = thread->id;
    }
    return con;
}
예제 #2
0
/*
 * Allocate a new ThreadInfo structure, setup a connection to the
 * server, allocate/init a packer context, bind this ThreadInfo to
 * the calling thread with crSetTSD().
 * We'll always call this function at least once even if we're not
 * using threads.
 */
ThreadInfo *packspuNewThread( unsigned long id )
{
    ThreadInfo *thread=NULL;
    int i;

#ifdef CHROMIUM_THREADSAFE
    crLockMutex(&_PackMutex);
#else
    CRASSERT(pack_spu.numThreads == 0);
#endif

    CRASSERT(pack_spu.numThreads < MAX_THREADS);
    for (i=0; i<MAX_THREADS; ++i)
    {
        if (!pack_spu.thread[i].inUse)
        {
            thread = &pack_spu.thread[i];
            break;
        }
    }
    CRASSERT(thread);

    thread->inUse = GL_TRUE;
    thread->id = id;
    thread->currentContext = NULL;
    thread->bInjectThread = GL_FALSE;

    /* connect to the server */
    thread->netServer.name = crStrdup( pack_spu.name );
    thread->netServer.buffer_size = pack_spu.buffer_size;
    if (pack_spu.numThreads == 0) {
        packspuConnectToServer( &(thread->netServer) );
        if (!thread->netServer.conn) {
            return NULL;
        }
        pack_spu.swap = thread->netServer.conn->swap;
    }
    else {
        /* a new pthread */
        crNetNewClient(pack_spu.thread[pack_spu.idxThreadInUse].netServer.conn, &(thread->netServer));
        CRASSERT(thread->netServer.conn);
    }

    /* packer setup */
    CRASSERT(thread->packer == NULL);
    thread->packer = crPackNewContext( pack_spu.swap );
    CRASSERT(thread->packer);
    crPackInitBuffer( &(thread->buffer), crNetAlloc(thread->netServer.conn),
                thread->netServer.conn->buffer_size, thread->netServer.conn->mtu );
    thread->buffer.canBarf = thread->netServer.conn->Barf ? GL_TRUE : GL_FALSE;
    crPackSetBuffer( thread->packer, &thread->buffer );
    crPackFlushFunc( thread->packer, packspuFlush );
    crPackFlushArg( thread->packer, (void *) thread );
    crPackSendHugeFunc( thread->packer, packspuHuge );
    crPackSetContext( thread->packer );

#ifdef CHROMIUM_THREADSAFE
    crSetTSD(&_PackTSD, thread);
#endif

    pack_spu.numThreads++;

#ifdef CHROMIUM_THREADSAFE
    crUnlockMutex(&_PackMutex);
#endif
    return thread;
}