github.com/ccccaoqing/test@v0.0.0-20220510085219-3985d23445c0/misc/cgo/test/issue3250.go (about)

     1  // Copyright 2013 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  package cgotest
     8  
     9  /*
    10  #include <signal.h>
    11  #include <pthread.h>
    12  #include <unistd.h>
    13  #include <stdlib.h>
    14  
    15  static void *thread(void *p) {
    16  	(void)p;
    17  	const int M = 100;
    18  	int i;
    19  	for (i = 0; i < M; i++) {
    20  		pthread_kill(pthread_self(), SIGCHLD);
    21  		usleep(rand() % 20 + 5);
    22  	}
    23  	return NULL;
    24  }
    25  void testSendSIG() {
    26  	const int N = 20;
    27  	int i;
    28  	pthread_t tid[N];
    29  	for (i = 0; i < N; i++) {
    30  		usleep(rand() % 200 + 100);
    31  		pthread_create(&tid[i], 0, thread, NULL);
    32  	}
    33  	for (i = 0; i < N; i++)
    34  		pthread_join(tid[i], 0);
    35  }
    36  */
    37  import "C"
    38  
    39  import (
    40  	"os"
    41  	"os/signal"
    42  	"syscall"
    43  	"testing"
    44  	"time"
    45  )
    46  
    47  func test3250(t *testing.T) {
    48  	t.Skip("skipped, see golang.org/issue/5885")
    49  	const (
    50  		thres = 1
    51  		sig   = syscall.SIGCHLD
    52  	)
    53  	type result struct {
    54  		n   int
    55  		sig os.Signal
    56  	}
    57  	var (
    58  		sigCh     = make(chan os.Signal, 10)
    59  		waitStart = make(chan struct{})
    60  		waitDone  = make(chan result)
    61  	)
    62  
    63  	signal.Notify(sigCh, sig)
    64  
    65  	go func() {
    66  		n := 0
    67  		alarm := time.After(time.Second * 3)
    68  		for {
    69  			select {
    70  			case <-waitStart:
    71  				waitStart = nil
    72  			case v := <-sigCh:
    73  				n++
    74  				if v != sig || n > thres {
    75  					waitDone <- result{n, v}
    76  					return
    77  				}
    78  			case <-alarm:
    79  				waitDone <- result{n, sig}
    80  				return
    81  			}
    82  		}
    83  	}()
    84  
    85  	waitStart <- struct{}{}
    86  	C.testSendSIG()
    87  	r := <-waitDone
    88  	if r.sig != sig {
    89  		t.Fatalf("received signal %v, but want %v", r.sig, sig)
    90  	}
    91  	t.Logf("got %d signals\n", r.n)
    92  	if r.n <= thres {
    93  		t.Fatalf("expected more than %d", thres)
    94  	}
    95  }