PKG_NAME:=libtorrent
-PKG_REV:=1106
+PKG_REV:=1123
PKG_VERSION:=0.12.6_r$(PKG_REV)
PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+++ /dev/null
-# Adjust number of pieces requested from peer if we're
-# uploading too slowly but downloading very fast so it exhausts the
-# queue before we finish sending a piece and can request more. See ticket #1302 - libtorrent.rakshasa.no
-Index: libtorrent/src/protocol/peer_connection_base.cc
-===================================================================
---- libtorrent/src/protocol/peer_connection_base.cc (revision 1060)
-+++ libtorrent/src/protocol/peer_connection_base.cc (working copy)
-@@ -783,8 +783,11 @@
- if (download_queue()->queued_empty())
- m_downStall = 0;
-
-- uint32_t pipeSize = download_queue()->calculate_pipe_size(m_peerChunks.download_throttle()->rate()->rate());
-+ uint32_t upRate = (!m_upChoke.choked() && !m_peerChunks.upload_queue()->empty()) ?
-+ m_peerChunks.upload_throttle()->rate()->rate() : 0;
-
-+ uint32_t pipeSize = download_queue()->calculate_pipe_size(m_peerChunks.download_throttle()->rate()->rate(), upRate);
-+
- // Don't start requesting if we can't do it in large enough chunks.
- if (download_queue()->queued_size() >= (pipeSize + 10) / 2)
- return false;
-Index: libtorrent/src/protocol/request_list.cc
-===================================================================
---- libtorrent/src/protocol/request_list.cc (revision 1060)
-+++ libtorrent/src/protocol/request_list.cc (working copy)
-@@ -263,22 +263,30 @@
- }
-
- uint32_t
--RequestList::calculate_pipe_size(uint32_t rate) {
-+RequestList::calculate_pipe_size(uint32_t downRate, uint32_t upRate) {
-+ // Compute how many pieces we will receive while transmitting one.
-+ // Since we can't request during that time, make sure the pipe is
-+ // big enough so it doesn't run dry.
-+ if (upRate)
-+ upRate = downRate / upRate;
-+
- // Change into KB.
-- rate /= 1024;
-+ downRate /= 1024;
-
- if (!m_delegator->get_aggressive()) {
-- if (rate < 20)
-- return rate + 2;
-+ if (downRate < 20)
-+ downRate = downRate + 2;
- else
-- return rate / 5 + 18;
-+ downRate = downRate / 5 + 18;
-
- } else {
-- if (rate < 10)
-- return rate / 5 + 1;
-+ if (downRate < 10)
-+ downRate = downRate / 5 + 1;
- else
-- return rate / 10 + 2;
-+ downRate = downRate / 10 + 2;
- }
-+
-+ return std::max(downRate, 1 + upRate);
- }
-
- }
-Index: libtorrent/src/protocol/request_list.h
-===================================================================
---- libtorrent/src/protocol/request_list.h (revision 1060)
-+++ libtorrent/src/protocol/request_list.h (working copy)
-@@ -87,7 +87,7 @@
- bool canceled_empty() const { return m_canceled.empty(); }
- size_t canceled_size() const { return m_queued.size(); }
-
-- uint32_t calculate_pipe_size(uint32_t rate);
-+ uint32_t calculate_pipe_size(uint32_t downRate, uint32_t upRate);
-
- void set_delegator(Delegator* d) { m_delegator = d; }
- void set_peer_chunks(PeerChunks* b) { m_peerChunks = b; }
--- /dev/null
+Index: libtorrent/rak/allocators.h
+===================================================================
+--- libtorrent/rak/allocators.h (revision 1121)
++++ libtorrent/rak/allocators.h (working copy)
+@@ -74,17 +74,13 @@
+ size_type max_size () const throw() { return std::numeric_limits<size_t>::max() / sizeof(T); }
+
+ pointer allocate(size_type num, const_void_pointer hint = 0) { return alloc_size(num*sizeof(T)); }
++ void deallocate (pointer p, size_type num) { dealloc_size(p, num*sizeof(T)); }
+
+- static pointer alloc_size(size_type size) {
+- pointer ptr = NULL;
+- int __UNUSED result = posix_memalign((void**)&ptr, LT_SMP_CACHE_BYTES, size);
++ static pointer alloc_size(size_type size);
++ static void dealloc_size(pointer p, size_type size);
+
+- return ptr;
+- }
+-
+ void construct (pointer p, const T& value) { new((void*)p)T(value); }
+ void destroy (pointer p) { p->~T(); }
+- void deallocate (pointer p, size_type num) { ::operator delete((void*)p); }
+ };
+
+
+@@ -98,8 +94,38 @@
+ return false;
+ }
+
++template <class T>
++inline typename cacheline_allocator<T>::pointer cacheline_allocator<T>::alloc_size(size_type size) {
++ pointer ptr;
++
++#if HAVE_POSIX_MEMALIGN
++ if (posix_memalign((void**)&ptr, LT_SMP_CACHE_BYTES, size))
++ return NULL;
++#else
++ char* org = (char*)malloc(size + sizeof(void*) + LT_SMP_CACHE_BYTES - 1);
++ if (org == NULL)
++ return NULL;
++
++ ptr = (pointer)((uintptr_t)(org + LT_SMP_CACHE_BYTES - 1) & ~(LT_SMP_CACHE_BYTES - 1));
++
++ // store originally allocated pointer for later free() at the end of the allocated data
++ *(void**)((char*)ptr + size) = org;
++#endif
++
++ return ptr;
+ }
+
++template <class T>
++inline void cacheline_allocator<T>::dealloc_size(pointer p, size_type size) {
++#if HAVE_POSIX_MEMALIGN
++ free(p);
++#else
++ free(*(void**)((char*)p + size));
++#endif
++}
++
++}
++
+ //
+ // Operator new with custom allocators:
+ //
--- /dev/null
+Index: libtorrent/src/net/socket_datagram.cc
+===================================================================
+--- libtorrent/src/net/socket_datagram.cc (revision 1121)
++++ libtorrent/src/net/socket_datagram.cc (working copy)
+@@ -73,6 +73,23 @@
+ int r;
+
+ if (sa != NULL) {
++#ifdef RAK_USE_INET6
++ if (m_ipv6_socket && sa->family() == rak::socket_address::pf_inet) {
++ uint32_t addr32[4];
++ sockaddr_in6 mapped_addr;
++ memset(&mapped_addr, 0, sizeof(mapped_addr));
++ mapped_addr.sin6_family = AF_INET6;
++ addr32[0] = 0;
++ addr32[1] = 0;
++ addr32[2] = htonl(0xffff);
++ addr32[3] = sa->sa_inet()->address_n();
++ memcpy(mapped_addr.sin6_addr.s6_addr, addr32, sizeof(uint32_t) * 4);
++ mapped_addr.sin6_port = sa->sa_inet()->port_n();
++ r = ::sendto(m_fileDesc, buffer, length, 0, (sockaddr*)&mapped_addr, sizeof(mapped_addr));
++ } else if (m_ipv6_socket && sa->family() == rak::socket_address::pf_inet6) {
++ r = ::sendto(m_fileDesc, buffer, length, 0, sa->sa_inet6()->c_sockaddr(), sizeof(rak::socket_address_inet6));
++ } else
++#endif
+ r = ::sendto(m_fileDesc, buffer, length, 0, sa->sa_inet()->c_sockaddr(), sizeof(rak::socket_address_inet));
+ } else {
+ r = ::send(m_fileDesc, buffer, length, 0);
--- /dev/null
+Index: libtorrent/src/net/socket_set.h
+===================================================================
+--- libtorrent/src/net/socket_set.h (revision 1121)
++++ libtorrent/src/net/socket_set.h (working copy)
+@@ -53,12 +53,12 @@
+
+ // Propably should rename to EventSet...
+
+-class SocketSet : private std::vector<Event*, rak::cacheline_allocator<> > {
++class SocketSet : private std::vector<Event*, rak::cacheline_allocator<Event*> > {
+ public:
+ typedef uint32_t size_type;
+
+- typedef std::vector<Event*, rak::cacheline_allocator<> > base_type;
+- typedef std::vector<size_type, rak::cacheline_allocator<> > Table;
++ typedef std::vector<Event*, rak::cacheline_allocator<Event*> > base_type;
++ typedef std::vector<size_type, rak::cacheline_allocator<size_type> > Table;
+
+ static const size_type npos = static_cast<size_type>(-1);
+