I've found and fixed another bug related to signal handling - sigcx's
non-GTK library doesn't handle select() bailing due to EINTR, and
generates spurious file events as a result. This is patch-6 in my arch
branch, the following diff as attached, and I've updated the pretend-NMU
to -2.4 which contains it.
Fix interruption of select() by a signal causing spurrious file events.
The select() loop wasn't being restarted on EINTR, wrap it in such a loop.
Previously, it'd cause a fall-through into attempting to read fd sets
that hadn't been initialized, and would generate spurrious file events as a
result.
- Steven Brown <[EMAIL PROTECTED]>
--- orig/sigcx/dispatch.cc
+++ mod/sigcx/dispatch.cc
@@ -357,31 +357,36 @@
fd_set wr = wr_fds_;
fd_set ex = ex_fds_;
- if (tm_events_.size() == 0)
+ // Loop on select, restarting if we were interrupted by a signal.
+ int result;
+ do
{
- UnGuard unguard (mutex_);
- int result = select(FD_SETSIZE, &rd, &wr, &ex, 0);
- assert(result != -1 || errno == EINTR);
- }
- else
- {
- now.get_current_time();
- timeout = tm_events_.begin()->first.expiration - now;
+ if (tm_events_.size() == 0)
+ {
+ UnGuard unguard (mutex_);
+ result = select(FD_SETSIZE, &rd, &wr, &ex, 0);
+ assert(result != -1 || errno == EINTR);
+ }
+ else
+ {
+ now.get_current_time();
+ timeout = tm_events_.begin()->first.expiration - now;
- UnGuard unguard(mutex_);
-
- if (timeout < TimeVal(0))
- timeout = TimeVal(0);
-
- struct timeval tv;
- tv.tv_sec = timeout.tv_sec;
- tv.tv_usec = timeout.tv_usec;
-
- int result = select(FD_SETSIZE, &rd, &wr, &ex, &tv);
- assert(result != -1 || errno == EINTR);
- }
+ UnGuard unguard(mutex_);
+
+ if (timeout < TimeVal(0))
+ timeout = TimeVal(0);
+
+ struct timeval tv;
+ tv.tv_sec = timeout.tv_sec;
+ tv.tv_usec = timeout.tv_usec;
+
+ result = select(FD_SETSIZE, &rd, &wr, &ex, &tv);
+ assert(result != -1 || errno == EINTR);
+ }
+ } while(result == -1 && errno == EINTR);
- // check after select, we might have caught a signal
+ // check if we've been asked to exit. If so, exit early.
if (do_exit_)
break;