[Patch] Fix gethwnd race

Brian Ford ford@vss.fsi.com
Fri May 7 00:18:00 GMT 2004


Although not the complete rewrite you may have been hoping for, the
attached patch does appear to fix the:

Winmain: Cannot register window class, Win32 error 1410

portion of this bug:

http://www.cygwin.com/ml/cygwin/2004-05/msg00232.html

I still see:

recv: No buffer space available

but have only pursued it to the point of being sure it is unrelated.  I'll
look at it more later if time permits.

2004-05-06  Brian Ford  <ford@vss.fsi.com>

	* window.cc (window_started): Change type to long and make NO_COPY.
	(Winmain): Use InterlockedExchange instead of SetEvent.
	(gethwnd): Fix initialization race using InterlockedExchange
	based state table.

-- 
Brian Ford
Senior Realtime Software Engineer
VITAL - Visual Simulation Systems
FlightSafety International
the best safety device in any aircraft is a well-trained pilot...
-------------- next part --------------
Index: window.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/window.cc,v
retrieving revision 1.30
diff -u -p -r1.30 window.cc
--- window.cc	9 Feb 2004 04:04:24 -0000	1.30
+++ window.cc	7 May 2004 00:02:31 -0000
@@ -73,7 +73,7 @@ WndProc (HWND hwnd, UINT uMsg, WPARAM wP
     }
 }
 
-static HANDLE window_started;
+static NO_COPY long window_started;
 
 static DWORD WINAPI
 Winmain (VOID *)
@@ -104,17 +104,17 @@ Winmain (VOID *)
   /* Create hidden window. */
   ourhwnd = CreateWindow (classname, classname, WS_POPUP, CW_USEDEFAULT,
 			  CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
-			  (HWND) NULL, (HMENU) NULL, user_data->hmodule,
-			  (LPVOID) NULL);
-
-  SetEvent (window_started);
+			  NULL, NULL, user_data->hmodule, NULL);
 
   if (!ourhwnd)
     {
       system_printf ("Cannot create window");
+      InterlockedExchange (&window_started, 0);
       return FALSE;
     }
 
+  InterlockedExchange (&window_started, 1);
+
   /* Start the message loop. */
 
   while (GetMessage (&msg, ourhwnd, 0, 0) == TRUE)
@@ -126,17 +126,22 @@ Winmain (VOID *)
 HWND __stdcall
 gethwnd ()
 {
-  if (ourhwnd != NULL)
-    return ourhwnd;
+  long ws = InterlockedExchange (&window_started, -1);
 
-  cygthread *h;
+  if (ws == 1)
+    InterlockedExchange (&window_started, 1);
+  else
+    {
+      if (ws == 0)
+	{
+	  cygthread *h = new cygthread (Winmain, NULL, "win");
+	  h->zap_h ();
+	}
+    
+      while (window_started == -1)
+	low_priority_sleep (0);
+    }
 
-  window_started = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
-  h = new cygthread (Winmain, NULL, "win");
-  h->SetThreadPriority (THREAD_PRIORITY_HIGHEST);
-  WaitForSingleObject (window_started, INFINITE);
-  CloseHandle (window_started);
-  h->zap_h ();
   return ourhwnd;
 }
 


More information about the Cygwin-patches mailing list