summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2014-11-27 16:20:14 +0000
committerCorinna Vinschen <corinna@vinschen.de>2014-11-27 16:20:14 +0000
commitdb880b56427272aaea287a42541fe127dc5590a6 (patch)
tree9c5a094c3450cbff86ad658a4d72dc4022022d01
parent84b2a020daa17d8ee5c9ec979c3d56f95e69573b (diff)
downloadcygnal-db880b56427272aaea287a42541fe127dc5590a6.tar.gz
cygnal-db880b56427272aaea287a42541fe127dc5590a6.tar.bz2
cygnal-db880b56427272aaea287a42541fe127dc5590a6.zip
* cygheap.cc (init_cygheap::find_tls): Allow to keep loop going after
access to threadlist[ix] faulted. In case of an exception, remove threadlist[ix] from threadlist only. Add comment.
-rw-r--r--winsup/cygwin/ChangeLog6
-rw-r--r--winsup/cygwin/cygheap.cc46
2 files changed, 33 insertions, 19 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 443176095..ecb801b95 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,9 @@
+2014-11-27 Corinna Vinschen <corinna@vinschen.de>
+
+ * cygheap.cc (init_cygheap::find_tls): Allow to keep loop going after
+ access to threadlist[ix] faulted. In case of an exception, remove
+ threadlist[ix] from threadlist only. Add comment.
+
2014-11-26 Corinna Vinschen <corinna@vinschen.de>
* Makefile.in (install): Add install-ldif target.
diff --git a/winsup/cygwin/cygheap.cc b/winsup/cygwin/cygheap.cc
index ce7b02a86..9ac303eed 100644
--- a/winsup/cygwin/cygheap.cc
+++ b/winsup/cygwin/cygheap.cc
@@ -667,26 +667,34 @@ init_cygheap::find_tls (int sig, bool& issig_wait)
_cygtls *t = NULL;
issig_wait = false;
- __try
+ ix = -1;
+ /* Scan thread list looking for valid signal-delivery candidates */
+ while (++ix < (int) nthreads)
{
- ix = -1;
- /* Scan thread list looking for valid signal-delivery candidates */
- while (++ix < (int) nthreads)
- if (!threadlist[ix]->tid)
- continue;
- else if (sigismember (&(threadlist[ix]->sigwait_mask), sig))
- {
- t = cygheap->threadlist[ix];
- issig_wait = true;
- __leave;
- }
- else if (!t && !sigismember (&(threadlist[ix]->sigmask), sig))
- t = cygheap->threadlist[ix];
- }
- __except (NO_ERROR)
- {
- threadlist[ix]->remove (INFINITE);
+ __try
+ {
+ if (!threadlist[ix]->tid)
+ continue;
+ else if (sigismember (&(threadlist[ix]->sigwait_mask), sig))
+ {
+ t = cygheap->threadlist[ix];
+ issig_wait = true;
+ __leave;
+ }
+ else if (!t && !sigismember (&(threadlist[ix]->sigmask), sig))
+ t = cygheap->threadlist[ix];
+ }
+ __except (NO_ERROR)
+ {
+ /* We're here because threadlist[ix] became NULL or invalid. In
+ theory this should be impossible due to correct synchronization.
+ But *if* it happens, just remove threadlist[ix] from threadlist.
+ TODO: This should be totally unnecessary. */
+ debug_printf ("cygtls synchronization is leaking...");
+ remove_tls (threadlist[ix], 0);
+ --ix;
+ }
+ __endtry
}
- __endtry
return t;
}