1  // Copyright 2015 The Go Authors. All rights reserved.
       2  // Use of this source code is governed by a BSD-style
       3  // license that can be found in the LICENSE file.
       4  
       5  // +build !windows
       6  
       7  #include <errno.h>
       8  #include <signal.h>
       9  #include <stdlib.h>
      10  #include <pthread.h>
      11  #include <stdio.h>
      12  #include <time.h>
      13  #include <unistd.h>
      14  
      15  extern void IntoGoAndBack();
      16  
      17  int CheckBlocked() {
      18  	sigset_t mask;
      19  	sigprocmask(SIG_BLOCK, NULL, &mask);
      20  	return sigismember(&mask, SIGIO);
      21  }
      22  
      23  static void* sigthreadfunc(void* unused) {
      24  	sigset_t mask;
      25  	sigemptyset(&mask);
      26  	sigaddset(&mask, SIGIO);
      27  	sigprocmask(SIG_BLOCK, &mask, NULL);
      28  	IntoGoAndBack();
      29  	return NULL;
      30  }
      31  
      32  int RunSigThread() {
      33  	int tries;
      34  	pthread_t thread;
      35  	int r;
      36  	struct timespec ts;
      37  
      38  	for (tries = 0; tries < 20; tries++) {
      39  		r = pthread_create(&thread, NULL, &sigthreadfunc, NULL);
      40  		if (r == 0) {
      41  			return pthread_join(thread, NULL);
      42  		}
      43  		if (r != EAGAIN) {
      44  			return r;
      45  		}
      46  		ts.tv_sec = 0;
      47  		ts.tv_nsec = (tries + 1) * 1000 * 1000; // Milliseconds.
      48  		nanosleep(&ts, NULL);
      49  	}
      50  	return EAGAIN;
      51  }