blob: 96b5680b1b76a0f71a37af8ab501b813f3e65614 [file] [log] [blame]
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -04001#include <stddef.h>
2#include <stdio.h>
3#include <errno.h>
4#include <stdlib.h>
5#include <string.h>
6#include <sys/socket.h>
7#include <sys/un.h>
8#include <sys/epoll.h>
9#include <unistd.h>
10#include "wayland.h"
11
12struct wl_event_loop {
13 int epoll_fd;
14};
15
16struct wl_event_source {
17 int fd;
18 wl_event_loop_func_t func;
19 void *data;
20};
21
22struct wl_event_source *
23wl_event_loop_add_fd(struct wl_event_loop *loop,
24 int fd, uint32_t mask,
25 wl_event_loop_func_t func,
26 void *data)
27{
28 struct wl_event_source *source;
29 struct epoll_event ep;
30
31 source = malloc(sizeof *source);
32 source->fd = fd;
33 source->func = func;
34 source->data = data;
35
36 ep.events = 0;
37 if (mask & WL_EVENT_READABLE)
38 ep.events |= EPOLLIN;
39 if (mask & WL_EVENT_WRITEABLE)
40 ep.events |= EPOLLOUT;
41 ep.data.ptr = source;
42
43 if (epoll_ctl(loop->epoll_fd, EPOLL_CTL_ADD, fd, &ep) < 0) {
44 free(source);
45 return NULL;
46 }
47
48 return source;
49}
50
51int
52wl_event_loop_remove_source(struct wl_event_loop *loop,
53 struct wl_event_source *source)
54{
55 int fd;
56
57 fd = source->fd;
58 free(source);
59
60 return epoll_ctl(loop->epoll_fd, EPOLL_CTL_DEL, fd, NULL);
61}
62
Kristian Høgsberga67a71a2008-10-07 10:10:36 -040063int
64wl_event_loop_update_source(struct wl_event_loop *loop,
65 struct wl_event_source *source,
66 uint32_t mask)
67{
68 struct epoll_event ep;
69
70 ep.events = 0;
71 if (mask & WL_EVENT_READABLE)
72 ep.events |= EPOLLIN;
73 if (mask & WL_EVENT_WRITEABLE)
74 ep.events |= EPOLLOUT;
75 ep.data.ptr = source;
76
77 return epoll_ctl(loop->epoll_fd,
78 EPOLL_CTL_MOD, source->fd, &ep);
79}
80
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -040081struct wl_event_loop *
82wl_event_loop_create(void)
83{
84 struct wl_event_loop *loop;
85
86 loop = malloc(sizeof *loop);
87 if (loop == NULL)
88 return NULL;
89
90 loop->epoll_fd = epoll_create(16);
91 if (loop->epoll_fd < 0) {
92 free(loop);
93 return NULL;
94 }
95
96 return loop;
97}
98
99void
100wl_event_loop_destroy(struct wl_event_loop *loop)
101{
102 close(loop->epoll_fd);
103 free(loop);
104}
105
106#define ARRAY_LENGTH(a) (sizeof (a) / sizeof (a)[0])
107
108int
109wl_event_loop_wait(struct wl_event_loop *loop)
110{
111 struct epoll_event ep[32];
112 struct wl_event_source *source;
113 int i, count;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400114 uint32_t mask;
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400115
116 count = epoll_wait(loop->epoll_fd, ep, ARRAY_LENGTH(ep), -1);
117 if (count < 0)
118 return -1;
119
120 for (i = 0; i < count; i++) {
121 source = ep[i].data.ptr;
Kristian Høgsberga67a71a2008-10-07 10:10:36 -0400122 mask = 0;
123 if (ep[i].events & EPOLLIN)
124 mask |= WL_EVENT_READABLE;
125 if (ep[i].events & EPOLLOUT)
126 mask |= WL_EVENT_WRITEABLE;
127
128 source->func(source->fd, mask, source->data);
Kristian Høgsberg97f1ebe2008-09-30 09:46:10 -0400129 }
130
131 return 0;
132}