static int
packSPUCleanup(void)
{
    int i;
#ifdef CHROMIUM_THREADSAFE
    crLockMutex(&_PackMutex);
#endif
    for (i=0; i<MAX_THREADS; ++i)
    {
        if (pack_spu.thread[i].inUse && pack_spu.thread[i].packer)
        {
            crPackDeleteContext(pack_spu.thread[i].packer);
        }
    }

    crFreeTSD(&_PackerTSD);
    crFreeTSD(&_PackTSD);
    
#ifdef CHROMIUM_THREADSAFE
    crUnlockMutex(&_PackMutex);
# ifndef WINDOWS
    crFreeMutex(&_PackMutex);
# endif
#endif
    return 1;
}
/**
 * This routine is called when a context or thread is done with a DLM.
 * It maintains an internal count of users, and will only actually destroy
 * itself when no one is still using the DLM.
 */
void DLM_APIENTRY crDLMFreeDLM(CRDLM *dlm, SPUDispatchTable *dispatchTable)
{
    /* We're about to change the displayLists hash; lock it first */
    DLM_LOCK(dlm)

    /* Decrement the user count.  If the user count has gone to
     * 0, then free the rest of the DLM.  Otherwise, other
     * contexts or threads are still using this DLM; keep
     * it around.
     */
    dlm->userCount--;
    if (dlm->userCount == 0) {

	crFreeHashtableEx(dlm->displayLists, crdlmFreeDisplayListResourcesCb, dispatchTable);
	dlm->displayLists = NULL;

	/* Must unlock before freeing the mutex */
	DLM_UNLOCK(dlm)

#ifdef CHROMIUM_THREADSAFE
	/* We release the mutex here; we really should delete the
	 * thread data key, but there's no utility in Chromium to
	 * do this.
	 *
	 * Note that, should one thread release the entire DLM
	 * while other threads still believe they are using it,
	 * any other threads that have current display lists (i.e.
	 * have issued glNewList more recently than glEndList)
	 * will be unable to reclaim their (likely very large)
	 * content buffers, as there will be no way to reclaim
	 * the thread-specific data.
	 *
	 * On the other hand, if one thread really does release
	 * the DLM while other threads still believe they are 
	 * using it, unreclaimed memory is the least of the
	 * application's problems...
	 */
	crFreeMutex(&(dlm->dlMutex));

	/* We free the TSD key here as well.  Note that this will
	 * strand any threads that still have thread-specific data
	 * tied to this key; but as stated above, if any threads
	 * still do have thread-specific data attached to this DLM,
	 * they're in big trouble anyway.
	 */
	crFreeTSD(&(dlm->tsdKey));
	crFreeTSD(&CRDLMTSDKey);
#endif

	/* Free the master record, and we're all done. */
	crFree(dlm);
    }
    else {
	/* We're keeping the DLM around for other users.  Unlock it,
	 * but retain its memory and display lists.
	 */
	DLM_UNLOCK(dlm)
    }
}
Exemple #3
0
void crStateDestroy(void)
{
    if (__currentBits)
    {
        crStateClientDestroyBits(&(__currentBits->client));
        crStateLightingDestroyBits(&(__currentBits->lighting));
        crFree(__currentBits);
        __currentBits = NULL;
    }

#ifdef CHROMIUM_THREADSAFE
    crFreeTSD(&__contextTSD);
#endif
}
Exemple #4
0
/* Windows crap */
BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
{
    (void) lpvReserved;

    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
    {
        CRNetServer ns;

#ifdef CHROMIUM_THREADSAFE
        crInitTSD(&g_stubCurrentContextTSD);
#endif

        crInitMutex(&stub_init_mutex);

#ifdef VDBG_VEHANDLER
        vboxVDbgVEHandlerRegister();
#endif

        crNetInit(NULL, NULL);
        ns.name = "vboxhgcm://host:0";
        ns.buffer_size = 1024;
        crNetServerConnect(&ns
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
                , NULL
#endif
);
        if (!ns.conn)
        {
            crDebug("Failed to connect to host (is guest 3d acceleration enabled?), aborting ICD load.");
#ifdef VDBG_VEHANDLER
            vboxVDbgVEHandlerUnregister();
#endif
            return FALSE;
        }
        else
            crNetFreeConnection(ns.conn);

        break;
    }

    case DLL_PROCESS_DETACH:
    {
        /* do exactly the same thing as for DLL_THREAD_DETACH since
         * DLL_THREAD_DETACH is not called for the thread doing DLL_PROCESS_DETACH according to msdn docs */
        stubSetCurrentContext(NULL);
        if (stub_initialized)
        {
            CRASSERT(stub.spu);
            stub.spu->dispatch_table.VBoxDetachThread();
        }

        stubSPUSafeTearDown();

#ifdef CHROMIUM_THREADSAFE
        crFreeTSD(&g_stubCurrentContextTSD);
#endif

#ifdef VDBG_VEHANDLER
        vboxVDbgVEHandlerUnregister();
#endif
        break;
    }

    case DLL_THREAD_ATTACH:
    {
        if (stub_initialized)
        {
            CRASSERT(stub.spu);
            stub.spu->dispatch_table.VBoxAttachThread();
        }
        break;
    }

    case DLL_THREAD_DETACH:
    {
        stubSetCurrentContext(NULL);
        if (stub_initialized)
        {
            CRASSERT(stub.spu);
            stub.spu->dispatch_table.VBoxDetachThread();
        }
        break;
    }

    default:
        break;
    }

    return TRUE;
}
static int renderSPUCleanup(void)
{
    renderspuVBoxCompositorClearAll();

    if (render_spu.blitterTable)
    {
        crFreeHashtable(render_spu.blitterTable, DeleteBlitterCallback);
        render_spu.blitterTable = NULL;
    }
    else
    {
        crHashtableWalk(render_spu.windowTable, renderspuBlitterCleanupCB, NULL);

        crHashtableWalk(render_spu.dummyWindowTable, renderspuBlitterCleanupCB, NULL);
    }

    renderspuSetDefaultSharedContext(NULL);

    crFreeHashtable(render_spu.contextTable, DeleteContextCallback);
    render_spu.contextTable = NULL;
    crFreeHashtable(render_spu.windowTable, DeleteWindowCallback);
    render_spu.windowTable = NULL;
    crFreeHashtable(render_spu.dummyWindowTable, DeleteWindowCallback);
    render_spu.dummyWindowTable = NULL;
    crFreeHashtable(render_spu.barrierHash, crFree);
    render_spu.barrierHash = NULL;

#ifdef RT_OS_DARWIN
# ifndef VBOX_WITH_COCOA_QT
    render_spu.fInit = false;
    DisposeEventHandlerUPP(render_spu.hParentEventHandler);
    ReleaseWindowGroup(render_spu.pMasterGroup);
    ReleaseWindowGroup(render_spu.pParentGroup);
    if (render_spu.hRootVisibleRegion)
    {
        DisposeRgn(render_spu.hRootVisibleRegion);
        render_spu.hRootVisibleRegion = 0;
    }
    render_spu.currentBufferName = 1;
    render_spu.uiDockUpdateTS = 0;
    RTSemFastMutexDestroy(render_spu.syncMutex);
# else /* VBOX_WITH_COCOA_QT */
# endif /* VBOX_WITH_COCOA_QT */
#endif /* RT_OS_DARWIN */

#ifdef RT_OS_WINDOWS
    if (render_spu.dwWinThreadId)
    {
        HANDLE hNative;

        hNative = OpenThread(SYNCHRONIZE|THREAD_QUERY_INFORMATION|THREAD_TERMINATE,
                             false, render_spu.dwWinThreadId);
        if (!hNative)
        {
            crWarning("Failed to get handle for window thread(%#x)", GetLastError());
        }

        if (PostThreadMessage(render_spu.dwWinThreadId, WM_QUIT, 0, 0))
        {
            WaitForSingleObject(render_spu.hWinThreadReadyEvent, INFINITE);

            /*wait for os thread to actually finish*/
            if (hNative && WaitForSingleObject(hNative, 3000)==WAIT_TIMEOUT)
            {
                crDebug("Wait failed, terminating");
                if (!TerminateThread(hNative, 1))
                {
                    crWarning("TerminateThread failed");
                }
            }
        }

        if (hNative)
        {
            CloseHandle(hNative);
        }
    }
    CloseHandle(render_spu.hWinThreadReadyEvent);
    render_spu.hWinThreadReadyEvent = NULL;
#endif

    crUnloadOpenGL();

#ifdef CHROMIUM_THREADSAFE
    crFreeTSD(&_RenderTSD);
#endif

    return 1;
}
Exemple #6
0
/* Windows crap */
BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved)
{
    (void) lpvReserved;

    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
    {
        CRNetServer ns;
        const char * env;
#if defined(DEBUG_misha)
        HMODULE hCrUtil;
        char aName[MAX_PATH];

        GetModuleFileNameA(hDLLInst, aName, RT_ELEMENTS(aName));
        crDbgCmdSymLoadPrint(aName, hDLLInst);

        hCrUtil = GetModuleHandleA("VBoxOGLcrutil.dll");
        Assert(hCrUtil);
        crDbgCmdSymLoadPrint("VBoxOGLcrutil.dll", hCrUtil);
#endif
#ifdef CHROMIUM_THREADSAFE
        crInitTSD(&g_stubCurrentContextTSD);
#endif

        crInitMutex(&stub_init_mutex);

#ifdef VDBG_VEHANDLER
        env = crGetenv("CR_DBG_VEH_ENABLE");
        g_VBoxVehEnable = crStrParseI32(env,
# ifdef DEBUG_misha
                1
# else
                0
# endif
                );

        if (g_VBoxVehEnable)
        {
            char procName[1024];
            size_t cProcName;
            size_t cChars;

            env = crGetenv("CR_DBG_VEH_FLAGS");
            g_VBoxVehFlags = crStrParseI32(env,
                    0
# ifdef DEBUG_misha
                    | VBOXVEH_F_BREAK
# else
                    | VBOXVEH_F_DUMP
# endif
                    );

            env = crGetenv("CR_DBG_VEH_DUMP_DIR");
            if (!env)
                env = VBOXMD_DUMP_DIR_DEFAULT;

            g_cVBoxMdFilePrefixLen = strlen(env);

            if (RT_ELEMENTS(g_aszwVBoxMdFilePrefix) <= g_cVBoxMdFilePrefixLen + 26 + (sizeof (VBOXMD_DUMP_NAME_PREFIX_W) - sizeof (WCHAR)) / sizeof (WCHAR))
            {
                g_cVBoxMdFilePrefixLen = 0;
                env = "";
            }

            mbstowcs_s(&cChars, g_aszwVBoxMdFilePrefix, g_cVBoxMdFilePrefixLen + 1, env, _TRUNCATE);

            Assert(cChars == g_cVBoxMdFilePrefixLen + 1);

            g_cVBoxMdFilePrefixLen = cChars - 1;

            if (g_cVBoxMdFilePrefixLen && g_aszwVBoxMdFilePrefix[g_cVBoxMdFilePrefixLen - 1] != L'\\')
                g_aszwVBoxMdFilePrefix[g_cVBoxMdFilePrefixLen++] = L'\\';

            memcpy(g_aszwVBoxMdFilePrefix + g_cVBoxMdFilePrefixLen, VBOXMD_DUMP_NAME_PREFIX_W, sizeof (VBOXMD_DUMP_NAME_PREFIX_W) - sizeof (WCHAR));
            g_cVBoxMdFilePrefixLen += (sizeof (VBOXMD_DUMP_NAME_PREFIX_W) - sizeof (WCHAR)) / sizeof (WCHAR);

            crGetProcName(procName, RT_ELEMENTS(procName));
            cProcName = strlen(procName);

            if (RT_ELEMENTS(g_aszwVBoxMdFilePrefix) > g_cVBoxMdFilePrefixLen + cProcName + 1 + 26)
            {
                mbstowcs_s(&cChars, g_aszwVBoxMdFilePrefix + g_cVBoxMdFilePrefixLen, cProcName + 1, procName, _TRUNCATE);
                Assert(cChars == cProcName + 1);
                g_cVBoxMdFilePrefixLen += cChars - 1;
                g_aszwVBoxMdFilePrefix[g_cVBoxMdFilePrefixLen++] = L'_';
            }

            /* sanity */
            g_aszwVBoxMdFilePrefix[g_cVBoxMdFilePrefixLen] = L'\0';

            env = crGetenv("CR_DBG_VEH_DUMP_TYPE");

            g_enmVBoxMdDumpType = crStrParseI32(env,
                    MiniDumpNormal
                    | MiniDumpWithDataSegs
                    | MiniDumpWithFullMemory
                    | MiniDumpWithHandleData
            ////        | MiniDumpFilterMemory
            ////        | MiniDumpScanMemory
            //        | MiniDumpWithUnloadedModules
            ////        | MiniDumpWithIndirectlyReferencedMemory
            ////        | MiniDumpFilterModulePaths
            //        | MiniDumpWithProcessThreadData
            //        | MiniDumpWithPrivateReadWriteMemory
            ////        | MiniDumpWithoutOptionalData
            //        | MiniDumpWithFullMemoryInfo
            //        | MiniDumpWithThreadInfo
            //        | MiniDumpWithCodeSegs
            //        | MiniDumpWithFullAuxiliaryState
            //        | MiniDumpWithPrivateWriteCopyMemory
            //        | MiniDumpIgnoreInaccessibleMemory
            //        | MiniDumpWithTokenInformation
            ////        | MiniDumpWithModuleHeaders
            ////        | MiniDumpFilterTriage
                    );

            vboxVDbgVEHandlerRegister();
        }
#endif

        crNetInit(NULL, NULL);
        ns.name = "vboxhgcm://host:0";
        ns.buffer_size = 1024;
        crNetServerConnect(&ns
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
                , NULL
#endif
);
        if (!ns.conn)
        {
            crDebug("Failed to connect to host (is guest 3d acceleration enabled?), aborting ICD load.");
#ifdef VDBG_VEHANDLER
            if (g_VBoxVehEnable)
                vboxVDbgVEHandlerUnregister();
#endif
            return FALSE;
        }
        else
        {
            crNetFreeConnection(ns.conn);
        }

#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
        VBoxCrHgsmiInit();
#endif
        break;
    }

    case DLL_PROCESS_DETACH:
    {
        /* do exactly the same thing as for DLL_THREAD_DETACH since
         * DLL_THREAD_DETACH is not called for the thread doing DLL_PROCESS_DETACH according to msdn docs */
        stubSetCurrentContext(NULL);
        if (stub_initialized)
        {
            CRASSERT(stub.spu);
            stub.spu->dispatch_table.VBoxDetachThread();
        }

        
#if defined(VBOX_WITH_CRHGSMI) && defined(IN_GUEST)
        VBoxCrHgsmiTerm();
#endif

        stubSPUSafeTearDown();

#ifdef CHROMIUM_THREADSAFE
        crFreeTSD(&g_stubCurrentContextTSD);
#endif

#ifdef VDBG_VEHANDLER
        if (g_VBoxVehEnable)
            vboxVDbgVEHandlerUnregister();
#endif
        break;
    }

    case DLL_THREAD_ATTACH:
    {
        if (stub_initialized)
        {
            CRASSERT(stub.spu);
            stub.spu->dispatch_table.VBoxAttachThread();
        }
        break;
    }

    case DLL_THREAD_DETACH:
    {
        stubSetCurrentContext(NULL);
        if (stub_initialized)
        {
            CRASSERT(stub.spu);
            stub.spu->dispatch_table.VBoxDetachThread();
        }
        break;
    }

    default:
        break;
    }

    return TRUE;
}