mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 11:48:06 +02:00
Fix a potential race condition. Fix a couple of places where
_glapi_DispatchTSD wasn't properly handled.
This commit is contained in:
parent
2491d5135b
commit
d14d103a0c
1 changed files with 26 additions and 13 deletions
|
|
@ -155,10 +155,15 @@ static int NoOpUnused(void)
|
|||
* static dispatch functions to call \c _glapi_get_dispatch to get the real
|
||||
* dispatch table.
|
||||
*
|
||||
* Throughout the code \c _glapi_DispatchTSD == \c NULL is used to determine
|
||||
* whether or not the application is multi-threaded.
|
||||
* There is a race condition in setting \c _glapi_DispatchTSD to \c NULL.
|
||||
* It is possible for the original thread to be setting it at the same instant
|
||||
* a new thread, perhaps running on a different processor, is clearing it.
|
||||
* Because of that, \c ThreadSafe, which can only ever be changed to
|
||||
* \c GL_FALSE, is used to determin whether or not the application is
|
||||
* multithreaded.
|
||||
*/
|
||||
/*@{*/
|
||||
static GLboolean ThreadSafe = GL_FALSE; /**< In thread-safe mode? */
|
||||
_glthread_TSD _gl_DispatchTSD; /**< Per-thread dispatch pointer */
|
||||
static _glthread_TSD RealDispatchTSD; /**< only when using override */
|
||||
static _glthread_TSD ContextTSD; /**< Per-thread context pointer */
|
||||
|
|
@ -184,9 +189,12 @@ static int glUnused(void)
|
|||
|
||||
|
||||
struct _glapi_table *_glapi_Dispatch = (struct _glapi_table *) __glapi_noop_table;
|
||||
#if defined( THREADS )
|
||||
struct _glapi_table *_glapi_DispatchTSD = (struct _glapi_table *) __glapi_noop_table;
|
||||
#endif
|
||||
struct _glapi_table *_glapi_RealDispatch = (struct _glapi_table *) __glapi_noop_table;
|
||||
|
||||
|
||||
/* Used when thread safety disabled */
|
||||
void *_glapi_Context = NULL;
|
||||
|
||||
|
|
@ -219,7 +227,7 @@ void
|
|||
_glapi_check_multithread(void)
|
||||
{
|
||||
#if defined(THREADS)
|
||||
if ( _glapi_DispatchTSD != NULL ) {
|
||||
if (!ThreadSafe) {
|
||||
static unsigned long knownID;
|
||||
static GLboolean firstCall = GL_TRUE;
|
||||
if (firstCall) {
|
||||
|
|
@ -227,6 +235,7 @@ _glapi_check_multithread(void)
|
|||
firstCall = GL_FALSE;
|
||||
}
|
||||
else if (knownID != _glthread_GetID()) {
|
||||
ThreadSafe = GL_TRUE;
|
||||
_glapi_set_dispatch(NULL);
|
||||
}
|
||||
}
|
||||
|
|
@ -249,7 +258,7 @@ _glapi_set_context(void *context)
|
|||
{
|
||||
#if defined(THREADS)
|
||||
_glthread_SetTSD(&ContextTSD, context);
|
||||
_glapi_Context = (_glapi_DispatchTSD == NULL) ? NULL : context;
|
||||
_glapi_Context = (ThreadSafe) ? NULL : context;
|
||||
#else
|
||||
_glapi_Context = context;
|
||||
#endif
|
||||
|
|
@ -266,7 +275,7 @@ void *
|
|||
_glapi_get_context(void)
|
||||
{
|
||||
#if defined(THREADS)
|
||||
if ( _glapi_DispatchTSD == NULL ) {
|
||||
if (ThreadSafe) {
|
||||
return _glthread_GetTSD(&ContextTSD);
|
||||
}
|
||||
else {
|
||||
|
|
@ -303,7 +312,7 @@ _glapi_set_dispatch(struct _glapi_table *dispatch)
|
|||
#if defined(THREADS)
|
||||
if (DispatchOverride) {
|
||||
_glthread_SetTSD(&RealDispatchTSD, (void *) old_style_dispatch);
|
||||
if ( dispatch == NULL )
|
||||
if (ThreadSafe)
|
||||
_glapi_RealDispatch = (struct _glapi_table*) __glapi_threadsafe_table;
|
||||
else
|
||||
_glapi_RealDispatch = dispatch;
|
||||
|
|
@ -311,11 +320,14 @@ _glapi_set_dispatch(struct _glapi_table *dispatch)
|
|||
else {
|
||||
/* normal operation */
|
||||
_glthread_SetTSD(&_gl_DispatchTSD, (void *) old_style_dispatch);
|
||||
_glapi_DispatchTSD = dispatch;
|
||||
|
||||
_glapi_Dispatch = (dispatch == NULL)
|
||||
? (struct _glapi_table *) __glapi_threadsafe_table
|
||||
: old_style_dispatch;
|
||||
if (ThreadSafe) {
|
||||
_glapi_Dispatch = (struct _glapi_table *) __glapi_threadsafe_table;
|
||||
_glapi_DispatchTSD = NULL;
|
||||
}
|
||||
else {
|
||||
_glapi_Dispatch = old_style_dispatch;
|
||||
_glapi_DispatchTSD = dispatch;
|
||||
}
|
||||
}
|
||||
#else /*THREADS*/
|
||||
if (DispatchOverride) {
|
||||
|
|
@ -336,7 +348,7 @@ struct _glapi_table *
|
|||
_glapi_get_dispatch(void)
|
||||
{
|
||||
#if defined(THREADS)
|
||||
if ( _glapi_DispatchTSD == NULL ) {
|
||||
if (ThreadSafe) {
|
||||
if (DispatchOverride) {
|
||||
return (struct _glapi_table *) _glthread_GetTSD(&RealDispatchTSD);
|
||||
}
|
||||
|
|
@ -394,8 +406,9 @@ _glapi_begin_dispatch_override(struct _glapi_table *override)
|
|||
|
||||
#if defined(THREADS)
|
||||
_glthread_SetTSD(&_gl_DispatchTSD, (void *) override);
|
||||
if ( _glapi_DispatchTSD == NULL ) {
|
||||
if ( ThreadSafe ) {
|
||||
_glapi_Dispatch = (struct _glapi_table *) __glapi_threadsafe_table;
|
||||
_glapi_DispatchTSD = NULL;
|
||||
}
|
||||
else {
|
||||
_glapi_Dispatch = override;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue