diff options
| -rw-r--r-- | opentracker.c | 2 | ||||
| -rw-r--r-- | ot_event.c | 18 | ||||
| -rw-r--r-- | tests/integration/harness.py | 6 |
3 files changed, 19 insertions, 7 deletions
diff --git a/opentracker.c b/opentracker.c index 34b8fd5..a546fc5 100644 --- a/opentracker.c +++ b/opentracker.c | |||
| @@ -84,7 +84,7 @@ static void install_signal_handlers(void) { | |||
| 84 | 84 | ||
| 85 | sa.sa_handler = signal_handler; | 85 | sa.sa_handler = signal_handler; |
| 86 | sigemptyset(&sa.sa_mask); | 86 | sigemptyset(&sa.sa_mask); |
| 87 | sa.sa_flags = SA_RESTART; | 87 | sa.sa_flags = 0; |
| 88 | if ((sigaction(SIGINT, &sa, NULL) == -1) || (sigaction(SIGALRM, &sa, NULL) == -1)) | 88 | if ((sigaction(SIGINT, &sa, NULL) == -1) || (sigaction(SIGALRM, &sa, NULL) == -1)) |
| 89 | panic("install_signal_handlers"); | 89 | panic("install_signal_handlers"); |
| 90 | 90 | ||
| @@ -83,8 +83,10 @@ int event_wait(ot_event *out, int max, int timeout_ms) { | |||
| 83 | g_ready_space = max; | 83 | g_ready_space = max; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | while ((count = epoll_wait(g_epoll, g_ready, max, timeout_ms)) == -1 && errno == EINTR) | 86 | /* An interrupted wait is reported as no events rather than retried here, |
| 87 | ; | 87 | so that the caller gets to look at whatever the signal was about */ |
| 88 | if ((count = epoll_wait(g_epoll, g_ready, max, timeout_ms)) == -1) | ||
| 89 | return errno == EINTR ? 0 : -1; | ||
| 88 | for (i = 0; i < count; ++i) { | 90 | for (i = 0; i < count; ++i) { |
| 89 | uint32_t events = g_ready[i].events; | 91 | uint32_t events = g_ready[i].events; |
| 90 | 92 | ||
| @@ -189,8 +191,10 @@ int event_wait(ot_event *out, int max, int timeout_ms) { | |||
| 189 | deadline = &timeout; | 191 | deadline = &timeout; |
| 190 | } | 192 | } |
| 191 | 193 | ||
| 192 | while ((count = kevent(g_kqueue, NULL, 0, g_ready, max, deadline)) == -1 && errno == EINTR) | 194 | /* An interrupted wait is reported as no events rather than retried here, |
| 193 | ; | 195 | so that the caller gets to look at whatever the signal was about */ |
| 196 | if ((count = kevent(g_kqueue, NULL, 0, g_ready, max, deadline)) == -1) | ||
| 197 | return errno == EINTR ? 0 : -1; | ||
| 194 | for (i = 0; i < count; ++i) { | 198 | for (i = 0; i < count; ++i) { |
| 195 | uint64_t udata = (uint64_t)(uintptr_t)g_ready[i].udata; | 199 | uint64_t udata = (uint64_t)(uintptr_t)g_ready[i].udata; |
| 196 | int eof = (g_ready[i].flags & (EV_EOF | EV_ERROR)) != 0; | 200 | int eof = (g_ready[i].flags & (EV_EOF | EV_ERROR)) != 0; |
| @@ -310,8 +314,10 @@ int event_del(int fd) { | |||
| 310 | int event_wait(ot_event *out, int max, int timeout_ms) { | 314 | int event_wait(ot_event *out, int max, int timeout_ms) { |
| 311 | int ready, found = 0, i; | 315 | int ready, found = 0, i; |
| 312 | 316 | ||
| 313 | while ((ready = poll(g_pfds, (nfds_t)g_count, timeout_ms)) == -1 && errno == EINTR) | 317 | /* An interrupted wait is reported as no events rather than retried here, |
| 314 | ; | 318 | so that the caller gets to look at whatever the signal was about */ |
| 319 | if ((ready = poll(g_pfds, (nfds_t)g_count, timeout_ms)) == -1) | ||
| 320 | return errno == EINTR ? 0 : -1; | ||
| 315 | if (ready <= 0) | 321 | if (ready <= 0) |
| 316 | return ready; | 322 | return ready; |
| 317 | 323 | ||
diff --git a/tests/integration/harness.py b/tests/integration/harness.py index 03a0561..122c36d 100644 --- a/tests/integration/harness.py +++ b/tests/integration/harness.py | |||
| @@ -121,6 +121,7 @@ class Tracker: | |||
| 121 | all: LeakSanitizer reports from an exit handler, so a killed tracker | 121 | all: LeakSanitizer reports from an exit handler, so a killed tracker |
| 122 | reports nothing and the suite passes over leaks it never looked for. | 122 | reports nothing and the suite passes over leaks it never looked for. |
| 123 | """ | 123 | """ |
| 124 | refused_to_exit = False | ||
| 124 | if self.process is not None and self.process.poll() is None: | 125 | if self.process is not None and self.process.poll() is None: |
| 125 | self.process.send_signal(signal.SIGINT) | 126 | self.process.send_signal(signal.SIGINT) |
| 126 | try: | 127 | try: |
| @@ -128,11 +129,16 @@ class Tracker: | |||
| 128 | except subprocess.TimeoutExpired: | 129 | except subprocess.TimeoutExpired: |
| 129 | self.process.kill() | 130 | self.process.kill() |
| 130 | self.process.wait() | 131 | self.process.wait() |
| 132 | refused_to_exit = True | ||
| 131 | complaints = [ | 133 | complaints = [ |
| 132 | line | 134 | line |
| 133 | for line in self.output().splitlines() | 135 | for line in self.output().splitlines() |
| 134 | if "Sanitizer" in line or "runtime error" in line or line.startswith("ERROR") | 136 | if "Sanitizer" in line or "runtime error" in line or line.startswith("ERROR") |
| 135 | ] | 137 | ] |
| 138 | if refused_to_exit: | ||
| 139 | # Killing it throws away whatever the sanitizer had to say on the | ||
| 140 | # way out, so a test that ends this way has checked nothing. | ||
| 141 | complaints.append("the tracker did not exit within 5 s of SIGINT and had to be killed") | ||
| 136 | self._cleanup() | 142 | self._cleanup() |
| 137 | return complaints | 143 | return complaints |
| 138 | 144 | ||
