Index: /trunk/src/VBox/Additions/common/crOpenGL/context.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/context.c	(revision 39567)
+++ /trunk/src/VBox/Additions/common/crOpenGL/context.c	(revision 39568)
@@ -309,4 +309,46 @@
 }
 
+static void stubWindowCheckOwnerCB(unsigned long key, void *data1, void *data2);
+
+static void
+stubDestroyContextLocked( ContextInfo *context )
+{
+    unsigned long contextId = context->id;
+    if (context->type == NATIVE) {
+#ifdef WINDOWS
+        stub.wsInterface.wglDeleteContext( context->hglrc );
+#elif defined(Darwin)
+        stub.wsInterface.CGLDestroyContext( context->cglc );
+#elif defined(GLX)
+        stub.wsInterface.glXDestroyContext( context->dpy, context->glxContext );
+#endif
+    }
+    else if (context->type == CHROMIUM) {
+        /* Have pack SPU or tilesort SPU, etc. destroy the context */
+        CRASSERT(context->spuContext >= 0);
+        stub.spu->dispatch_table.DestroyContext( context->spuContext );
+        crHashtableWalk(stub.windowTable, stubWindowCheckOwnerCB, context);
+    }
+
+#ifdef GLX
+    crFreeHashtable(context->pGLXPixmapsHash, crFree);
+    if (context->damageDpy)
+    {
+        XCloseDisplay(context->damageDpy);
+    }
+#endif
+
+    crMemZero(context, sizeof(ContextInfo));  /* just to be safe */
+    crHashtableDelete(stub.contextTable, contextId, crFree);
+}
+
+#ifdef CHROMIUM_THREADSAFE
+static DECLCALLBACK(void) stubContextDtor(void*pvContext)
+{
+    crHashtableLock(stub.contextTable);
+    stubDestroyContextLocked((ContextInfo*)pvContext);
+    crHashtableUnlock(stub.contextTable);
+}
+#endif
 
 /**
@@ -353,4 +395,8 @@
     crStrncpy(context->dpyName, dpyName, MAX_DPY_NAME);
     context->dpyName[MAX_DPY_NAME-1] = 0;
+
+#ifdef CHROMIUM_THREADSAFE
+    crTSDRefInit(context, stubContextDtor);
+#endif
 
 #if defined(GLX) || defined(DARWIN)
@@ -925,9 +971,10 @@
 
     if (!context || !window) {
-        if (stub.currentContext)
-            stub.currentContext->currentDrawable = NULL;
+        ContextInfo * currentContext = stubGetCurrentContext();
+        if (currentContext)
+            currentContext->currentDrawable = NULL;
         if (context)
             context->currentDrawable = NULL;
-        stub.currentContext = NULL;
+        stubSetCurrentContext(NULL);
         return GL_TRUE;  /* OK */
     }
@@ -1062,5 +1109,5 @@
     window->pOwner = context;
     context->currentDrawable = window;
-    stub.currentContext = context;
+    stubSetCurrentContext(context);
 
     if (retVal) {
@@ -1140,35 +1187,17 @@
     CRASSERT(context);
 
-    if (context->type == NATIVE) {
-#ifdef WINDOWS
-        stub.wsInterface.wglDeleteContext( context->hglrc );
-#elif defined(Darwin)
-        stub.wsInterface.CGLDestroyContext( context->cglc );
-#elif defined(GLX)
-        stub.wsInterface.glXDestroyContext( context->dpy, context->glxContext );
-#endif
-    }
-    else if (context->type == CHROMIUM) {
-        /* Have pack SPU or tilesort SPU, etc. destroy the context */
-        CRASSERT(context->spuContext >= 0);
-        stub.spu->dispatch_table.DestroyContext( context->spuContext );
-        crHashtableWalk(stub.windowTable, stubWindowCheckOwnerCB, context);
-    }
-
-    if (stub.currentContext == context) {
-        stub.currentContext = NULL;
-    }
-
-#ifdef GLX
-    crFreeHashtable(context->pGLXPixmapsHash, crFree);
-    if (context->damageDpy)
-    {
-        XCloseDisplay(context->damageDpy);
-    }
-#endif
-
-    crMemZero(context, sizeof(ContextInfo));  /* just to be safe */
-    crHashtableDelete(stub.contextTable, contextId, crFree);
-
+#ifdef CHROMIUM_THREADSAFE
+    if (stubGetCurrentContext() == context) {
+        stubSetCurrentContext(NULL);
+    }
+
+    crTSDRefRelease(context);
+#else
+    stubDestroyContextLocked(context);
+
+    if (stubGetCurrentContext() == context) {
+        stubSetCurrentContext(NULL);
+    }
+#endif
     crHashtableUnlock(stub.contextTable);
 }
