blob: 214c78570c0473a855158c10275d2a5d37a6f280 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
# Fixes a crash in epoll due to libcurl/c-ares bug:
# PollEPoll::modify(...) epoll_ctl call failed
Index: libtorrent/src/torrent/poll_epoll.cc
===================================================================
--- libtorrent/src/torrent/poll_epoll.cc (revision 1067)
+++ libtorrent/src/torrent/poll_epoll.cc (working copy)
@@ -75,12 +75,21 @@
set_event_mask(event, mask);
- // If error is EEXIST, try again with EPOLL_CTL_MOD.
- // libcurl with c-ares may unwittingly re-open an FD closed by
- // c-ares before notified (and thus notifying us) of its closure.
if (epoll_ctl(m_fd, op, event->file_descriptor(), &e)) {
- if (op != EPOLL_CTL_ADD || errno != EEXIST ||
- epoll_ctl(m_fd, EPOLL_CTL_MOD, event->file_descriptor(), &e))
+ // Socket was probably already closed. Ignore this.
+ if (op == EPOLL_CTL_DEL && errno == ENOENT)
+ return;
+
+ // Handle some libcurl/c-ares bugs by retrying once.
+ if (op == EPOLL_CTL_ADD && errno == EEXIST) {
+ op = EPOLL_CTL_MOD;
+ errno = 0;
+ } else if (op == EPOLL_CTL_MOD && errno == ENOENT) {
+ op = EPOLL_CTL_ADD;
+ errno = 0;
+ }
+
+ if (errno || epoll_ctl(m_fd, op, event->file_descriptor(), &e))
throw internal_error("PollEPoll::modify(...) epoll_ctl call failed");
}
}
|