xref: /haiku/src/tests/system/kernel/wait_for_objects_test.cpp (revision 1214ef1b2100f2b3299fc9d8d6142e46f70a4c3f)
1 #include <errno.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <sys/select.h>
6 #include <unistd.h>
7 
8 #include <OS.h>
9 
10 
11 static sem_id sSemaphore1;
12 static sem_id sSemaphore2;
13 static port_id sPort1;
14 static port_id sPort2;
15 
16 
17 static status_t
18 notifier_thread(void* data)
19 {
20 	snooze(1000000);
21 	release_sem(sSemaphore1);
22 	snooze(1000000);
23 	release_sem(sSemaphore2);
24 	snooze(1000000);
25 	write_port(sPort1, 0xcafe, "test", 4);
26 	snooze(1000000);
27 	int32 code;
28 	read_port(sPort2, &code, &code, sizeof(code));
29 	snooze(1000000);
30 
31 	return B_OK;
32 }
33 
34 
35 static void
36 print_events(const object_wait_info* infos, int infoCount)
37 {
38 	printf("events:\n");
39 	for (int i = 0; i < infoCount; i++)
40 		printf("  %d: 0x%x\n", i, infos[i].events);
41 }
42 
43 
44 int
45 main()
46 {
47 	sSemaphore1 = create_sem(0L, "test semaphore 1");
48 	sSemaphore2 = create_sem(0L, "test semaphore 2");
49 	sPort1 = create_port(2L, "test port 1");
50 	sPort2 = create_port(1L, "test port 2");
51 
52 	printf("semaphore 1: %ld\n", sSemaphore1);
53 	printf("semaphore 2: %ld\n", sSemaphore2);
54 	printf("port 1:      %ld\n", sPort1);
55 	printf("port 2:      %ld\n", sPort2);
56 
57 	thread_id thread = spawn_thread(notifier_thread, "notifier",
58 		B_NORMAL_PRIORITY, NULL);
59 	resume_thread(thread);
60 
61 	printf("thread:      %ld\n", thread);
62 
63 	object_wait_info initialInfos[] = {
64 		{
65 			sSemaphore1,
66 			B_OBJECT_TYPE_SEMAPHORE,
67 			B_EVENT_ACQUIRE_SEMAPHORE
68 		},
69 		{
70 			sSemaphore2,
71 			B_OBJECT_TYPE_SEMAPHORE,
72 			B_EVENT_ACQUIRE_SEMAPHORE
73 		},
74 		{
75 			sPort1,
76 			B_OBJECT_TYPE_PORT,
77 			B_EVENT_READ
78 		},
79 		{
80 			sPort2,
81 			B_OBJECT_TYPE_PORT,
82 			B_EVENT_WRITE
83 		},
84 		{
85 			0,
86 			B_OBJECT_TYPE_FD,
87 			B_EVENT_READ
88 		},
89 		{
90 			thread,
91 			B_OBJECT_TYPE_THREAD,
92 			B_EVENT_INVALID
93 		}
94 	};
95 	int infoCount = sizeof(initialInfos) / sizeof(object_wait_info);
96 
97 	while (true) {
98 		object_wait_info infos[infoCount];
99 		memcpy(infos, initialInfos, sizeof(initialInfos));
100 
101 		ssize_t result = wait_for_objects_etc(infos, infoCount,
102 			B_RELATIVE_TIMEOUT, 10000000LL);
103 
104 		if (result >= 0)
105 			printf("\nwait_for_objects(): %ld\n", result);
106 		else
107 			printf("\nwait_for_objects(): %s\n", strerror(result));
108 
109 		print_events(infos, infoCount);
110 
111 		for (int i = 0; i < infoCount; i++) {
112 			int32 type = infos[i].type;
113 			int32 object = infos[i].object;
114 			uint16 events = infos[i].events;
115 			char buffer[256];
116 
117 			if (type == B_OBJECT_TYPE_SEMAPHORE) {
118 				if (events & B_EVENT_ACQUIRE_SEMAPHORE) {
119 					status_t error = acquire_sem_etc(object, 1,
120 						B_RELATIVE_TIMEOUT, 0);
121 					printf("acquire_sem(%ld): %s\n", object, strerror(error));
122 				}
123 			} else if (type == B_OBJECT_TYPE_PORT) {
124 				if (events & B_EVENT_READ) {
125 					int32 code;
126 					ssize_t bytesRead = read_port_etc(object, &code,
127 						buffer, sizeof(buffer), B_RELATIVE_TIMEOUT, 0);
128 					printf("read_port(%ld): %ld\n", object, bytesRead);
129 				}
130 				if (events & B_EVENT_WRITE) {
131 					status_t error = write_port_etc(object, 0xc0de, buffer, 10,
132 						B_RELATIVE_TIMEOUT, 0);
133 					printf("write_port(%ld): %s\n", object, strerror(error));
134 				}
135 			} else if (type == B_OBJECT_TYPE_FD) {
136 				if (events & B_EVENT_READ) {
137 					ssize_t bytesRead = read(object, buffer, sizeof(buffer));
138 					printf("read(%ld): %ld\n", object, bytesRead);
139 				}
140 			} else if (type == B_OBJECT_TYPE_THREAD) {
141 				if (events & B_EVENT_INVALID) {
142 					printf("thread %ld quit\n", object);
143 					infoCount--;
144 				}
145 			}
146 		}
147 	}
148 
149 	return 0;
150 }
151