Index: /trunk/src/VBox/Additions/common/crOpenGL/glx.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/glx.c	(revision 39567)
+++ /trunk/src/VBox/Additions/common/crOpenGL/glx.c	(revision 39568)
@@ -1043,6 +1043,7 @@
 DECLEXPORT(GLXContext) VBOXGLXTAG(glXGetCurrentContext)( void )
 {
-    if (stub.currentContext)
-        return (GLXContext) stub.currentContext->id;
+    ContextInfo *context = stubGetCurrentContext();
+    if (context)
+        return (GLXContext) context->id;
     else
         return (GLXContext) NULL;
@@ -1182,5 +1183,6 @@
 DECLEXPORT(void) VBOXGLXTAG(glXUseXFont)( Font font, int first, int count, int listBase )
 {
-    if (stub.currentContext->type == CHROMIUM)
+    ContextInfo *context = stubGetCurrentContext();
+    if (context->type == CHROMIUM)
     {
         Display *dpy = stub.wsInterface.glXGetCurrentDisplay();
@@ -1201,5 +1203,6 @@
 DECLEXPORT(void) VBOXGLXTAG(glXUseXFont)( Font font, int first, int count, int listBase )
 {
-    Display *dpy = stub.currentContext->dpy;
+    ContextInfo *context = stubGetCurrentContext();
+    Display *dpy = context->dpy;
     if (dpy) {
         stubUseXFont( dpy, font, first, count, listBase );
@@ -2479,4 +2482,5 @@
     if (event->type==damage_evb+XDamageNotify)
     {
+        ContextInfo *context = stubGetCurrentContext();
         XDamageNotifyEvent *e = (XDamageNotifyEvent *) event;
         /* we're interested in pixmaps only...and those have e->drawable set to 0 or other strange value for some odd reason 
@@ -2486,6 +2490,6 @@
                 (unsigned int) e->drawable, (unsigned int) e->damage, (int) e->level,
                 e->area.x, e->area.y, e->area.width, e->area.height);*/
-        CRASSERT(stub.currentContext);
-        crHashtableWalk(stub.currentContext->pGLXPixmapsHash, checkdamageCB, e);
+        CRASSERT(context);
+        crHashtableWalk(context->pGLXPixmapsHash, checkdamageCB, e);
     }
     return False;
@@ -2498,8 +2502,9 @@
     static int cnt=0;
     XImage dummyimg;
+    ContextInfo *context = stubGetCurrentContext();
 
     GLX_Pixmap_t *pGlxPixmap;
 
-    if (!stub.currentContext)
+    if (!context)
     {
         crWarning("glXBindTexImageEXT called without current context");
@@ -2507,5 +2512,5 @@
     }
 
-    pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(stub.currentContext->pGLXPixmapsHash, (unsigned int) draw);
+    pGlxPixmap = (GLX_Pixmap_t *) crHashtableSearch(context->pGLXPixmapsHash, (unsigned int) draw);
     if (!pGlxPixmap)
     {
@@ -2516,5 +2521,5 @@
             return;
         }
-        pGlxPixmap = stubInitGlxPixmap(pGlxPixmap, dpy, draw, stub.currentContext);
+        pGlxPixmap = stubInitGlxPixmap(pGlxPixmap, dpy, draw, context);
         if (!pGlxPixmap)
         {
@@ -2525,5 +2530,5 @@
 
     /* If there's damage extension, then process incoming events as we need the information right now */
-    if (stub.currentContext->damageDpy)
+    if (context->damageDpy)
     {
         /* Sync connections, note that order of syncs is important here.
@@ -2532,13 +2537,13 @@
         XSync(dpy, False);
         XUNLOCK(dpy);
-        XSync(stub.currentContext->damageDpy, False);
-
-        while (XPending(stub.currentContext->damageDpy))
+        XSync(context->damageDpy, False);
+
+        while (XPending(context->damageDpy))
         {
             XEvent event;
-            XNextEvent(stub.currentContext->damageDpy, &event);
-            if (event.type==stub.currentContext->damageEventsBase+XDamageNotify)
+            XNextEvent(context->damageDpy, &event);
+            if (event.type==contextt->damageEventsBase+XDamageNotify)
             {
-                crHashtableWalk(stub.currentContext->pGLXPixmapsHash, stubCheckXDamageCB, &event);
+                crHashtableWalk(contextt->pGLXPixmapsHash, stubCheckXDamageCB, &event);
             }
         }
@@ -2590,5 +2595,5 @@
     {
         /* Check if we have damage extension */
-        if (stub.currentContext->damageDpy)
+        if (context->damageDpy)
         {
             if (pGlxPixmap->bPixmapImageDirty)
Index: /trunk/src/VBox/Additions/common/crOpenGL/load.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/load.c	(revision 39567)
+++ /trunk/src/VBox/Additions/common/crOpenGL/load.c	(revision 39568)
@@ -68,4 +68,7 @@
 /* NOTE: 'SPUDispatchTable stubThreadsafeDispatch' is declared in tsfuncs.c */
 Stub stub;
+#ifdef CHROMIUM_THREADSAFE
+CRtsd g_stubCurrentContextTSD;
+#endif
 
 
@@ -201,7 +204,9 @@
 static void stubCheckWindowsState(void)
 {
+    ContextInfo *context = stubGetCurrentContext();
+
     CRASSERT(stub.trackWindowSize || stub.trackWindowPos);
 
-    if (!stub.currentContext)
+    if (!context)
         return;
 
@@ -215,6 +220,6 @@
 #endif
 
-    stubCheckWindowState(stub.currentContext->currentDrawable, GL_TRUE);
-    crHashtableWalk(stub.windowTable, stubCheckWindowsCB, stub.currentContext);
+    stubCheckWindowState(context->currentDrawable, GL_TRUE);
+    crHashtableWalk(stub.windowTable, stubCheckWindowsCB, context);
 
 #if defined(CR_NEWWINTRACK) && !defined(WINDOWS)
@@ -250,8 +255,9 @@
     else
     {
+        ContextInfo *context = stubGetCurrentContext();
         int winX, winY;
         unsigned int winW, winH;
         WindowInfo *pWindow;
-        pWindow = stub.currentContext->currentDrawable;
+        pWindow = context->currentDrawable;
         stubGetWindowGeometry(pWindow, &winX, &winY, &winW, &winH);
         origViewport(0, 0, winW, winH);
@@ -276,5 +282,6 @@
     unsigned int winW, winH;
     WindowInfo *pWindow;
-    pWindow = stub.currentContext->currentDrawable;
+    ContextInfo *context = stubGetCurrentContext();
+    pWindow = context->currentDrawable;
     stubGetWindowGeometry(pWindow, &winX, &winY, &winW, &winH);
     origScissor(0, 0, winW, winH);
@@ -538,5 +545,10 @@
     stub.freeContextNumber = MAGIC_CONTEXT_BASE;
     stub.contextTable = crAllocHashtable();
-    stub.currentContext = NULL;
+#ifndef RT_OS_WINDOWS
+# ifdef CHROMIUM_THREADSAFE
+    crInitTSD(&g_stubCurrentContextTSD);
+# endif
+#endif
+    stubSetCurrentContext(NULL);
 
     stub.windowTable = crAllocHashtable();
@@ -1367,4 +1379,8 @@
         CRNetServer ns;
 
+#ifdef CHROMIUM_THREADSAFE
+        crInitTSD(&g_stubCurrentContextTSD);
+#endif
+
         crInitMutex(&stub_init_mutex);
 
@@ -1402,7 +1418,7 @@
     }
 
+    case DLL_THREAD_ATTACH:
+    {
 #if 0
-    case DLL_THREAD_ATTACH:
-    {
         if (stub_initialized)
         {
@@ -1410,4 +1426,5 @@
             stub.spu->dispatch_table.VBoxPackAttachThread();
         }
+#endif
         break;
     }
@@ -1415,4 +1432,6 @@
     case DLL_THREAD_DETACH:
     {
+        stubSetCurrentContext(NULL);
+#if 0
         if (stub_initialized)
         {
@@ -1420,7 +1439,7 @@
             stub.spu->dispatch_table.VBoxPackDetachThread();
         }
+#endif
         break;
     }
-#endif
 
     default:
Index: /trunk/src/VBox/Additions/common/crOpenGL/stub.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/stub.c	(revision 39567)
+++ /trunk/src/VBox/Additions/common/crOpenGL/stub.c	(revision 39568)
@@ -88,7 +88,9 @@
 GLint APIENTRY crGetCurrentContext( void )
 {
+    ContextInfo *context;
     stubInit();
-    if (stub.currentContext)
-      return (GLint) stub.currentContext->id;
+    context = stubGetCurrentContext();
+    if (context)
+      return (GLint) context->id;
     else
       return 0;
@@ -97,7 +99,9 @@
 GLint APIENTRY crGetCurrentWindow( void )
 {
+    ContextInfo *context;
     stubInit();
-    if (stub.currentContext && stub.currentContext->currentDrawable)
-      return stub.currentContext->currentDrawable->spuWindow;
+    context = stubGetCurrentContext();
+    if (context && context->currentDrawable)
+      return context->currentDrawable->spuWindow;
     else
       return -1;
Index: /trunk/src/VBox/Additions/common/crOpenGL/stub.h
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/stub.h	(revision 39567)
+++ /trunk/src/VBox/Additions/common/crOpenGL/stub.h	(revision 39568)
@@ -111,4 +111,8 @@
     GLint visBits;
     WindowInfo *currentDrawable;
+
+#ifdef CHROMIUM_THREADSAFE
+    CRTSDREFDATA
+#endif
 
 #ifdef WINDOWS
@@ -225,5 +229,7 @@
     int freeContextNumber;
     CRHashTable *contextTable;
+#ifndef CHROMIUM_THREADSAFE
     ContextInfo *currentContext; /* may be NULL */
+#endif
 
     /* windows */
@@ -258,6 +264,27 @@
 } Stub;
 
+#ifdef CHROMIUM_THREADSAFE
+# define stubGetCurrentContext() crTSDRefGetCurrent(ContextInfo, &g_stubCurrentContextTSD)
+# define stubSetCurrentContext(_ctx) crTSDRefSetCurrent(ContextInfo, &g_stubCurrentContextTSD, _ctx)
+#else
+# define stubGetCurrentContext() (stub.currentContext)
+# define stubSetCurrentContext(_ctx) do { stub.currentContext = (_ctx); } while (0)
+#endif
 
 extern Stub stub;
+/* we place the __currentContextTSD outside the Stub data because Stub data is inited by the client's call,
+ * while we need __currentContextTSD the __currentContextTSD to be valid at any time to be able to handle
+ * THREAD_DETACH cleanup on windows.
+ * Note that we can not do
+ *  STUB_INIT_LOCK();
+ *  if (stub_initialized) stubSetCurrentContext(NULL);
+ *  STUB_INIT_UNLOCK();
+ * on THREAD_DETACH since it may cause deadlock, i.e. in this situation loader lock is acquired first and then the init lock,
+ * but since we use GetModuleFileName in crGetProcName called from stubInitLocked, the lock order might be the oposite.
+ * Note that GetModuleFileName acquires the loader lock.
+ * */
+#ifdef CHROMIUM_THREADSAFE
+extern CRtsd g_stubCurrentContextTSD;
+#endif
 extern DECLEXPORT(SPUDispatchTable) glim;
 extern SPUDispatchTable stubThreadsafeDispatch;
Index: /trunk/src/VBox/Additions/common/crOpenGL/wgl.c
===================================================================
--- /trunk/src/VBox/Additions/common/crOpenGL/wgl.c	(revision 39567)
+++ /trunk/src/VBox/Additions/common/crOpenGL/wgl.c	(revision 39568)
@@ -186,11 +186,13 @@
 HGLRC WINAPI wglGetCurrentContext_prox( void )
 {
-    return (HGLRC) (stub.currentContext ? stub.currentContext->id : 0);
+    ContextInfo *context = stubGetCurrentContext();
+    return (HGLRC) (context ? context->id : 0);
 }
 
 HDC WINAPI wglGetCurrentDC_prox( void )
 {
-    if (stub.currentContext && stub.currentContext->currentDrawable)
-        return (HDC) stub.currentContext->currentDrawable->drawable;
+    ContextInfo *context = stubGetCurrentContext();
+    if (context && context->currentDrawable)
+        return (HDC) context->currentDrawable->drawable;
     else
         return (HDC) NULL;
Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h	(revision 39567)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_glstate.h	(revision 39568)
@@ -46,4 +46,8 @@
 #include "spu_dispatch_table.h"
 
+#ifdef CHROMIUM_THREADSAFE
+#include "cr_threads.h"
+#endif
+
 #include <iprt/cdefs.h>
 
@@ -129,6 +133,5 @@
      * => Thread2 still refers to destroyed ctx1
      * */
-    /* number of threads that have context set as current */
-    volatile int cRefs;
+    CRTSDREFDATA
 #endif
 
Index: /trunk/src/VBox/GuestHost/OpenGL/include/cr_threads.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/include/cr_threads.h	(revision 39567)
+++ /trunk/src/VBox/GuestHost/OpenGL/include/cr_threads.h	(revision 39568)
@@ -25,5 +25,5 @@
 #endif
 
-
+#include <iprt/asm.h>
 /*
  * Handle for Thread-Specific Data
@@ -101,5 +101,60 @@
 extern DECLEXPORT(void) crSignalSemaphore(CRsemaphore *s);
 
+typedef DECLCALLBACK(void) FNCRTSDREFDTOR(void*);
+typedef FNCRTSDREFDTOR *PFNCRTSDREFDTOR;
 
+typedef enum {
+    CRTSDREFDATA_STATE_UNDEFINED = 0,
+    CRTSDREFDATA_STATE_INITIALIZED,
+    CRTSDREFDATA_STATE_TOBE_DESTROYED,
+    CRTSDREFDATA_STATE_DESTROYING,
+    CRTSDREFDATA_STATE_32BIT_HACK = 0x7fffffff
+} CRTSDREFDATA_STATE;
+
+#define CRTSDREFDATA \
+    volatile uint32_t cTsdRefs; \
+    uint32_t enmTsdRefState; \
+    PFNCRTSDREFDTOR pfnTsdRefDtor; \
+
+#define crTSDRefInit(_p, _pfnDtor) do { \
+        (_p)->cTsdRefs = 1; \
+        (_p)->enmTsdRefState = CRTSDREFDATA_STATE_INITIALIZED; \
+        (_p)->pfnTsdRefDtor = (_pfnDtor); \
+    } while (0)
+
+#define crTSDRefIsFunctional(_p) (!!((_p)->enmTsdRefState == CRTSDREFDATA_STATE_INITIALIZED))
+
+#define crTSDRefAddRef(_p) do { \
+        int cRefs = ASMAtomicIncS32(&(_p)->cTsdRefs); \
+        CRASSERT(cRefs > 1 || (_p)->enmTsdRefState == CRTSDREFDATA_STATE_DESTROYING); \
+    } while (0)
+
+#define crTSDRefRelease(_p) do { \
+        int cRefs = ASMAtomicDecS32(&(_p)->cTsdRefs); \
+        CRASSERT(cRefs >= 0); \
+        if (!cRefs && (_p)->enmTsdRefState != CRTSDREFDATA_STATE_DESTROYING /* <- avoid recursion if crTSDRefAddRef/Release is called from dtor */) { \
+            (_p)->enmTsdRefState = CRTSDREFDATA_STATE_DESTROYING; \
+            (_p)->pfnTsdRefDtor((_p)); \
+        } \
+    } while (0)
+
+#define crTSDRefReleaseMarkDestroy(_p) do { \
+        (_p)->enmTsdRefState = CRTSDREFDATA_STATE_TOBE_DESTROYED; \
+    } while (0)
+
+#define crTSDRefGetCurrent(_t, _pTsd) ((_t*) crGetTSD((_pTsd)))
+
+#define crTSDRefSetCurrent(_t, _pTsd, _p) do { \
+        _t * oldCur = crTSDRefGetCurrent(_t, _pTsd); \
+        if (oldCur != (_p)) { \
+            crSetTSD((_pTsd), (_p)); \
+            if (oldCur) { \
+                crTSDRefRelease(oldCur); \
+            } \
+            if ((_p)) { \
+                crTSDRefAddRef((_t*)(_p)); \
+            } \
+        } \
+    } while (0)
 #ifdef __cplusplus
 }
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state.h
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state.h	(revision 39567)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state.h	(revision 39568)
@@ -11,5 +11,4 @@
 #ifdef CHROMIUM_THREADSAFE
 #include "cr_threads.h"
-#include <iprt/asm.h>
 #endif
 
@@ -25,33 +24,10 @@
 #ifdef CHROMIUM_THREADSAFE
 extern CRtsd __contextTSD;
-#define GetCurrentContext() (CRContext *) crGetTSD(&__contextTSD)
+#define GetCurrentContext() crTSDRefGetCurrent(CRContext, &__contextTSD)
 
-/* NOTE: below ref & SetCurrentContext stuff is supposed to be used only internally!!
+/* NOTE: below SetCurrentContext stuff is supposed to be used only internally!!
  * it is placed here only to simplify things since some code besides state_init.c
  * (i.e. state_glsl.c) is using it */
-void crStateFreeContext(CRContext *ctx);
-#define CRCONTEXT_ADDREF(_ctx) do { \
-        int cRefs = ASMAtomicIncS32(&((CRContext*)(_ctx))->cRefs); \
-        CRASSERT(cRefs > 1); \
-    } while (0)
-#define CRCONTEXT_RELEASE(_ctx) do { \
-        int cRefs = ASMAtomicDecS32(&((CRContext*)(_ctx))->cRefs); \
-        CRASSERT(cRefs >= 0); \
-        if (!cRefs) { \
-            crStateFreeContext((_ctx)); \
-        } \
-    } while (0)
-#define SetCurrentContext(_ctx) do { \
-        CRContext * oldCur = GetCurrentContext(); \
-        if (oldCur != (_ctx)) { \
-            if (oldCur) { \
-                CRCONTEXT_RELEASE(oldCur); \
-            } \
-            if ((_ctx)) { \
-                CRCONTEXT_ADDREF(_ctx); \
-            } \
-            crSetTSD(&__contextTSD, _ctx); \
-        } \
-    } while (0)
+#define SetCurrentContext(_ctx) crTSDRefSetCurrent(CRContext, &__contextTSD, _ctx)
 #else
 extern CRContext *__currentContext;
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_glsl.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_glsl.c	(revision 39567)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_glsl.c	(revision 39568)
@@ -174,8 +174,8 @@
       as the current context isn't the one being destroyed*/
 #ifdef CHROMIUM_THREADSAFE
-    CRASSERT(!ctx->cRefs);
-    ++ctx->cRefs; /* <- this is a hack to avoid subsequent SetCurrentContext(g) do recursive Destroy for ctx */
+    CRASSERT(g != ctx);
+    crTSDRefAddRef(ctx); /* <- this is a hack to avoid subsequent SetCurrentContext(g) do recursive Destroy for ctx */
     if (g)
-        CRCONTEXT_ADDREF(g); /* <- ensure the g is not destroyed by the following SetCurrentContext call */
+        crTSDRefAddRef(g); /* <- ensure the g is not destroyed by the following SetCurrentContext call */
     SetCurrentContext(ctx);
 #else
@@ -189,6 +189,6 @@
     SetCurrentContext(g);
     if (g)
-        CRCONTEXT_RELEASE(g);
-    --ctx->cRefs; /* <- restore back the cRefs (see above) */
+        crTSDRefRelease(g);
+    crTSDRefRelease(ctx); /* <- restore back the cRefs (see above) */
 #else
     __currentContext = g;
Index: /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c
===================================================================
--- /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c	(revision 39567)
+++ /trunk/src/VBox/GuestHost/OpenGL/state_tracker/state_init.c	(revision 39568)
@@ -145,4 +145,13 @@
 }
 
+#ifdef CHROMIUM_THREADSAFE
+static void
+crStateFreeContext(CRContext *ctx);
+static DECLCALLBACK(void) crStateContextDtor(void *pvCtx)
+{
+    crStateFreeContext((CRContext*)pvCtx);
+}
+#endif
+
 /*
  * Helper for crStateCreateContext, below.
@@ -159,5 +168,5 @@
     ctx->id = i;
 #ifdef CHROMIUM_THREADSAFE
-    ctx->cRefs = 1;
+    crTSDRefInit(ctx, crStateContextDtor);
 #endif
     ctx->flush_func = NULL;
@@ -261,5 +270,5 @@
 
 /*@todo crStateAttribDestroy*/
-void
+static void
 crStateFreeContext(CRContext *ctx)
 {
@@ -312,5 +321,5 @@
 #ifdef CHROMIUM_THREADSAFE
         SetCurrentContext(NULL);
-        CRCONTEXT_RELEASE(defaultContext);
+        crTSDRefRelease(defaultContext);
 #else
         crStateFreeContext(defaultContext);
@@ -448,5 +457,5 @@
 
 #ifdef CHROMIUM_THREADSAFE
-    CRCONTEXT_RELEASE(ctx);
+    crTSDRefRelease(ctx);
 #else
     crStateFreeContext(ctx);
