[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