Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2011-12-14 00:06:31 +0400
committerChristopher Faylor <me@cgf.cx>2011-12-14 00:06:31 +0400
commit45d7b637fa74ac79469892653188e2554f151633 (patch)
tree1a23cbc08e233079ef13732fc7f36525befa2938 /winsup
parent8d1bda71b4538fe0c4dee14f057645da33443a9e (diff)
* dcrt0.cc (init_windows_system_directory): Record system_wow64_directory
information. * exceptions.cc (_cygtls::inside_kernel): Modernize comment. Consider executing a DLL from the Wow64 directory as being "in the kernel". (_cygtls::call_signal_handler): For now, only deal with main_tls signals if main_tls is known to be executing in the cygwin DLL. To more closely emulate linux, consider the operation to be restartable if not executing in the main thread. * globals.cc (windows_system_directory): Remove NO_COPY. (windows_system_directory_length): Ditto. (system_wow64_directory): New variable. (system_wow64_directory_length): Ditto. * select.cc (cygwin_select): Don't issue a EINTR on non-main threads since that seems to be what Linux does. Add missing break to signal case/switch. (select_stuff::wait): Don't issue a EINTR on non-main threads since that seems to be what Linux does. Remove now-unneeded accommodation for WAIT_IO_COMPLETION. Add a comment. * sigproc.h (cygwait): Ditto. Don't return if signal_received noticed and it's not the main thread. * signal.cc (sigprocmask): Add standard syscall debug stuff. * thread.cc (pthread_sigmask): Ditto.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog27
-rw-r--r--winsup/cygwin/dcrt0.cc23
-rw-r--r--winsup/cygwin/exceptions.cc20
-rw-r--r--winsup/cygwin/globals.cc6
-rw-r--r--winsup/cygwin/select.cc48
-rw-r--r--winsup/cygwin/signal.cc8
-rw-r--r--winsup/cygwin/sigproc.h2
-rw-r--r--winsup/cygwin/thread.cc4
8 files changed, 95 insertions, 43 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index cb9579f48..154e608e7 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,30 @@
+2011-12-13 Christopher Faylor <me.cygwin2011@cgf.cx>
+
+ * dcrt0.cc (init_windows_system_directory): Record
+ system_wow64_directory information.
+ * exceptions.cc (_cygtls::inside_kernel): Modernize comment. Consider
+ executing a DLL from the Wow64 directory as being "in the kernel".
+ (_cygtls::call_signal_handler): For now, only deal with main_tls
+ signals if main_tls is known to be executing in the cygwin DLL. To
+ more closely emulate linux, consider the operation to be restartable if
+ not executing in the main thread.
+ * globals.cc (windows_system_directory): Remove NO_COPY.
+ (windows_system_directory_length): Ditto.
+ (system_wow64_directory): New variable.
+ (system_wow64_directory_length): Ditto.
+
+ * select.cc (cygwin_select): Don't issue a EINTR on non-main threads
+ since that seems to be what Linux does. Add missing break to signal
+ case/switch.
+ (select_stuff::wait): Don't issue a EINTR on non-main threads since
+ that seems to be what Linux does. Remove now-unneeded accommodation
+ for WAIT_IO_COMPLETION. Add a comment.
+ * sigproc.h (cygwait): Ditto. Don't return if signal_received noticed
+ and it's not the main thread.
+
+ * signal.cc (sigprocmask): Add standard syscall debug stuff.
+ * thread.cc (pthread_sigmask): Ditto.
+
2011-12-13 Corinna Vinschen <vinschen@redhat.com>
* netdb.cc (open_system_file): Avoid MS-DOS path warning.
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 5364e4dd8..b6392acf2 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -638,12 +638,23 @@ child_info_spawn::handle_spawn ()
static void
init_windows_system_directory ()
{
- windows_system_directory_length =
- GetSystemDirectoryW (windows_system_directory, MAX_PATH);
- if (windows_system_directory_length == 0)
- api_fatal ("can't find windows system directory");
- windows_system_directory[windows_system_directory_length++] = L'\\';
- windows_system_directory[windows_system_directory_length] = L'\0';
+ if (!windows_system_directory_length)
+ {
+ windows_system_directory_length =
+ GetSystemDirectoryW (windows_system_directory, MAX_PATH);
+ if (windows_system_directory_length == 0)
+ api_fatal ("can't find windows system directory");
+ windows_system_directory[windows_system_directory_length++] = L'\\';
+ windows_system_directory[windows_system_directory_length] = L'\0';
+
+ system_wow64_directory_length =
+ GetSystemWow64DirectoryW (system_wow64_directory, MAX_PATH);
+ if (system_wow64_directory_length)
+ {
+ system_wow64_directory[system_wow64_directory_length++] = L'\\';
+ system_wow64_directory[system_wow64_directory_length] = L'\0';
+ }
+ }
}
static bool NO_COPY wow64_respawn = false;
diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc
index 97f04b2ec..0ab89441b 100644
--- a/winsup/cygwin/exceptions.cc
+++ b/winsup/cygwin/exceptions.cc
@@ -326,10 +326,7 @@ _cygtls::inside_kernel (CONTEXT *cx)
memset (checkdir, 0, size);
# define h ((HMODULE) m.AllocationBase)
- /* Apparently Windows 95 can sometimes return bogus addresses from
- GetThreadContext. These resolve to a strange allocation base.
- These should *never* be treated as interruptible. */
- if (!h || m.State != MEM_COMMIT)
+ if (!h || m.State != MEM_COMMIT) /* Be defensive */
res = true;
else if (h == user_data->hmodule)
res = false;
@@ -340,8 +337,12 @@ _cygtls::inside_kernel (CONTEXT *cx)
/* Skip potential long path prefix. */
if (!wcsncmp (checkdir, L"\\\\?\\", 4))
checkdir += 4;
- res = !wcsncasecmp (windows_system_directory, checkdir,
- windows_system_directory_length);
+ res = wcsncasecmp (windows_system_directory, checkdir,
+ windows_system_directory_length) == 0;
+ if (!res && system_wow64_directory_length)
+ res = wcsncasecmp (system_wow64_directory, checkdir,
+ system_wow64_directory_length) == 0;
+
}
sigproc_printf ("pc %p, h %p, inside_kernel %d", cx->Eip, h, res);
# undef h
@@ -828,7 +829,6 @@ set_sig_errno (int e)
{
*_my_tls.errno_addr = e;
_my_tls.saved_errno = e;
- // sigproc_printf ("errno %d", e);
}
static int setup_handler (int, void *, struct sigaction&, _cygtls *tls)
@@ -1328,9 +1328,9 @@ _cygtls::call_signal_handler ()
else if (this != _main_tls)
{
_main_tls->lock ();
- if (_main_tls->sig)
+ if (_main_tls->sig && _main_tls->incyg)
{
- paranoid_printf ("Redirecting to main_tls signal %d", _main_tls->sig);
+ small_printf ("Redirecting to main_tls signal %d", _main_tls->sig);
sig = _main_tls->sig;
sa_flags = _main_tls->sa_flags;
func = _main_tls->func;
@@ -1373,7 +1373,7 @@ _cygtls::call_signal_handler ()
}
unlock ();
- return this_sa_flags & SA_RESTART;
+ return this_sa_flags & SA_RESTART || (this != _main_tls);
}
void
diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc
index 413c8730a..07bfe2feb 100644
--- a/winsup/cygwin/globals.cc
+++ b/winsup/cygwin/globals.cc
@@ -23,8 +23,10 @@ HANDLE NO_COPY hProcToken;
HANDLE NO_COPY hProcImpToken;
HMODULE NO_COPY cygwin_hmodule;
int NO_COPY sigExeced;
-WCHAR NO_COPY windows_system_directory[MAX_PATH];
-UINT NO_COPY windows_system_directory_length;
+WCHAR windows_system_directory[MAX_PATH];
+UINT windows_system_directory_length;
+WCHAR system_wow64_directory[MAX_PATH];
+UINT system_wow64_directory_length;
/* program exit the program */
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index 77a78c427..5e6baa6f5 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -129,23 +129,28 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
fd_set *w = allocfd_set (maxfds);
fd_set *e = allocfd_set (maxfds);
- int res = 1;
+ int res = 0;
/* Degenerate case. No fds to wait for. Just wait. */
if (sel.start.next == NULL)
- switch (cygwait (ms))
- {
- case WAIT_OBJECT_0:
- select_printf ("signal received");
- set_sig_errno (EINTR);
- res = -1;
- case WAIT_OBJECT_0 + 1:
- sel.destroy ();
- pthread::static_cancel_self ();
- /*NOTREACHED*/
- default:
- res = 1;
- break;
- }
+ while (!res)
+ switch (cygwait (ms))
+ {
+ case WAIT_OBJECT_0:
+ _my_tls.call_signal_handler ();
+ if (&_my_tls != _main_tls)
+ continue; /* Emulate linux behavior */
+ select_printf ("signal received");
+ set_sig_errno (EINTR);
+ res = -1;
+ break;
+ case WAIT_OBJECT_0 + 1:
+ sel.destroy ();
+ pthread::static_cancel_self ();
+ /*NOTREACHED*/
+ default:
+ res = 1; /* temporary flag. Will be set to zero below. */
+ break;
+ }
else if (sel.always_ready || ms == 0)
res = 0;
else
@@ -321,12 +326,11 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
MWMO_INPUTAVAILABLE);
switch (wait_ret)
- {
- case WAIT_IO_COMPLETION:
- syscall_printf ("woke due to apc");
- continue; /* Keep going */
- break;
+ {
case WAIT_OBJECT_0:
+ _my_tls.call_signal_handler ();
+ if (&_my_tls != _main_tls)
+ continue; /* Emulate linux behavior */
cleanup ();
select_printf ("signal received");
set_sig_errno (EINTR);
@@ -338,6 +342,8 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
destroy ();
pthread::static_cancel_self ();
}
+ /* This wasn't a cancel event. It was just a normal object to wait
+ for. */
break;
case WAIT_FAILED:
cleanup ();
@@ -350,7 +356,7 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
select_printf ("timed out");
res = 1;
goto out;
- }
+ }
select_printf ("woke up. wait_ret %d. verifying", wait_ret);
s = &start;
diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc
index 272fb366e..482ccd213 100644
--- a/winsup/cygwin/signal.cc
+++ b/winsup/cygwin/signal.cc
@@ -182,8 +182,12 @@ sigprocmask (int how, const sigset_t *set, sigset_t *oldset)
{
int res = handle_sigprocmask (how, set, oldset, _my_tls.sigmask);
if (res)
- set_errno (res);
- return res ? -1 : 0;
+ {
+ set_errno (res);
+ res = -1;
+ }
+ syscall_printf ("%R = sigprocmask (%d, %p, %p)", res, set, oldset);
+ return res;
}
int __stdcall
diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h
index 0cfac8699..f5547154d 100644
--- a/winsup/cygwin/sigproc.h
+++ b/winsup/cygwin/sigproc.h
@@ -100,7 +100,7 @@ cygwait (HANDLE h, DWORD howlong = INFINITE)
n++;
DWORD res;
while ((res = WaitForMultipleObjects (n, w4, FALSE, howlong)) == wait_signal
- && _my_tls.call_signal_handler ())
+ && (_my_tls.call_signal_handler () || &_my_tls != _main_tls))
continue;
return res;
}
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index 2f7d79460..52bca9839 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -3087,7 +3087,9 @@ pthread_kill (pthread_t thread, int sig)
extern "C" int
pthread_sigmask (int operation, const sigset_t *set, sigset_t *old_set)
{
- return handle_sigprocmask (operation, set, old_set, _my_tls.sigmask);
+ int res = handle_sigprocmask (operation, set, old_set, _my_tls.sigmask);
+ syscall_printf ("%d = pthread_sigmask(%d, %p, %p)", operation, set, old_set);
+ return res;
}
/* ID */