Skip to content

Commit 641c26c

Browse files
committed
Stop epolling FD immediately after remove_reader & remove_writer.
1 parent 3a44397 commit 641c26c

File tree

3 files changed

+36
-0
lines changed

3 files changed

+36
-0
lines changed

uvloop/handles/poll.pyx

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,29 @@ cdef class UVPoll(UVHandle):
6161
self._fatal_error(exc, True)
6262
return
6363

64+
IF UNAME_SYSNAME == "Linux":
65+
# libuv doesn't remove the FD from epoll immediately
66+
# after uv_poll_stop or uv_poll_close, causing hard
67+
# to debug issue with dup-ed file descriptors causing
68+
# CPU burn in epoll/epoll_ctl:
69+
# https://github.com/MagicStack/uvloop/issues/61
70+
#
71+
# It's safe though to manually call epoll_ctl here,
72+
# after calling uv_poll_stop.
73+
74+
cdef:
75+
int backend_id
76+
system.epoll_event dummy_event
77+
78+
backend_id = uv.uv_backend_fd(self._loop.uvloop)
79+
if backend_id != -1:
80+
memset(&dummy_event, 0, sizeof(dummy_event))
81+
system.epoll_ctl(
82+
backend_id,
83+
system.EPOLL_CTL_DEL,
84+
self.fd,
85+
&dummy_event) # ignore errors
86+
6487
cdef start_reading(self, Handle callback):
6588
cdef:
6689
int mask = 0

uvloop/includes/system.pxd

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,15 @@ cdef extern from "includes/compat.h" nogil:
6363

6464
cdef int EWOULDBLOCK
6565
cdef int PLATFORM_IS_APPLE
66+
67+
68+
IF UNAME_SYSNAME == "Linux":
69+
70+
cdef extern from "sys/epoll.h" nogil:
71+
72+
struct epoll_event:
73+
# We don't use the fields
74+
pass
75+
76+
int EPOLL_CTL_DEL
77+
int epoll_ctl(int epfd, int op, int fd, epoll_event *event)

uvloop/includes/uv.pxd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,7 @@ cdef extern from "uv.h" nogil:
266266
int uv_loop_init(uv_loop_t* loop)
267267
int uv_loop_close(uv_loop_t* loop)
268268
int uv_loop_alive(uv_loop_t* loop)
269+
int uv_backend_fd(uv_loop_t* loop)
269270

270271
void uv_update_time(uv_loop_t* loop)
271272
uint64_t uv_now(const uv_loop_t*)

0 commit comments

Comments
 (0)