2 * uloop - event loop implementation
4 * Copyright (C) 2010-2016 Felix Fietkau <nbd@openwrt.org>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 * FIXME: uClibc < 0.9.30.3 does not define EPOLLRDHUP for Linux >= 2.6.17
23 #define EPOLLRDHUP 0x2000
26 static int uloop_init_pollfd(void)
31 poll_fd
= epoll_create(32);
35 fcntl(poll_fd
, F_SETFD
, fcntl(poll_fd
, F_GETFD
) | FD_CLOEXEC
);
39 static int register_poll(struct uloop_fd
*fd
, unsigned int flags
)
41 struct epoll_event ev
;
42 int op
= fd
->registered
? EPOLL_CTL_MOD
: EPOLL_CTL_ADD
;
44 memset(&ev
, 0, sizeof(struct epoll_event
));
46 if (flags
& ULOOP_READ
)
47 ev
.events
|= EPOLLIN
| EPOLLRDHUP
;
49 if (flags
& ULOOP_WRITE
)
50 ev
.events
|= EPOLLOUT
;
52 if (flags
& ULOOP_EDGE_TRIGGER
)
58 return epoll_ctl(poll_fd
, op
, fd
->fd
, &ev
);
61 static struct epoll_event events
[ULOOP_MAX_EVENTS
];
63 static int __uloop_fd_delete(struct uloop_fd
*sock
)
66 return epoll_ctl(poll_fd
, EPOLL_CTL_DEL
, sock
->fd
, 0);
69 static int uloop_fetch_events(int timeout
)
73 nfds
= epoll_wait(poll_fd
, events
, ARRAY_SIZE(events
), timeout
);
74 for (n
= 0; n
< nfds
; ++n
) {
75 struct uloop_fd_event
*cur
= &cur_fds
[n
];
76 struct uloop_fd
*u
= events
[n
].data
.ptr
;
83 if (events
[n
].events
& (EPOLLERR
|EPOLLHUP
)) {
85 if (!(u
->flags
& ULOOP_ERROR_CB
))
89 if(!(events
[n
].events
& (EPOLLRDHUP
|EPOLLIN
|EPOLLOUT
|EPOLLERR
|EPOLLHUP
))) {
94 if(events
[n
].events
& EPOLLRDHUP
)
97 if(events
[n
].events
& EPOLLIN
)
100 if(events
[n
].events
& EPOLLOUT
)