| // Copyright 2015 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| // +build !windows |
| |
| #include <errno.h> |
| #include <signal.h> |
| #include <stdlib.h> |
| #include <pthread.h> |
| #include <stdio.h> |
| #include <time.h> |
| #include <unistd.h> |
| |
| extern void IntoGoAndBack(); |
| |
| int CheckBlocked() { |
| sigset_t mask; |
| sigprocmask(SIG_BLOCK, NULL, &mask); |
| return sigismember(&mask, SIGIO); |
| } |
| |
| static void* sigthreadfunc(void* unused) { |
| sigset_t mask; |
| sigemptyset(&mask); |
| sigaddset(&mask, SIGIO); |
| sigprocmask(SIG_BLOCK, &mask, NULL); |
| IntoGoAndBack(); |
| return NULL; |
| } |
| |
| int RunSigThread() { |
| int tries; |
| pthread_t thread; |
| int r; |
| struct timespec ts; |
| |
| for (tries = 0; tries < 20; tries++) { |
| r = pthread_create(&thread, NULL, &sigthreadfunc, NULL); |
| if (r == 0) { |
| return pthread_join(thread, NULL); |
| } |
| if (r != EAGAIN) { |
| return r; |
| } |
| ts.tv_sec = 0; |
| ts.tv_nsec = (tries + 1) * 1000 * 1000; // Milliseconds. |
| nanosleep(&ts, NULL); |
| } |
| return EAGAIN; |
| } |