summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/DevNotes
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2012-06-03 02:59:20 +0000
committerChristopher Faylor <me@cgf.cx>2012-06-03 02:59:20 +0000
commit45b61a88becdc9477826f6576b97e75b8ee49f37 (patch)
tree5e200dcbb1f35953d8ba1391de2b7086f14eeaec /winsup/cygwin/DevNotes
parentfaab45455a469db4ca5c4d230e7dd97dfa56382c (diff)
downloadcygnal-45b61a88becdc9477826f6576b97e75b8ee49f37.tar.gz
cygnal-45b61a88becdc9477826f6576b97e75b8ee49f37.tar.bz2
cygnal-45b61a88becdc9477826f6576b97e75b8ee49f37.zip
* DevNotes: Add entry cgf-000010.
* select.cc (set_handle_or_return_if_not_open): Remove unneeded final backslash from definition. (cygwin_select): Reorganize to incorporate outer retry loop. Move remaining time recalculation here for retry case. Use select_stuff::wait_states for loop control. (select_stuff::cleanup): Avoid unneeded initialization. (select_stuff::wait): Modify definition to return select_stuff::wait_states. Eliminate is_cancelable. Don't element 1 of an array if it is a cancel handle. Remove loop. Rely on being called from enclosing loop in cygwin_select. Remove time recalculation when restarting. Try harder to always return from the bottom. * select.h (select_stuff::wait_state): New enum. (select_stuff::wait): Modify declaration to return select_stuff::wait_states.
Diffstat (limited to 'winsup/cygwin/DevNotes')
-rw-r--r--winsup/cygwin/DevNotes42
1 files changed, 42 insertions, 0 deletions
diff --git a/winsup/cygwin/DevNotes b/winsup/cygwin/DevNotes
index 3b97e9e86..778a5d059 100644
--- a/winsup/cygwin/DevNotes
+++ b/winsup/cygwin/DevNotes
@@ -1,3 +1,45 @@
+2012-06-02 cgf-000010
+
+<1.7.16>
+- Fix emacs problem which exposed an issue with Cygwin's select() function.
+ If a signal arrives while select is blocking and the program longjmps
+ out of the signal handler then threads and memory may be left hanging.
+ Fixes: http://cygwin.com/ml/cygwin/2012-05/threads.html#00275
+</1.7.16>
+
+This was try #4 or #5 to get select() signal handling working right.
+It's still not there but it should now at least not leak memory or
+threads.
+
+I mucked with the interface between cygwin_select and select_stuff::wait
+so that the "new" loop in select_stuff::wait() was essentially moved
+into the caller. cygwin_select now uses various enum states to decide
+what to do. It builds the select linked list at the beginning of the
+loop, allowing wait() to tear everything down and restart. This is
+necessary before calling a signal handler because the signal handler may
+longjmp away.
+
+I initially had this all coded up to use a special signal_cleanup
+callback which could be called when a longjmp is called in a signal
+handler. And cygwin_select() set up and tore down this callback. Once
+I got everything compiling it, of course, dawned on me that just because
+you call a longjmp in a signal handler it doesn't mean that you are
+jumping *out* of the signal handler. So, if the signal handler invokes
+the callback and returns it will be very bad for select(). Hence, this
+slower, but hopefully more correct implementation.
+
+(I still wonder if some sort of signal cleanup callback might still
+be useful in the future)
+
+TODO: I need to do an audit of other places where this problem could be
+occurring.
+
+As alluded to above, select's signal handling is still not right. It
+still acts as if it could call a signal handler from something other
+than the main thread but, AFAICT, from my STC, this doesn't seem to be
+the case. It might be worthwhile to extend cygwait to just magically
+figure this out and not even bother using w4[0] for scenarios like this.
+
2012-05-16 cgf-000009
<1.7.16>