diff options
author | Peter Alfredsen <loki_val@gentoo.org> | 2008-10-22 15:43:21 +0000 |
---|---|---|
committer | Peter Alfredsen <loki_val@gentoo.org> | 2008-10-22 15:43:21 +0000 |
commit | cea12a6e11b66ff5ac3b06a9590cfaf52513d26d (patch) | |
tree | 33b2beb7a9d2e376586201d64fa26bf808e1ef39 /net-libs/libtorrent | |
parent | media-libs/mesa: pkgmove from xf86-video-i810 to xf86-video-intel (diff) | |
download | gentoo-2-cea12a6e11b66ff5ac3b06a9590cfaf52513d26d.tar.gz gentoo-2-cea12a6e11b66ff5ac3b06a9590cfaf52513d26d.tar.bz2 gentoo-2-cea12a6e11b66ff5ac3b06a9590cfaf52513d26d.zip |
Fix _ZN7torrent9PollEPoll7performEv crash with fix from upstream ticket 1497 by Josef Drexler.
(Portage version: 2.2_rc12/cvs/Linux 2.6.27 x86_64)
Diffstat (limited to 'net-libs/libtorrent')
-rw-r--r-- | net-libs/libtorrent/ChangeLog | 9 | ||||
-rw-r--r-- | net-libs/libtorrent/files/libtorrent-0.12.3-fix-poll_fd.patch | 230 | ||||
-rw-r--r-- | net-libs/libtorrent/libtorrent-0.12.3-r1.ebuild | 51 |
3 files changed, 289 insertions, 1 deletions
diff --git a/net-libs/libtorrent/ChangeLog b/net-libs/libtorrent/ChangeLog index 74426c9f3398..9ea46ef9ea8c 100644 --- a/net-libs/libtorrent/ChangeLog +++ b/net-libs/libtorrent/ChangeLog @@ -1,6 +1,13 @@ # ChangeLog for net-libs/libtorrent # Copyright 1999-2008 Gentoo Foundation; Distributed under the GPL v2 -# $Header: /var/cvsroot/gentoo-x86/net-libs/libtorrent/ChangeLog,v 1.129 2008/10/04 12:57:07 ranger Exp $ +# $Header: /var/cvsroot/gentoo-x86/net-libs/libtorrent/ChangeLog,v 1.130 2008/10/22 15:43:20 loki_val Exp $ + +*libtorrent-0.12.3-r1 (22 Oct 2008) + + 22 Oct 2008; Peter Alfredsen <loki_val@gentoo.org> + +files/libtorrent-0.12.3-fix-poll_fd.patch, +libtorrent-0.12.3-r1.ebuild: + Fix _ZN7torrent9PollEPoll7performEv crash with fix from upstream ticket + 1497 by Josef Drexler. 04 Oct 2008; Brent Baude <ranger@gentoo.org> libtorrent-0.12.2-r4.ebuild: Marking libtorrent-0.12.2-r4 ppc64 for bug 238611 diff --git a/net-libs/libtorrent/files/libtorrent-0.12.3-fix-poll_fd.patch b/net-libs/libtorrent/files/libtorrent-0.12.3-fix-poll_fd.patch new file mode 100644 index 000000000000..2d6d7afc87b4 --- /dev/null +++ b/net-libs/libtorrent/files/libtorrent-0.12.3-fix-poll_fd.patch @@ -0,0 +1,230 @@ +# Changes epoll/kqueue to operate by file descriptors, not +# event pointers, to hopefully fix the recent poll crashes. +Index: libtorrent/src/torrent/poll_epoll.cc +=================================================================== +--- libtorrent/src/torrent/poll_epoll.cc (revision 1072) ++++ libtorrent/src/torrent/poll_epoll.cc (working copy) +@@ -37,6 +37,7 @@ + #include "config.h" + + #include <cerrno> ++#include <cstring> + + #include <unistd.h> + #include <torrent/exceptions.h> +@@ -60,7 +61,7 @@ + + inline void + PollEPoll::set_event_mask(Event* e, uint32_t m) { +- m_table[e->file_descriptor()] = std::make_pair(m, e); ++ m_table[e->file_descriptor()] = Table::value_type(m, e); + } + + inline void +@@ -70,7 +71,7 @@ + + epoll_event e; + e.data.u64 = 0; // Make valgrind happy? Remove please. +- e.data.ptr = event; ++ e.data.fd = event->file_descriptor(); + e.events = mask; + + set_event_mask(event, mask); +@@ -81,16 +82,20 @@ + return; + + // Handle some libcurl/c-ares bugs by retrying once. ++ int retry = op; + if (op == EPOLL_CTL_ADD && errno == EEXIST) { +- op = EPOLL_CTL_MOD; ++ retry = EPOLL_CTL_MOD; + errno = 0; + } else if (op == EPOLL_CTL_MOD && errno == ENOENT) { +- op = EPOLL_CTL_ADD; ++ retry = 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"); ++ if (errno || epoll_ctl(m_fd, retry, event->file_descriptor(), &e)) { ++ char errmsg[1024]; ++ snprintf(errmsg, sizeof(errmsg), "PollEPoll::modify(...) epoll_ctl(%d, %d -> %d, %d, [%p:%x]) = %d: %s", m_fd, op, retry, event->file_descriptor(), event, mask, errno, strerror(errno)); ++ throw internal_error(errmsg); ++ } + } + } + +@@ -138,20 +143,25 @@ + void + PollEPoll::perform() { + for (epoll_event *itr = m_events, *last = m_events + m_waitingEvents; itr != last; ++itr) { ++ if (itr->data.fd < 0 || (size_t)itr->data.fd >= m_table.size()) ++ continue; ++ ++ Table::iterator evItr = m_table.begin() + itr->data.fd; ++ + // Each branch must check for data.ptr != NULL to allow the socket + // to remove itself between the calls. + // + // TODO: Make it so that it checks that read/write is wanted, that + // it wasn't removed from one of them but not closed. + +- if (itr->events & EPOLLERR && itr->data.ptr != NULL && event_mask((Event*)itr->data.ptr) & EPOLLERR) +- ((Event*)itr->data.ptr)->event_error(); ++ if (itr->events & EPOLLERR && evItr->second != NULL && evItr->first & EPOLLERR) ++ evItr->second->event_error(); + +- if (itr->events & EPOLLIN && itr->data.ptr != NULL && event_mask((Event*)itr->data.ptr) & EPOLLIN) +- ((Event*)itr->data.ptr)->event_read(); ++ if (itr->events & EPOLLIN && evItr->second != NULL && evItr->first & EPOLLIN) ++ evItr->second->event_read(); + +- if (itr->events & EPOLLOUT && itr->data.ptr != NULL && event_mask((Event*)itr->data.ptr) & EPOLLOUT) +- ((Event*)itr->data.ptr)->event_write(); ++ if (itr->events & EPOLLOUT && evItr->second != NULL && evItr->first & EPOLLOUT) ++ evItr->second->event_write(); + } + + m_waitingEvents = 0; +@@ -173,9 +183,14 @@ + if (event_mask(event) != 0) + throw internal_error("PollEPoll::close(...) called but the file descriptor is active"); + ++ m_table[event->file_descriptor()] = Table::value_type(); ++ ++ /* ++ Shouldn't be needed anymore. + for (epoll_event *itr = m_events, *last = m_events + m_waitingEvents; itr != last; ++itr) + if (itr->data.ptr == event) + itr->data.ptr = NULL; ++ */ + } + + void +@@ -183,12 +198,14 @@ + // Kernel removes closed FDs automatically, so just clear the mask and remove it from pending calls. + // Don't touch if the FD was re-used before we received the close notification. + if (m_table[event->file_descriptor()].second == event) +- set_event_mask(event, 0); ++ m_table[event->file_descriptor()] = Table::value_type(); + ++ /* + for (epoll_event *itr = m_events, *last = m_events + m_waitingEvents; itr != last; ++itr) { + if (itr->data.ptr == event) + itr->data.ptr = NULL; + } ++ */ + } + + // Use custom defines for EPOLL* to make the below code compile with +Index: libtorrent/src/torrent/poll_kqueue.cc +=================================================================== +--- libtorrent/src/torrent/poll_kqueue.cc (revision 1072) ++++ libtorrent/src/torrent/poll_kqueue.cc (working copy) +@@ -70,7 +70,7 @@ + PollKQueue::set_event_mask(Event* e, uint32_t m) { + assert(e->file_descriptor() != -1); + +- m_table[e->file_descriptor()] = std::make_pair(m, e); ++ m_table[e->file_descriptor()] = Table::value_type(m, e); + } + + void +@@ -87,7 +87,7 @@ + + void + PollKQueue::modify(Event* event, unsigned short op, short mask) { +- // Flush the changed filters to the kernel if the buffer if full. ++ // Flush the changed filters to the kernel if the buffer is full. + if (m_changedEvents == m_table.size()) + flush_events(); + +@@ -100,7 +100,8 @@ + + struct kevent* itr = m_changes + (m_changedEvents++); + +- EV_SET(itr, event->file_descriptor(), mask, op, 0, 0, event); ++ assert(event == m_table[event->file_descriptor()].second); ++ EV_SET(itr, event->file_descriptor(), mask, op, 0, 0, NULL); + } + + PollKQueue* +@@ -196,8 +197,9 @@ + return nfds; + + if (FD_ISSET(0, readSet)) { ++ m_events[m_waitingEvents].ident = 0; + m_events[m_waitingEvents].filter = EVFILT_READ; +- m_events[m_waitingEvents].udata = m_stdinEvent; ++ m_events[m_waitingEvents].flags = 0; + m_waitingEvents++; + } + +@@ -208,19 +210,24 @@ + void + PollKQueue::perform() { + for (struct kevent *itr = m_events, *last = m_events + m_waitingEvents; itr != last; ++itr) { +- if ((itr->flags & EV_ERROR) && itr->udata != NULL) { +- if (event_mask((Event*)itr->udata) & flag_error) +- ((Event*)itr->udata)->event_error(); ++ if (itr->ident < 0 || itr->ident >= m_table.size()) + continue; ++ ++ Table::iterator evItr = m_table.begin() + itr->ident; ++ ++ if ((itr->flags & EV_ERROR) && evItr->second != NULL) { ++ if (evItr->first & flag_error) ++ evItr->second->event_error(); ++ continue; + } + + // Also check current mask. + +- if (itr->filter == EVFILT_READ && itr->udata != NULL && event_mask((Event*)itr->udata) & flag_read) +- ((Event*)itr->udata)->event_read(); ++ if (itr->filter == EVFILT_READ && evItr->second != NULL && evItr->first & flag_read) ++ evItr->second->event_read(); + +- if (itr->filter == EVFILT_WRITE && itr->udata != NULL && event_mask((Event*)itr->udata) & flag_write) +- ((Event*)itr->udata)->event_write(); ++ if (itr->filter == EVFILT_WRITE && evItr->second != NULL && evItr->first & flag_write) ++ evItr->second->event_write(); + } + + m_waitingEvents = 0; +@@ -249,11 +256,16 @@ + if (event_mask(event) != 0) + throw internal_error("PollKQueue::close(...) called but the file descriptor is active"); + ++ m_table[event->file_descriptor()] = Table::value_type(); ++ ++ /* ++ Shouldn't be needed anymore. + for (struct kevent *itr = m_events, *last = m_events + m_waitingEvents; itr != last; ++itr) + if (itr->udata == event) + itr->udata = NULL; + + m_changedEvents = std::remove_if(m_changes, m_changes + m_changedEvents, rak::equal(event, rak::mem_ref(&kevent::udata))) - m_changes; ++ */ + } + + void +@@ -269,14 +281,16 @@ + // and remove it from pending calls. Don't touch if the FD was + // re-used before we received the close notification. + if (m_table[event->file_descriptor()].second == event) +- set_event_mask(event, 0); ++ m_table[event->file_descriptor()] = Table::value_type(); + ++ /* + for (struct kevent *itr = m_events, *last = m_events + m_waitingEvents; itr != last; ++itr) { + if (itr->udata == event) + itr->udata = NULL; + } + + m_changedEvents = std::remove_if(m_changes, m_changes + m_changedEvents, rak::equal(event, rak::mem_ref(&kevent::udata))) - m_changes; ++ */ + } + + // Use custom defines for EPOLL* to make the below code compile with diff --git a/net-libs/libtorrent/libtorrent-0.12.3-r1.ebuild b/net-libs/libtorrent/libtorrent-0.12.3-r1.ebuild new file mode 100644 index 000000000000..ab2e35d605d4 --- /dev/null +++ b/net-libs/libtorrent/libtorrent-0.12.3-r1.ebuild @@ -0,0 +1,51 @@ +# Copyright 1999-2008 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/net-libs/libtorrent/libtorrent-0.12.3-r1.ebuild,v 1.1 2008/10/22 15:43:20 loki_val Exp $ + +inherit base eutils toolchain-funcs flag-o-matic libtool + +DESCRIPTION="LibTorrent is a BitTorrent library written in C++ for *nix." +HOMEPAGE="http://libtorrent.rakshasa.no/" +SRC_URI="http://libtorrent.rakshasa.no/downloads/${P}.tar.gz" +SLOT="0" +LICENSE="GPL-2" +KEYWORDS="~amd64 ~hppa ~ia64 ~ppc ~ppc64 ~sparc ~x86 ~x86-fbsd" + +IUSE="debug ipv6" + +RDEPEND=">=dev-libs/libsigc++-2" +DEPEND="${RDEPEND} + dev-util/pkgconfig" + +PATCHES=( "${FILESDIR}/${P}-fix-epoll-crash.patch" + "${FILESDIR}/${P}-fix-poll_fd.patch" ) + +src_unpack() { + base_src_unpack + cd "${S}" + elibtoolize #Don't remove. Needed for *bsd. +} + +src_compile() { + replace-flags -Os -O2 + + if [[ $(tc-arch) = "x86" ]]; then + filter-flags -fomit-frame-pointer -fforce-addr + fi + + econf \ + $(use_enable debug) \ + $(use_enable ipv6) \ + --enable-aligned \ + --enable-static \ + --enable-shared \ + --disable-dependency-tracking \ + || die "econf failed" + + emake || die "emake failed" +} + +src_install() { + emake DESTDIR="${D}" install || die "make install failed" + dodoc AUTHORS NEWS README +} |