2 * Copyright (C) 2018 "IoT.bzh"
3 * Author José Bollo <jose.bollo@iot.bzh>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
20 #include <sys/epoll.h>
24 #include "fdev-epoll.h"
26 #define epollfd(fdev_epoll) ((int)(intptr_t)fdev_epoll)
28 static void disable(void *closure, const struct fdev *fdev)
30 struct fdev_epoll *fdev_epoll = closure;
31 epoll_ctl(epollfd(fdev_epoll), EPOLL_CTL_DEL, fdev_fd(fdev), 0);
34 static void enable(void *closure, const struct fdev *fdev)
36 struct fdev_epoll *fdev_epoll = closure;
37 struct epoll_event event;
41 event.events = fdev_events(fdev);
42 event.data.ptr = (void*)fdev;
43 rc = epoll_ctl(epollfd(fdev_epoll), EPOLL_CTL_MOD, fd, &event);
44 if (rc < 0 && errno == ENOENT)
45 epoll_ctl(epollfd(fdev_epoll), EPOLL_CTL_ADD, fd, &event);
48 static struct fdev_itf itf =
55 struct fdev_epoll *fdev_epoll_create()
57 int fd = epoll_create1(EPOLL_CLOEXEC);
62 return fd < 0 ? 0 : (struct fdev_epoll*)(intptr_t)fd;
65 void fdev_epoll_destroy(struct fdev_epoll *fdev_epoll)
67 close(epollfd(fdev_epoll));
70 int fdev_epoll_fd(struct fdev_epoll *fdev_epoll)
72 return epollfd(fdev_epoll);
75 struct fdev *fdev_epoll_add(struct fdev_epoll *fdev_epoll, int fd)
79 fdev = fdev_create(fd);
81 fdev_set_itf(fdev, &itf, fdev_epoll);
85 void fdev_epoll_wait_and_dispatch(struct fdev_epoll *fdev_epoll, int timeout_ms)
88 struct epoll_event events[8];
91 rc = epoll_wait(epollfd(fdev_epoll), events, sizeof events / sizeof *events, timeout_ms < 0 ? -1 : timeout_ms);
92 for (i = 0 ; i < rc ; i++) {
93 fdev = events[i].data.ptr;
94 fdev_dispatch(fdev, events[i].events);