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
notifier_thread(void * data)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
print_events(const object_wait_info * infos,int infoCount)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
main()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