github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/misc/cgo/testcarchive/main3.c (about)

     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  // Test os/signal.Notify and os/signal.Reset.
     6  // This is a lot like misc/cgo/testcshared/main5.c.
     7  
     8  #include <signal.h>
     9  #include <stdio.h>
    10  #include <stdlib.h>
    11  #include <string.h>
    12  #include <sched.h>
    13  
    14  #include "libgo3.h"
    15  
    16  static void die(const char* msg) {
    17  	perror(msg);
    18  	exit(EXIT_FAILURE);
    19  }
    20  
    21  static volatile sig_atomic_t sigioSeen;
    22  
    23  static void ioHandler(int signo, siginfo_t* info, void* ctxt) {
    24  	sigioSeen = 1;
    25  }
    26  
    27  int main(int argc, char** argv) {
    28  	int verbose;
    29  	struct sigaction sa;
    30  	int i;
    31  
    32  	verbose = argc > 2;
    33  	setvbuf(stdout, NULL, _IONBF, 0);
    34  
    35  	if (verbose) {
    36  		printf("calling sigaction\n");
    37  	}
    38  
    39  	memset(&sa, 0, sizeof sa);
    40  	sa.sa_sigaction = ioHandler;
    41  	if (sigemptyset(&sa.sa_mask) < 0) {
    42  		die("sigemptyset");
    43  	}
    44  	sa.sa_flags = SA_SIGINFO;
    45  	if (sigaction(SIGIO, &sa, NULL) < 0) {
    46  		die("sigaction");
    47  	}
    48  
    49  	// At this point there should not be a Go signal handler
    50  	// installed for SIGIO.
    51  
    52  	if (verbose) {
    53  		printf("raising SIGIO\n");
    54  	}
    55  
    56  	if (raise(SIGIO) < 0) {
    57  		die("raise");
    58  	}
    59  
    60  	if (verbose) {
    61  		printf("waiting for sigioSeen\n");
    62  	}
    63  
    64  	// Wait until the signal has been delivered.
    65  	i = 0;
    66  	while (!sigioSeen) {
    67  		if (sched_yield() < 0) {
    68  			perror("sched_yield");
    69  		}
    70  		i++;
    71  		if (i > 100000) {
    72  			fprintf(stderr, "looping too long waiting for signal\n");
    73  			exit(EXIT_FAILURE);
    74  		}
    75  	}
    76  
    77  	sigioSeen = 0;
    78  
    79  	// Tell the Go code to catch SIGIO.
    80  
    81  	if (verbose) {
    82  		printf("calling CatchSIGIO\n");
    83  	}
    84  
    85  	CatchSIGIO();
    86  
    87  	if (verbose) {
    88  		printf("raising SIGIO\n");
    89  	}
    90  
    91  	if (raise(SIGIO) < 0) {
    92  		die("raise");
    93  	}
    94  
    95  	if (verbose) {
    96  		printf("calling SawSIGIO\n");
    97  	}
    98  
    99  	if (!SawSIGIO()) {
   100  		fprintf(stderr, "Go handler did not see SIGIO\n");
   101  		exit(EXIT_FAILURE);
   102  	}
   103  
   104  	if (sigioSeen != 0) {
   105  		fprintf(stderr, "C handler saw SIGIO when only Go handler should have\n");
   106  		exit(EXIT_FAILURE);
   107  	}
   108  
   109  	// Tell the Go code to stop catching SIGIO.
   110  
   111  	if (verbose) {
   112  		printf("calling ResetSIGIO\n");
   113  	}
   114  
   115  	ResetSIGIO();
   116  
   117  	if (verbose) {
   118  		printf("raising SIGIO\n");
   119  	}
   120  
   121  	if (raise(SIGIO) < 0) {
   122  		die("raise");
   123  	}
   124  
   125  	if (verbose) {
   126  		printf("calling SawSIGIO\n");
   127  	}
   128  
   129  	if (SawSIGIO()) {
   130  		fprintf(stderr, "Go handler saw SIGIO after Reset\n");
   131  		exit(EXIT_FAILURE);
   132  	}
   133  
   134  	if (verbose) {
   135  		printf("waiting for sigioSeen\n");
   136  	}
   137  
   138  	// Wait until the signal has been delivered.
   139  	i = 0;
   140  	while (!sigioSeen) {
   141  		if (sched_yield() < 0) {
   142  			perror("sched_yield");
   143  		}
   144  		i++;
   145  		if (i > 100000) {
   146  			fprintf(stderr, "looping too long waiting for signal\n");
   147  			exit(EXIT_FAILURE);
   148  		}
   149  	}
   150  
   151  	printf("PASS\n");
   152  	return 0;
   153  }