diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 99bcc9370..a2936bf40 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,19 @@ +2005-02-03 Christopher Faylor + + * cygthread.h (cygthread::terminate_thread): Reflect return value. + * cygthread.cc (cygthread::detach): Be more careful about ensuring that + sigwait is properly waited for to avoid later missynchronization. + (cygthread::terminate_thread): Return true if thread was actually + terminated and all handles were closed. + * fhandler_base.cc (fhandler_base::raw_read): Use signal_read_state + rather than raw calls to win32 api. + (fhandler_base::read): Ditto. + * fhandler.h (fhandler_pipe::fixup_after_exec): Use method to create + read_state signalling. + (fhandler_pipe::create): Ditto. + + * Makefile.in: Make some more files -fomit-frame-pointer. + 2005-02-02 Corinna Vinschen * fhandler.h (fhandler_base::ftruncate): Define new virtual method. diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in index efdd31fef..de9c9f8bb 100644 --- a/winsup/cygwin/Makefile.in +++ b/winsup/cygwin/Makefile.in @@ -250,9 +250,11 @@ fhandler_virtual_CFLAGS:=-fomit-frame-pointer fhandler_windows_CFLAGS:=-fomit-frame-pointer fhandler_zero_CFLAGS:=-fomit-frame-pointer flock_CFLAGS:=-fomit-frame-pointer +grp_CFLAGS:=-fomit-frame-pointer malloc_CFLAGS:=-fomit-frame-pointer malloc_wrapper_CFLAGS:=-fomit-frame-pointer miscfuncs_CFLAGS:=-fomit-frame-pointer +passwd_CFLAGS:=-fomit-frame-pointer regcomp_CFLAGS=-fomit-frame-pointer regerror_CFLAGS=-fomit-frame-pointer regexec_CFLAGS=-fomit-frame-pointer diff --git a/winsup/cygwin/cygthread.cc b/winsup/cygwin/cygthread.cc index 3f8286a88..c6ae0249c 100644 --- a/winsup/cygwin/cygthread.cc +++ b/winsup/cygwin/cygthread.cc @@ -243,9 +243,10 @@ cygthread::release (bool nuke_h) } /* Forcibly terminate a thread. */ -void +bool cygthread::terminate_thread () { + bool terminated = true; /* FIXME: The if (!inuse) stuff below should be handled better. The problem is that terminate_thread could be called while a thread is terminating and either the thread could be handling its own @@ -264,19 +265,19 @@ cygthread::terminate_thread () low_priority_sleep (0); if (!inuse) - return; + return false; (void) TerminateThread (h, 0); (void) WaitForSingleObject (h, INFINITE); if (ev) - WaitForSingleObject (ev, 0); + terminated = WaitForSingleObject (ev, 0) != WAIT_OBJECT_0; if (!inuse || exiting) - return; + return false; CloseHandle (h); if (!inuse) - return; + return false; MEMORY_BASIC_INFORMATION m; memset (&m, 0, sizeof (m)); @@ -299,6 +300,7 @@ cygthread::terminate_thread () #endif release (true); } + return terminated; } /* Detach the cygthread from the current thread. Note that the @@ -309,6 +311,7 @@ bool cygthread::detach (HANDLE sigwait) { bool signalled = false; + bool terminated = false; if (!inuse) system_printf ("called detach but inuse %d, thread %p?", inuse, id); else @@ -327,22 +330,27 @@ cygthread::detach (HANDLE sigwait) system_printf ("WFSO sigwait %p failed, res %u, %E", sigwait, res); res = WaitForMultipleObjects (2, w4, FALSE, INFINITE); if (res == WAIT_OBJECT_0) - /* nothing */; - else if (WaitForSingleObject (sigwait, 0) == WAIT_OBJECT_0) - res = WaitForSingleObject (*this, INFINITE); - else if ((res = WaitForSingleObject (*this, 0)) != WAIT_OBJECT_0) + signalled = false; + else if (res != WAIT_OBJECT_0 + 1) + api_fatal ("WFMO failed waiting for cygthread '%s'", __name); + else if ((res = WaitForSingleObject (*this, INFINITE)) == WAIT_OBJECT_0) + signalled = false; + else { - signalled = true; - terminate_thread (); - set_sig_errno (EINTR); /* caller should be dealing with return - values. */ + terminated = true; + signalled = terminate_thread (); } + if (WaitForSingleObject (sigwait, 0) == WAIT_OBJECT_0) + signalled = false; + else if (signalled) + set_sig_errno (EINTR); /* caller should be dealing with return + values. */ } thread_printf ("%s returns %d, id %p", sigwait ? "WFMO" : "WFSO", res, id); - if (signalled) + if (terminated) /* already handled */; else if (is_freerange) { diff --git a/winsup/cygwin/cygthread.h b/winsup/cygwin/cygthread.h index 73465ba72..e1c2e495f 100644 --- a/winsup/cygwin/cygthread.h +++ b/winsup/cygwin/cygthread.h @@ -27,7 +27,7 @@ class cygthread bool is_freerange; static bool exiting; public: - void terminate_thread (); + bool terminate_thread (); static DWORD WINAPI stub (VOID *); static DWORD WINAPI simplestub (VOID *); static DWORD main_thread_id; diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index aa996ea56..1a18b7550 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -231,14 +231,9 @@ fhandler_base::raw_read (void *ptr, size_t& ulen) h = GetCurrentThread (); prio = GetThreadPriority (h); (void) SetThreadPriority (h, THREAD_PRIORITY_TIME_CRITICAL); - SetEvent (read_state); + signal_read_state (1); } BOOL res = ReadFile (get_handle (), ptr, len, (DWORD *) &ulen, 0); - if (read_state) - { - SetEvent (read_state); - (void) SetThreadPriority (h, prio); - } if (!res) { /* Some errors are not really errors. Detect such cases here. */ @@ -275,6 +270,11 @@ fhandler_base::raw_read (void *ptr, size_t& ulen) break; } } + if (read_state) + { + signal_read_state (1); + (void) SetThreadPriority (h, prio); + } #undef bytes_read } @@ -705,8 +705,8 @@ fhandler_base::read (void *in_ptr, size_t& len) goto out; } - raw_read (ptr + copied_chars, len); need_signal = false; + raw_read (ptr + copied_chars, len); if (!copied_chars) /* nothing */; else if ((ssize_t) len > 0) @@ -775,7 +775,7 @@ fhandler_base::read (void *in_ptr, size_t& len) out: if (need_signal) - SetEvent (read_state); + signal_read_state (2); debug_printf ("returning %d, %s mode", len, rbinary () ? "binary" : "text"); return; diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index f710356bf..2f2f01706 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -193,6 +193,15 @@ class fhandler_base virtual void fixup_before_fork_exec (DWORD) {} virtual void fixup_after_fork (HANDLE); virtual void fixup_after_exec () {} + void create_read_state (LONG n) + { + read_state = CreateSemaphore (&sec_none_nih, 0, n, NULL); + } + + void signal_read_state (LONG n) + { + (void) ReleaseSemaphore (read_state, n, NULL); + } void set_fs_flags (DWORD flags) { fs_flags = flags; } bool get_fs_flags (DWORD flagval = UINT32_MAX) diff --git a/winsup/cygwin/pipe.cc b/winsup/cygwin/pipe.cc index 498b17206..58cf0109d 100644 --- a/winsup/cygwin/pipe.cc +++ b/winsup/cygwin/pipe.cc @@ -177,7 +177,7 @@ fhandler_pipe::fixup_after_exec () { if (read_state) { - read_state = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); + create_read_state (2); ProtectHandle (read_state); } } @@ -410,7 +410,7 @@ fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode, bool fif fhs[1]->close_on_exec (true); } - fhs[0]->read_state = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); + fhs[0]->create_read_state (2); fhs[0]->need_fork_fixup (true); ProtectHandle1 (fhs[0]->read_state, read_state);