[ros-diffs] [weiden] 30430: Make initializing the ICD in ROSGL_ICDForHDC thread-safe

weiden at svn.reactos.org weiden at svn.reactos.org
Wed Nov 14 01:01:36 CET 2007


Author: weiden
Date: Wed Nov 14 03:01:36 2007
New Revision: 30430

URL: http://svn.reactos.org/svn/reactos?rev=30430&view=rev
Log:
Make initializing the ICD in ROSGL_ICDForHDC thread-safe

Modified:
    trunk/reactos/dll/win32/opengl32/wgl.c

Modified: trunk/reactos/dll/win32/opengl32/wgl.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/opengl32/wgl.c?rev=30430&r1=30429&r2=30430&view=diff
==============================================================================
--- trunk/reactos/dll/win32/opengl32/wgl.c (original)
+++ trunk/reactos/dll/win32/opengl32/wgl.c Wed Nov 14 03:01:36 2007
@@ -294,6 +294,7 @@
 ROSGL_ICDForHDC( HDC hdc )
 {
 	GLDCDATA *dcdata;
+	GLDRIVERDATA *drvdata;
 
 	dcdata = ROSGL_GetPrivateDCData( hdc );
 	if (dcdata == NULL)
@@ -303,6 +304,9 @@
 	{
 		LPCWSTR driverName;
 		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" );
 		if (driverName == NULL)
@@ -336,7 +340,7 @@
 				}
 
 				/* 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)
 				{
 					DBGPRINT( "Error: Couldn't open registry key '%ws'", OPENGL_DRIVERS_SUBKEY );
@@ -361,8 +365,8 @@
 			wcsncpy( info.DriverName, driverName, sizeof (info.DriverName) / sizeof (info.DriverName[0]) );
 		}
 		/* load driver (or get a reference) */
-		dcdata->icd = OPENGL32_LoadICD( info.DriverName );
-		if (dcdata->icd == NULL)
+		drvdata = OPENGL32_LoadICD( info.DriverName );
+		if (drvdata == NULL)
 		{
 			WCHAR Buffer[256];
 			snwprintf(Buffer, sizeof(Buffer)/sizeof(WCHAR),
@@ -370,6 +374,17 @@
 			MessageBox(WindowFromDC( hdc ), Buffer,
 			           L"OPENGL32.dll: Warning",
 			           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);
+			}
 		}
 	}
 




More information about the Ros-diffs mailing list