diff --git a/include/pthread-fixes.h b/include/pthread-fixes.h index 230ce317..88c6b669 100644 --- a/include/pthread-fixes.h +++ b/include/pthread-fixes.h @@ -56,4 +56,17 @@ int pthread_barrier_destroy(pthread_barrier_t *barrier); #endif /* defined(PTHREAD_BARRIER_SERIAL_THREAD) */ int pthread_yield(void); + +/* Workaround pthread_sigmask() returning EINVAL on versions < 4.1 by + * replacing all calls to pthread_sigmask with sigprocmask. See: + * https://android.googlesource.com/platform/bionic/+/9bf330b5 + * https://code.google.com/p/android/issues/detail?id=15337 + */ +int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset); + +#ifdef pthread_sigmask +#undef pthread_sigmask +#endif +#define pthread_sigmask(how, set, oldset) uv__pthread_sigmask(how, set, oldset) + #endif /* GOOGLE_BREAKPAD_COMMON_ANDROID_TESTING_PTHREAD_FIXES_H */ diff --git a/src/unix/pthread-fixes.c b/src/unix/pthread-fixes.c index 2e4c542b..dc54f35d 100644 --- a/src/unix/pthread-fixes.c +++ b/src/unix/pthread-fixes.c @@ -29,6 +29,29 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* Android versions < 4.1 have a broken pthread_sigmask. + * Note that this block of code must come before any inclusion of + * pthread-fixes.h so that the real pthread_sigmask can be referenced. + * */ +#include +#include + +int uv__pthread_sigmask(int how, const sigset_t* set, sigset_t* oset) { + static int workaround; + + if (workaround) { + return sigprocmask(how, set, oset); + } else if (pthread_sigmask(how, set, oset)) { + if (errno == EINVAL && sigprocmask(how, set, oset) == 0) { + workaround = 1; + return 0; + } else { + return -1; + } + } else { + return 0; + } +} /*Android doesn't provide pthread_barrier_t for now.*/ #ifndef PTHREAD_BARRIER_SERIAL_THREAD