Make initializing the ICD in ROSGL_ICDForHDC thread-safe

svn path=/trunk/; revision=30430
This commit is contained in:
Thomas Bluemel 2007-11-14 00:01:36 +00:00
parent 65636af627
commit cf3352e6bc

View file

@ -294,6 +294,7 @@ GLDRIVERDATA *
ROSGL_ICDForHDC( HDC hdc ) ROSGL_ICDForHDC( HDC hdc )
{ {
GLDCDATA *dcdata; GLDCDATA *dcdata;
GLDRIVERDATA *drvdata;
dcdata = ROSGL_GetPrivateDCData( hdc ); dcdata = ROSGL_GetPrivateDCData( hdc );
if (dcdata == NULL) if (dcdata == NULL)
@ -304,6 +305,9 @@ ROSGL_ICDForHDC( HDC hdc )
LPCWSTR driverName; LPCWSTR driverName;
OPENGL_INFO info; OPENGL_INFO info;
/* NOTE: This might be done by multiple threads simultaneously, but only the fastest
actually gets to set the ICD! */
driverName = _wgetenv( L"OPENGL32_DRIVER" ); driverName = _wgetenv( L"OPENGL32_DRIVER" );
if (driverName == NULL) if (driverName == NULL)
{ {
@ -336,7 +340,7 @@ ROSGL_ICDForHDC( HDC hdc )
} }
/* open registry key */ /* open registry key */
ret = RegOpenKeyExW( HKEY_LOCAL_MACHINE, OPENGL_DRIVERS_SUBKEY, 0, KEY_READ, &hKey ); ret = RegOpenKeyExW( HKEY_LOCAL_MACHINE, OPENGL_DRIVERS_SUBKEY, 0, KEY_QUERY_VALUE, &hKey );
if (ret != ERROR_SUCCESS) if (ret != ERROR_SUCCESS)
{ {
DBGPRINT( "Error: Couldn't open registry key '%ws'", OPENGL_DRIVERS_SUBKEY ); DBGPRINT( "Error: Couldn't open registry key '%ws'", OPENGL_DRIVERS_SUBKEY );
@ -361,8 +365,8 @@ ROSGL_ICDForHDC( HDC hdc )
wcsncpy( info.DriverName, driverName, sizeof (info.DriverName) / sizeof (info.DriverName[0]) ); wcsncpy( info.DriverName, driverName, sizeof (info.DriverName) / sizeof (info.DriverName[0]) );
} }
/* load driver (or get a reference) */ /* load driver (or get a reference) */
dcdata->icd = OPENGL32_LoadICD( info.DriverName ); drvdata = OPENGL32_LoadICD( info.DriverName );
if (dcdata->icd == NULL) if (drvdata == NULL)
{ {
WCHAR Buffer[256]; WCHAR Buffer[256];
snwprintf(Buffer, sizeof(Buffer)/sizeof(WCHAR), snwprintf(Buffer, sizeof(Buffer)/sizeof(WCHAR),
@ -371,6 +375,17 @@ ROSGL_ICDForHDC( HDC hdc )
L"OPENGL32.dll: Warning", L"OPENGL32.dll: Warning",
MB_OK | MB_ICONWARNING); MB_OK | MB_ICONWARNING);
} }
else
{
/* Atomically set the ICD!!! */
if (InterlockedCompareExchangePointer((PVOID*)&dcdata->icd,
(PVOID)drvdata,
NULL) != NULL)
{
/* Too bad, somebody else was faster... */
OPENGL32_UnloadICD(drvdata);
}
}
} }
return dcdata->icd; return dcdata->icd;