[Patch] Fix gethwnd race
Brian Ford
ford@vss.fsi.com
Thu May 13 19:58:00 GMT 2004
On Thu, 6 May 2004, Christopher Faylor wrote:
> Thanks, but, I see that you're using busy loops. I use those in places
> where I have no choice but to do so or when the potential for a race is
> unlikely.
>
> I don't think that this is really a situation that qualifies for either.
> It seems like a muto is a cleaner choice here.
Sorry for the delay; my free time has been in short supply lately.
I can't seem to make a muto fit this situation cleanly since it would have
to be acquired and released by the same thread. Maybe I missed something
obvious, but I think the attached patch addresses the root of your
objection to the previous patch.
2004-05-13 Brian Ford <ford@vss.fsi.com>
* window.cc (window_started): Make NO_COPY.
(gethwnd): Fix initialization race.
(window_init): New function to initialize window_started.
* winsup.h (window_init): Prototype it.
* dcrt0.cc (dll_crt0_1): Call it.
--
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 13 May 2004 16:34:33 -0000
@@ -73,7 +73,13 @@ WndProc (HWND hwnd, UINT uMsg, WPARAM wP
}
}
-static HANDLE window_started;
+static NO_COPY HANDLE window_started;
+
+void
+window_init ()
+{
+ window_started = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
+}
static DWORD WINAPI
Winmain (VOID *)
@@ -126,18 +132,29 @@ Winmain (VOID *)
HWND __stdcall
gethwnd ()
{
- if (ourhwnd != NULL)
- return ourhwnd;
+ static NO_COPY long window_waiters;
+ long waiters = InterlockedIncrement (&window_waiters);
+ HWND hwnd = ourhwnd;
+
+ if (hwnd == NULL)
+ {
+ if (waiters == 1)
+ {
+ cygthread *h = new cygthread (Winmain, NULL, "win");
+ h->zap_h ();
+ }
+
+ WaitForSingleObject (window_started, INFINITE);
+ hwnd = ourhwnd;
+ }
+
+ HANDLE ws;
- cygthread *h;
+ if (InterlockedDecrement (&window_waiters) == 0 && hwnd
+ && (ws = (HANDLE) InterlockedExchange ((long *) &window_started, 0)))
+ CloseHandle (ws);
- 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;
+ return hwnd;
}
extern "C" int
Index: winsup.h
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/winsup.h,v
retrieving revision 1.143
diff -u -p -r1.143 winsup.h
--- winsup.h 3 May 2004 11:53:07 -0000 1.143
+++ winsup.h 13 May 2004 16:34:33 -0000
@@ -218,6 +218,7 @@ void events_terminate (void);
void __stdcall close_all_files ();
/* Invisible window initialization/termination. */
+void window_init (void);
HWND __stdcall gethwnd (void);
/* Check if running in a visible window station. */
extern bool has_visible_window_station (void);
Index: dcrt0.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/dcrt0.cc,v
retrieving revision 1.218
diff -u -p -r1.218 dcrt0.cc
--- dcrt0.cc 12 Mar 2004 03:09:28 -0000 1.218
+++ dcrt0.cc 13 May 2004 16:34:33 -0000
@@ -799,6 +799,9 @@ dll_crt0_1 (char *)
/* Connect to tty. */
tty_init ();
+ /* Initialize hidden window for itimers/sockets. */
+ window_init ();
+
if (!__argc)
{
char *line = GetCommandLineA ();
More information about the Cygwin-patches
mailing list