diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/loop.c | 105 | ||||
-rw-r--r-- | common/meson.build | 1 |
2 files changed, 106 insertions, 0 deletions
diff --git a/common/loop.c b/common/loop.c new file mode 100644 index 00000000..bfbfd5a6 --- /dev/null +++ b/common/loop.c | |||
@@ -0,0 +1,105 @@ | |||
1 | #include <string.h> | ||
2 | #include <stdbool.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <stdio.h> | ||
5 | #include <poll.h> | ||
6 | #include <sys/timerfd.h> | ||
7 | #include <unistd.h> | ||
8 | #include "list.h" | ||
9 | #include "log.h" | ||
10 | #include "loop.h" | ||
11 | |||
12 | struct loop_event { | ||
13 | void (*callback)(int fd, short mask, void *data); | ||
14 | void *data; | ||
15 | }; | ||
16 | |||
17 | struct loop { | ||
18 | struct pollfd *fds; | ||
19 | int fd_length; | ||
20 | int fd_capacity; | ||
21 | |||
22 | list_t *events; // struct loop_event | ||
23 | }; | ||
24 | |||
25 | struct loop *loop_create(void) { | ||
26 | struct loop *loop = calloc(1, sizeof(struct loop)); | ||
27 | if (!loop) { | ||
28 | wlr_log(WLR_ERROR, "Unable to allocate memory for loop"); | ||
29 | return NULL; | ||
30 | } | ||
31 | loop->fd_capacity = 10; | ||
32 | loop->fds = malloc(sizeof(struct pollfd) * loop->fd_capacity); | ||
33 | loop->events = create_list(); | ||
34 | return loop; | ||
35 | } | ||
36 | |||
37 | void loop_destroy(struct loop *loop) { | ||
38 | list_foreach(loop->events, free); | ||
39 | list_free(loop->events); | ||
40 | free(loop); | ||
41 | } | ||
42 | |||
43 | void loop_poll(struct loop *loop) { | ||
44 | poll(loop->fds, loop->fd_length, -1); | ||
45 | |||
46 | for (int i = 0; i < loop->fd_length; ++i) { | ||
47 | struct pollfd pfd = loop->fds[i]; | ||
48 | struct loop_event *event = loop->events->items[i]; | ||
49 | |||
50 | // Always send these events | ||
51 | unsigned events = pfd.events | POLLHUP | POLLERR; | ||
52 | |||
53 | if (pfd.revents & events) { | ||
54 | event->callback(pfd.fd, pfd.revents, event->data); | ||
55 | } | ||
56 | } | ||
57 | } | ||
58 | |||
59 | struct loop_event *loop_add_fd(struct loop *loop, int fd, short mask, | ||
60 | void (*callback)(int fd, short mask, void *data), void *data) { | ||
61 | struct pollfd pfd = {fd, mask, 0}; | ||
62 | |||
63 | if (loop->fd_length == loop->fd_capacity) { | ||
64 | loop->fd_capacity += 10; | ||
65 | loop->fds = realloc(loop->fds, sizeof(struct pollfd) * loop->fd_capacity); | ||
66 | } | ||
67 | |||
68 | loop->fds[loop->fd_length++] = pfd; | ||
69 | |||
70 | struct loop_event *event = calloc(1, sizeof(struct loop_event)); | ||
71 | event->callback = callback; | ||
72 | event->data = data; | ||
73 | |||
74 | list_add(loop->events, event); | ||
75 | |||
76 | return event; | ||
77 | } | ||
78 | |||
79 | struct loop_event *loop_add_timer(struct loop *loop, int ms, | ||
80 | void (*callback)(int fd, short mask, void *data), void *data) { | ||
81 | int fd = timerfd_create(CLOCK_MONOTONIC, 0); | ||
82 | struct itimerspec its; | ||
83 | its.it_interval.tv_sec = 0; | ||
84 | its.it_interval.tv_nsec = 0; | ||
85 | its.it_value.tv_sec = ms / 1000000000; | ||
86 | its.it_value.tv_nsec = (ms * 1000000) % 1000000000; | ||
87 | timerfd_settime(fd, 0, &its, NULL); | ||
88 | |||
89 | return loop_add_fd(loop, fd, POLLIN, callback, data); | ||
90 | } | ||
91 | |||
92 | bool loop_remove_event(struct loop *loop, struct loop_event *event) { | ||
93 | for (int i = 0; i < loop->events->length; ++i) { | ||
94 | if (loop->events->items[i] == event) { | ||
95 | list_del(loop->events, i); | ||
96 | |||
97 | loop->fd_length--; | ||
98 | memmove(&loop->fds[i], &loop->fds[i + 1], sizeof(void*) * (loop->fd_length - i)); | ||
99 | |||
100 | free(event); | ||
101 | return true; | ||
102 | } | ||
103 | } | ||
104 | return false; | ||
105 | } | ||
diff --git a/common/meson.build b/common/meson.build index 44a29508..224a9c3f 100644 --- a/common/meson.build +++ b/common/meson.build | |||
@@ -5,6 +5,7 @@ lib_sway_common = static_library( | |||
5 | 'cairo.c', | 5 | 'cairo.c', |
6 | 'ipc-client.c', | 6 | 'ipc-client.c', |
7 | 'log.c', | 7 | 'log.c', |
8 | 'loop.c', | ||
8 | 'list.c', | 9 | 'list.c', |
9 | 'pango.c', | 10 | 'pango.c', |
10 | 'readline.c', | 11 | 'readline.c', |