1// Copyright 2020 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//go:build !plan9 && !windows
6// +build !plan9,!windows
7
8package main
9
10// This is for issue #42207.
11// During a call to needm we could get a SIGCHLD signal
12// which would itself call needm, causing a deadlock.
13
14/*
15#include <signal.h>
16#include <pthread.h>
17#include <sched.h>
18#include <unistd.h>
19
20extern void GoNeedM();
21
22#define SIGNALERS 10
23
24static void* needmSignalThread(void* p) {
25	pthread_t* pt = (pthread_t*)(p);
26	int i;
27
28	for (i = 0; i < 100; i++) {
29		if (pthread_kill(*pt, SIGCHLD) < 0) {
30			return NULL;
31		}
32		usleep(1);
33	}
34	return NULL;
35}
36
37// We don't need many calls, as the deadlock is only likely
38// to occur the first couple of times that needm is called.
39// After that there will likely be an extra M available.
40#define CALLS 10
41
42static void* needmCallbackThread(void* p) {
43	int i;
44
45	for (i = 0; i < SIGNALERS; i++) {
46		sched_yield(); // Help the signal threads get started.
47	}
48	for (i = 0; i < CALLS; i++) {
49		GoNeedM();
50	}
51	return NULL;
52}
53
54static void runNeedmSignalThread() {
55	int i;
56	pthread_t caller;
57	pthread_t s[SIGNALERS];
58
59	pthread_create(&caller, NULL, needmCallbackThread, NULL);
60	for (i = 0; i < SIGNALERS; i++) {
61		pthread_create(&s[i], NULL, needmSignalThread, &caller);
62	}
63	for (i = 0; i < SIGNALERS; i++) {
64		pthread_join(s[i], NULL);
65	}
66	pthread_join(caller, NULL);
67}
68*/
69import "C"
70
71import (
72	"fmt"
73	"os"
74	"time"
75)
76
77func init() {
78	register("NeedmDeadlock", NeedmDeadlock)
79}
80
81//export GoNeedM
82func GoNeedM() {
83}
84
85func NeedmDeadlock() {
86	// The failure symptom is that the program hangs because of a
87	// deadlock in needm, so set an alarm.
88	go func() {
89		time.Sleep(5 * time.Second)
90		fmt.Println("Hung for 5 seconds")
91		os.Exit(1)
92	}()
93
94	C.runNeedmSignalThread()
95	fmt.Println("OK")
96}
97