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
11static sem_id sSemaphore1;
12static sem_id sSemaphore2;
13static port_id sPort1;
14static port_id sPort2;
15
16
17static status_t
18notifier_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
35static void
36print_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
44int
45main()
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