|
| 1 | +import ffi |
| 2 | +import struct |
| 3 | +import os |
| 4 | + |
| 5 | + |
| 6 | +libc = ffi.open("libc.so.6") |
| 7 | + |
| 8 | +#int epoll_create(int size); |
| 9 | +epoll_create = libc.func("i", "epoll_create", "i") |
| 10 | +#int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); |
| 11 | +epoll_ctl = libc.func("i", "epoll_ctl", "iiip") |
| 12 | +#int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout); |
| 13 | +epoll_wait = libc.func("i", "epoll_wait", "ipii") |
| 14 | + |
| 15 | +EPOLLIN = 0x001 |
| 16 | +EPOLLPRI = 0x002 |
| 17 | +EPOLLOUT = 0x004 |
| 18 | + |
| 19 | +EPOLL_CTL_ADD = 1 |
| 20 | +EPOLL_CTL_DEL = 2 |
| 21 | +EPOLL_CTL_MOD = 3 |
| 22 | + |
| 23 | + |
| 24 | +class Epoll: |
| 25 | + |
| 26 | + def __init__(self, epfd): |
| 27 | + self.epfd = epfd |
| 28 | + self.evbuf = struct.pack("IQ", 0, 0) |
| 29 | + |
| 30 | + def register(self, fd, eventmask=EPOLLIN|EPOLLPRI|EPOLLOUT, retval=None): |
| 31 | + if retval is None: |
| 32 | + retval = fd |
| 33 | + s = struct.pack("IQ", eventmask, retval) |
| 34 | + r = epoll_ctl(self.epfd, EPOLL_CTL_ADD, fd, s) |
| 35 | + os.check_error(r) |
| 36 | + |
| 37 | + def poll(self, timeout=-1): |
| 38 | + s = bytearray(self.evbuf) |
| 39 | + n = epoll_wait(self.epfd, s, 1, timeout) |
| 40 | + os.check_error(n) |
| 41 | + res = [] |
| 42 | + if n > 0: |
| 43 | + ev, h = struct.unpack("IQ", s) |
| 44 | + res.append((h, ev)) |
| 45 | + return res |
| 46 | + |
| 47 | + |
| 48 | +def epoll(): |
| 49 | + fd = epoll_create(4) |
| 50 | + os.check_error(fd) |
| 51 | + return Epoll(fd) |
0 commit comments