summaryrefslogtreecommitdiffstats
path: root/winpr/libwinpr/synch/test/TestSynchThread.c
blob: 58f7cb0808bc6cc93c79cc73b75dc48fd2915f4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <winpr/crt.h>
#include <winpr/synch.h>
#include <winpr/thread.h>

static DWORD WINAPI test_thread(LPVOID arg)
{
	WINPR_UNUSED(arg);
	Sleep(100);
	ExitThread(0);
	return 0;
}

int TestSynchThread(int argc, char* argv[])
{
	DWORD rc = 0;
	HANDLE thread = NULL;

	WINPR_UNUSED(argc);
	WINPR_UNUSED(argv);

	thread = CreateThread(NULL, 0, test_thread, NULL, 0, NULL);

	if (!thread)
	{
		printf("CreateThread failure\n");
		return -1;
	}

	/* TryJoin should now fail. */
	rc = WaitForSingleObject(thread, 0);

	if (WAIT_TIMEOUT != rc)
	{
		printf("Timed WaitForSingleObject on running thread failed with %" PRIu32 "\n", rc);
		return -3;
	}

	/* Join the thread */
	rc = WaitForSingleObject(thread, INFINITE);

	if (WAIT_OBJECT_0 != rc)
	{
		printf("WaitForSingleObject on thread failed with %" PRIu32 "\n", rc);
		return -2;
	}

	/* TimedJoin should now succeed. */
	rc = WaitForSingleObject(thread, 0);

	if (WAIT_OBJECT_0 != rc)
	{
		printf("Timed WaitForSingleObject on dead thread failed with %" PRIu32 "\n", rc);
		return -5;
	}

	/* check that WaitForSingleObject works multiple times on a terminated thread */
	for (int i = 0; i < 4; i++)
	{
		rc = WaitForSingleObject(thread, 0);
		if (WAIT_OBJECT_0 != rc)
		{
			printf("Timed WaitForSingleObject on dead thread failed with %" PRIu32 "\n", rc);
			return -6;
		}
	}

	if (!CloseHandle(thread))
	{
		printf("CloseHandle failed!");
		return -1;
	}

	thread = CreateThread(NULL, 0, test_thread, NULL, 0, NULL);

	if (!thread)
	{
		printf("CreateThread failure\n");
		return -1;
	}

	/* TryJoin should now fail. */
	rc = WaitForSingleObject(thread, 10);

	if (WAIT_TIMEOUT != rc)
	{
		printf("Timed WaitForSingleObject on running thread failed with %" PRIu32 "\n", rc);
		return -3;
	}

	/* Join the thread */
	rc = WaitForSingleObject(thread, INFINITE);

	if (WAIT_OBJECT_0 != rc)
	{
		printf("WaitForSingleObject on thread failed with %" PRIu32 "\n", rc);
		return -2;
	}

	/* TimedJoin should now succeed. */
	rc = WaitForSingleObject(thread, 0);

	if (WAIT_OBJECT_0 != rc)
	{
		printf("Timed WaitForSingleObject on dead thread failed with %" PRIu32 "\n", rc);
		return -5;
	}

	if (!CloseHandle(thread))
	{
		printf("CloseHandle failed!");
		return -1;
	}

	/* Thread detach test */
	thread = CreateThread(NULL, 0, test_thread, NULL, 0, NULL);

	if (!thread)
	{
		printf("CreateThread failure\n");
		return -1;
	}

	if (!CloseHandle(thread))
	{
		printf("CloseHandle failed!");
		return -1;
	}

	return 0;
}