VirtualBox

Changeset 39507 in vbox for trunk/src/VBox/GuestHost/OpenGL


Ignore:
Timestamp:
Dec 2, 2011 7:44:16 AM (13 years ago)
Author:
vboxsync
Message:

crOpenGL: fix destroyed context refference in TLS

Location:
trunk/src/VBox/GuestHost/OpenGL
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h

    r37613 r39507  
    118118struct CRContext {
    119119    int id;
     120
     121#ifdef CHROMIUM_THREADSAFE
     122    /* we keep reference counting of context's makeCurrent for different threads
     123     * this is primarily needed to avoid having an invalid memory reference in the TLS
     124     * when the context is assigned to more than one threads and then destroyed from
     125     * one of those, i.e.
     126     * 1. Thread1 -> MakeCurrent(ctx1);
     127     * 2. Thread2 -> MakeCurrent(ctx1);
     128     * 3. Thread1 -> Destroy(ctx1);
     129     * => Thread2 still refers to destroyed ctx1
     130     * */
     131    /* number of threads that have context set as current */
     132    volatile int cRefs;
     133#endif
     134
    120135    CRbitvalue bitid[CR_MAX_BITARRAY];
    121136    CRbitvalue neg_bitid[CR_MAX_BITARRAY];
     
    181196DECLEXPORT(void) crStateInit(void);
    182197DECLEXPORT(void) crStateDestroy(void);
     198DECLEXPORT(void) crStateOnThreadAttachDetach(GLboolean attach);
    183199DECLEXPORT(CRContext *) crStateCreateContext(const CRLimitsState *limits, GLint visBits, CRContext *share);
    184200DECLEXPORT(CRContext *) crStateCreateContextEx(const CRLimitsState *limits, GLint visBits, CRContext *share, GLint presetID);
  • trunk/src/VBox/GuestHost/OpenGL/state_tracker/state.h

    r31808 r39507  
    1111#ifdef CHROMIUM_THREADSAFE
    1212#include "cr_threads.h"
     13#include <iprt/asm.h>
    1314#endif
    1415
     
    2526extern CRtsd __contextTSD;
    2627#define GetCurrentContext() (CRContext *) crGetTSD(&__contextTSD)
     28
     29/* NOTE: below ref & SetCurrentContext stuff is supposed to be used only internally!!
     30 * it is placed here only to simplify things since some code besides state_init.c
     31 * (i.e. state_glsl.c) is using it */
     32void crStateFreeContext(CRContext *ctx);
     33#define CRCONTEXT_ADDREF(_ctx) do { \
     34        int cRefs = ASMAtomicIncS32(&((CRContext*)(_ctx))->cRefs); \
     35        CRASSERT(cRefs > 1); \
     36    } while (0)
     37#define CRCONTEXT_RELEASE(_ctx) do { \
     38        int cRefs = ASMAtomicDecS32(&((CRContext*)(_ctx))->cRefs); \
     39        CRASSERT(cRefs >= 0); \
     40        if (!cRefs) { \
     41            crStateFreeContext((_ctx)); \
     42        } \
     43    } while (0)
     44#define SetCurrentContext(_ctx) do { \
     45        CRContext * oldCur = GetCurrentContext(); \
     46        if (oldCur != (_ctx)) { \
     47            if (oldCur) { \
     48                CRCONTEXT_RELEASE(oldCur); \
     49            } \
     50            if ((_ctx)) { \
     51                CRCONTEXT_ADDREF(_ctx); \
     52            } \
     53            crSetTSD(&__contextTSD, _ctx); \
     54        } \
     55    } while (0)
    2756#else
    2857extern CRContext *__currentContext;
  • trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_glsl.c

    r37773 r39507  
    174174      as the current context isn't the one being destroyed*/
    175175#ifdef CHROMIUM_THREADSAFE
    176     crSetTSD(&__contextTSD, ctx);
     176    CRASSERT(g != ctx);
     177    CRASSERT(!ctx->cRefs);
     178    ++ctx->cRefs; /* <- this is a hack to avoid subsequent SetCurrentContext(g) do recursive Destroy for ctx */
     179    if (g)
     180        CRCONTEXT_ADDREF(g); /* <- ensure the g is not destroyed by the following SetCurrentContext call */
     181    SetCurrentContext(ctx);
    177182#else
    178183    __currentContext = ctx;
     
    183188
    184189#ifdef CHROMIUM_THREADSAFE
    185     crSetTSD(&__contextTSD, g);
     190    SetCurrentContext(g);
     191    if (g)
     192        CRCONTEXT_RELEASE(g);
     193    --ctx->cRefs; /* <- restore back the cRefs (see above) */
    186194#else
    187195    __currentContext = g;
  • trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c

    r37613 r39507  
    158158
    159159    ctx->id = i;
     160#ifdef CHROMIUM_THREADSAFE
     161    ctx->cRefs = 1;
     162#endif
    160163    ctx->flush_func = NULL;
    161164    for (j=0;j<CR_MAX_BITARRAY;j++){
     
    258261
    259262/*@todo crStateAttribDestroy*/
    260 static void
     263void
    261264crStateFreeContext(CRContext *ctx)
    262265{
     
    307310        /* Free the default/NULL context.
    308311         * Ensures context bits are reset */
     312#ifdef CHROMIUM_THREADSAFE
     313        SetCurrentContext(NULL);
     314        CRCONTEXT_RELEASE(defaultContext);
     315#else
    309316        crStateFreeContext(defaultContext);
    310 #ifdef CHROMIUM_THREADSAFE
    311         crSetTSD(&__contextTSD, NULL);
    312 #else
    313317        __currentContext = NULL;
    314318#endif
     
    324328
    325329#ifdef CHROMIUM_THREADSAFE
    326     crSetTSD(&__contextTSD, defaultContext);
     330    SetCurrentContext(defaultContext);
    327331#else
    328332    __currentContext = defaultContext;
     
    434438            crStateSwitchContext(current, defaultContext);
    435439#ifdef CHROMIUM_THREADSAFE
    436         crSetTSD(&__contextTSD, defaultContext);
     440        SetCurrentContext(defaultContext);
    437441#else
    438442        __currentContext = defaultContext;
     
    443447    g_availableContexts[ctx->id] = 0;
    444448
     449#ifdef CHROMIUM_THREADSAFE
     450    CRCONTEXT_RELEASE(ctx);
     451#else
    445452    crStateFreeContext(ctx);
     453#endif
    446454}
    447455
     
    467475
    468476#ifdef CHROMIUM_THREADSAFE
    469     crSetTSD(&__contextTSD, ctx);
     477    SetCurrentContext(ctx);
    470478#else
    471479    __currentContext = ctx;
     
    493501
    494502#ifdef CHROMIUM_THREADSAFE
    495     crSetTSD(&__contextTSD, ctx);
     503    SetCurrentContext(ctx);
    496504#else
    497505    __currentContext = ctx;
     
    549557}
    550558
     559void crStateOnThreadAttachDetach(GLboolean attach)
     560{
     561    if (attach)
     562        return;
     563
     564    /* release the context ref so that it can be freed */
     565    SetCurrentContext(NULL);
     566}
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette