1/*
2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5
6#include <errno.h>
7#include <signal.h>
8#include <stdio.h>
9#include <stdlib.h>
10#include <signal.h>
11#include <string.h>
12
13#include <OS.h>
14
15
16static int64 sHandledSignals = 0;
17
18
19static status_t
20signal_pusher(void* data)
21{
22	team_info teamInfo;
23	get_team_info(B_CURRENT_TEAM, &teamInfo);
24	thread_id mainThread = teamInfo.team;
25
26	while (true) {
27		send_signal(mainThread, SIGUSR1);
28		snooze(1000);
29	}
30
31	return B_OK;
32}
33
34
35static void
36signal_handler(int signal)
37{
38	free(malloc(10));
39	sHandledSignals++;
40}
41
42
43int
44main()
45{
46	const int testSeconds = 2;
47	printf("Trying to provoke allocator deadlock in signal handler.\n");
48	printf("If successful test will finish in %d seconds...\n", testSeconds);
49
50	// install signal handler
51	if (signal(SIGUSR1, signal_handler) == SIG_ERR) {
52		fprintf(stderr, "Error: Failed to install signal handler: %s\n",
53			strerror(errno));
54		exit(1);
55	}
56
57	// start signal thread
58	thread_id signalThread = spawn_thread(&signal_pusher, "signal pusher",
59		B_NORMAL_PRIORITY, NULL);
60	resume_thread(signalThread);
61
62	bigtime_t endTime = system_time() + 1000000 * (bigtime_t)testSeconds;
63	while (system_time() < endTime) {
64		const int allocationCount = 1000;
65		void* allocations[allocationCount];
66		for (int i = 0; i < allocationCount; i++)
67			allocations[i] = malloc(rand() % 50);
68		for (int i = 0; i < allocationCount; i++)
69			free(allocations[i]);
70	}
71
72	kill_thread(signalThread);
73	snooze(1000);
74
75	printf("test successful, handled %" B_PRId64 " signals\n", sHandledSignals);
76
77	return 0;
78}
79