summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Alfredsen <loki_val@gentoo.org>2008-10-22 15:43:21 +0000
committerPeter Alfredsen <loki_val@gentoo.org>2008-10-22 15:43:21 +0000
commitcea12a6e11b66ff5ac3b06a9590cfaf52513d26d (patch)
tree33b2beb7a9d2e376586201d64fa26bf808e1ef39 /net-libs/libtorrent
parentmedia-libs/mesa: pkgmove from xf86-video-i810 to xf86-video-intel (diff)
downloadgentoo-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/ChangeLog9
-rw-r--r--net-libs/libtorrent/files/libtorrent-0.12.3-fix-poll_fd.patch230
-rw-r--r--net-libs/libtorrent/libtorrent-0.12.3-r1.ebuild51
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
+}