Permalink
Browse files

System call wrappers should only throw thread_interrupted on EINTR if…

… the thread interruption flag is set.

This avoids erroneously treating non-interruption-caused EINTR signals
to as interruption requests.
  • Loading branch information...
FooBarWidget committed Oct 25, 2012
1 parent 88aaa42 commit 64ff6dda12cf6d3d1744b4ff127617491845c6c2
Showing with 24 additions and 6 deletions.
  1. +24 −6 ext/oxt/system_calls.cpp
View
@@ -122,15 +122,22 @@ shouldSimulateFailure() {
ctx->syscall_interruption_lock.unlock(); \
} \
int _my_errno; \
+ bool _intr_requested; \
do { \
code; \
_my_errno = errno; \
- } while ((error_expression) && _my_errno == EINTR \
- && !this_thread::syscalls_interruptable()); \
+ } while ((error_expression) \
+ && _my_errno == EINTR \
+ && (!this_thread::syscalls_interruptable() \
+ || !(_intr_requested = this_thread::interruption_requested())) \
+ ); \
if (OXT_UNLIKELY(ctx != NULL)) { \
ctx->syscall_interruption_lock.lock(); \
} \
- if ((error_expression) && _my_errno == EINTR && this_thread::syscalls_interruptable()) { \
+ if ((error_expression) \
+ && _my_errno == EINTR \
+ && this_thread::syscalls_interruptable() \
+ && _intr_requested) { \
throw thread_interrupted(); \
} \
errno = _my_errno; \
@@ -247,7 +254,10 @@ syscalls::close(int fd) {
ctx->syscall_interruption_lock.lock();
errno = e;
}
- if (ret == -1 && errno == EINTR && this_thread::syscalls_interruptable()) {
+ if (ret == -1
+ && errno == EINTR
+ && this_thread::syscalls_interruptable()
+ && this_thread::interruption_requested()) {
throw thread_interrupted();
} else {
return ret;
@@ -597,6 +607,7 @@ syscalls::nanosleep(const struct timespec *req, struct timespec *rem) {
struct timespec req2 = *req;
struct timespec rem2;
int ret, e;
+ bool intr_requested;
/* We never simulate failure in this function. */
@@ -621,13 +632,20 @@ syscalls::nanosleep(const struct timespec *req, struct timespec *rem) {
req2.tv_nsec = 0;
}
}
- } while (ret == -1 && e == EINTR && !this_thread::syscalls_interruptable());
+ } while (ret == -1
+ && e == EINTR
+ && (!this_thread::syscalls_interruptable()
+ || !(intr_requested = this_thread::interruption_requested()))
+ );
if (OXT_UNLIKELY(ctx != NULL)) {
ctx->syscall_interruption_lock.lock();
}
- if (ret == -1 && e == EINTR && this_thread::syscalls_interruptable()) {
+ if (ret == -1
+ && e == EINTR
+ && this_thread::syscalls_interruptable()
+ && intr_requested) {
throw thread_interrupted();
}
errno = e;

0 comments on commit 64ff6dd

Please sign in to comment.