xref: /aosp_15_r20/external/wmediumd/wmediumd/lib/loop.c (revision 621120a22a0cd8ba80b131fe8bcb37c86ff453e3)
1 /*
2  * Copyright (C) 2019 - 2020 Intel Corporation
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 #include <stddef.h>
7 #include <stdbool.h>
8 #include <stdint.h>
9 #include <string.h>
10 #include <usfstl/loop.h>
11 #include <usfstl/list.h>
12 #include <assert.h>
13 #ifdef _WIN32
14 #undef _WIN32_WINNT
15 #define _WIN32_WINNT 0x0600
16 #include <winsock2.h>
17 #include <windows.h>
18 #else
19 #include <sys/select.h>
20 #endif
21 
22 struct usfstl_list g_usfstl_loop_entries =
23 	USFSTL_LIST_INIT(g_usfstl_loop_entries);
24 void (*g_usfstl_loop_pre_handler_fn)(void *);
25 void *g_usfstl_loop_pre_handler_fn_data;
26 
27 
usfstl_loop_register(struct usfstl_loop_entry * entry)28 void usfstl_loop_register(struct usfstl_loop_entry *entry)
29 {
30 	struct usfstl_loop_entry *tmp;
31 
32 	usfstl_loop_for_each_entry(tmp) {
33 		if (entry->priority >= tmp->priority) {
34 			usfstl_list_insert_before(&tmp->list, &entry->list);
35 			return;
36 		}
37 	}
38 
39 	usfstl_list_append(&g_usfstl_loop_entries, &entry->list);
40 }
41 
usfstl_loop_unregister(struct usfstl_loop_entry * entry)42 void usfstl_loop_unregister(struct usfstl_loop_entry *entry)
43 {
44 	usfstl_list_item_remove(&entry->list);
45 }
46 
usfstl_loop_wait_and_handle(void)47 void usfstl_loop_wait_and_handle(void)
48 {
49 	while (true) {
50 		struct usfstl_loop_entry *tmp;
51 		fd_set rd_set, exc_set;
52 		unsigned int max = 0, num;
53 
54 		FD_ZERO(&rd_set);
55 		FD_ZERO(&exc_set);
56 
57 		usfstl_loop_for_each_entry(tmp) {
58 			FD_SET(tmp->fd, &rd_set);
59 			FD_SET(tmp->fd, &exc_set);
60 			if ((unsigned int)tmp->fd > max)
61 				max = tmp->fd;
62 		}
63 
64 		num = select(max + 1, &rd_set, NULL, &exc_set, NULL);
65 		assert(num > 0);
66 
67 		usfstl_loop_for_each_entry(tmp) {
68 			void *data = g_usfstl_loop_pre_handler_fn_data;
69 
70 			if (!FD_ISSET(tmp->fd, &rd_set) &&
71 			    !FD_ISSET(tmp->fd, &exc_set))
72 				continue;
73 
74 			if (g_usfstl_loop_pre_handler_fn)
75 				g_usfstl_loop_pre_handler_fn(data);
76 			tmp->handler(tmp);
77 			return;
78 		}
79 	}
80 }
81