mirror of
https://github.com/codex-storage/deluge.git
synced 2025-02-26 10:05:19 +00:00
sync lt and asio 1615 and upload version # of plugin
This commit is contained in:
parent
c0d8bf2d7f
commit
3de1cb9938
219
libtorrent/include/libtorrent/asio/detail/handler_queue.hpp
Normal file
219
libtorrent/include/libtorrent/asio/detail/handler_queue.hpp
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
//
|
||||||
|
// handler_queue.hpp
|
||||||
|
// ~~~~~~~~~~~~~~~~~
|
||||||
|
//
|
||||||
|
// Copyright (c) 2003-2007 Christopher M. Kohlhoff (chris at kohlhoff dot com)
|
||||||
|
//
|
||||||
|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||||
|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef ASIO_DETAIL_HANDLER_QUEUE_HPP
|
||||||
|
#define ASIO_DETAIL_HANDLER_QUEUE_HPP
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
# pragma once
|
||||||
|
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
|
||||||
|
|
||||||
|
#include "asio/detail/push_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/detail/handler_alloc_helpers.hpp"
|
||||||
|
#include "asio/detail/handler_invoke_helpers.hpp"
|
||||||
|
#include "asio/detail/noncopyable.hpp"
|
||||||
|
|
||||||
|
namespace asio {
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
class handler_queue
|
||||||
|
: private noncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Base class for handlers in the queue.
|
||||||
|
class handler
|
||||||
|
: private noncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void invoke()
|
||||||
|
{
|
||||||
|
invoke_func_(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void destroy()
|
||||||
|
{
|
||||||
|
destroy_func_(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
typedef void (*invoke_func_type)(handler*);
|
||||||
|
typedef void (*destroy_func_type)(handler*);
|
||||||
|
|
||||||
|
handler(invoke_func_type invoke_func,
|
||||||
|
destroy_func_type destroy_func)
|
||||||
|
: next_(0),
|
||||||
|
invoke_func_(invoke_func),
|
||||||
|
destroy_func_(destroy_func)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~handler()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class handler_queue;
|
||||||
|
handler* next_;
|
||||||
|
invoke_func_type invoke_func_;
|
||||||
|
destroy_func_type destroy_func_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Smart point to manager handler lifetimes.
|
||||||
|
class scoped_ptr
|
||||||
|
: private noncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit scoped_ptr(handler* h)
|
||||||
|
: handler_(h)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~scoped_ptr()
|
||||||
|
{
|
||||||
|
if (handler_)
|
||||||
|
handler_->destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
handler* get() const
|
||||||
|
{
|
||||||
|
return handler_;
|
||||||
|
}
|
||||||
|
|
||||||
|
handler* release()
|
||||||
|
{
|
||||||
|
handler* tmp = handler_;
|
||||||
|
handler_ = 0;
|
||||||
|
return tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
handler* handler_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Constructor.
|
||||||
|
handler_queue()
|
||||||
|
: front_(0),
|
||||||
|
back_(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap a handler to be pushed into the queue.
|
||||||
|
template <typename Handler>
|
||||||
|
static handler* wrap(Handler h)
|
||||||
|
{
|
||||||
|
// Allocate and construct an object to wrap the handler.
|
||||||
|
typedef handler_wrapper<Handler> value_type;
|
||||||
|
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
|
||||||
|
raw_handler_ptr<alloc_traits> raw_ptr(h);
|
||||||
|
handler_ptr<alloc_traits> ptr(raw_ptr, h);
|
||||||
|
return ptr.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the handler at the front of the queue.
|
||||||
|
handler* front()
|
||||||
|
{
|
||||||
|
return front_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pop a handler from the front of the queue.
|
||||||
|
void pop()
|
||||||
|
{
|
||||||
|
if (front_)
|
||||||
|
{
|
||||||
|
handler* tmp = front_;
|
||||||
|
front_ = front_->next_;
|
||||||
|
if (front_ == 0)
|
||||||
|
back_ = 0;
|
||||||
|
tmp->next_= 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Push a handler on to the back of the queue.
|
||||||
|
void push(handler* h)
|
||||||
|
{
|
||||||
|
h->next_ = 0;
|
||||||
|
if (back_)
|
||||||
|
{
|
||||||
|
back_->next_ = h;
|
||||||
|
back_ = h;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
front_ = back_ = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Whether the queue is empty.
|
||||||
|
bool empty() const
|
||||||
|
{
|
||||||
|
return front_ == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Template wrapper for handlers.
|
||||||
|
template <typename Handler>
|
||||||
|
class handler_wrapper
|
||||||
|
: public handler
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
handler_wrapper(Handler h)
|
||||||
|
: handler(
|
||||||
|
&handler_wrapper<Handler>::do_call,
|
||||||
|
&handler_wrapper<Handler>::do_destroy),
|
||||||
|
handler_(h)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_call(handler* base)
|
||||||
|
{
|
||||||
|
// Take ownership of the handler object.
|
||||||
|
typedef handler_wrapper<Handler> this_type;
|
||||||
|
this_type* h(static_cast<this_type*>(base));
|
||||||
|
typedef handler_alloc_traits<Handler, this_type> alloc_traits;
|
||||||
|
handler_ptr<alloc_traits> ptr(h->handler_, h);
|
||||||
|
|
||||||
|
// Make a copy of the handler so that the memory can be deallocated before
|
||||||
|
// the upcall is made.
|
||||||
|
Handler handler(h->handler_);
|
||||||
|
|
||||||
|
// Free the memory associated with the handler.
|
||||||
|
ptr.reset();
|
||||||
|
|
||||||
|
// Make the upcall.
|
||||||
|
asio_handler_invoke_helpers::invoke(handler, &handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void do_destroy(handler* base)
|
||||||
|
{
|
||||||
|
// Take ownership of the handler object.
|
||||||
|
typedef handler_wrapper<Handler> this_type;
|
||||||
|
this_type* h(static_cast<this_type*>(base));
|
||||||
|
typedef handler_alloc_traits<Handler, this_type> alloc_traits;
|
||||||
|
handler_ptr<alloc_traits> ptr(h->handler_, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Handler handler_;
|
||||||
|
};
|
||||||
|
|
||||||
|
// The front of the queue.
|
||||||
|
handler* front_;
|
||||||
|
|
||||||
|
// The back of the queue.
|
||||||
|
handler* back_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace asio
|
||||||
|
|
||||||
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#endif // ASIO_DETAIL_HANDLER_QUEUE_HPP
|
@ -450,7 +450,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
endpoint_type endpoint;
|
endpoint_type endpoint;
|
||||||
socket_addr_len_type addr_len = endpoint.capacity();
|
std::size_t addr_len = endpoint.capacity();
|
||||||
if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec))
|
if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec))
|
||||||
return endpoint_type();
|
return endpoint_type();
|
||||||
endpoint.resize(addr_len);
|
endpoint.resize(addr_len);
|
||||||
@ -468,7 +468,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
endpoint_type endpoint;
|
endpoint_type endpoint;
|
||||||
socket_addr_len_type addr_len = endpoint.capacity();
|
std::size_t addr_len = endpoint.capacity();
|
||||||
if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec))
|
if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec))
|
||||||
return endpoint_type();
|
return endpoint_type();
|
||||||
endpoint.resize(addr_len);
|
endpoint.resize(addr_len);
|
||||||
@ -1073,7 +1073,7 @@ public:
|
|||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
// Try to complete the operation without blocking.
|
// Try to complete the operation without blocking.
|
||||||
socket_addr_len_type addr_len = sender_endpoint.capacity();
|
std::size_t addr_len = sender_endpoint.capacity();
|
||||||
int bytes_recvd = socket_ops::recvfrom(impl.socket_, bufs, i, flags,
|
int bytes_recvd = socket_ops::recvfrom(impl.socket_, bufs, i, flags,
|
||||||
sender_endpoint.data(), &addr_len, ec);
|
sender_endpoint.data(), &addr_len, ec);
|
||||||
|
|
||||||
@ -1144,7 +1144,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Receive some data.
|
// Receive some data.
|
||||||
socket_addr_len_type addr_len = sender_endpoint_.capacity();
|
std::size_t addr_len = sender_endpoint_.capacity();
|
||||||
asio::error_code ec;
|
asio::error_code ec;
|
||||||
int bytes = socket_ops::recvfrom(socket_, bufs, i, flags_,
|
int bytes = socket_ops::recvfrom(socket_, bufs, i, flags_,
|
||||||
sender_endpoint_.data(), &addr_len, ec);
|
sender_endpoint_.data(), &addr_len, ec);
|
||||||
@ -1242,7 +1242,7 @@ public:
|
|||||||
// Try to complete the operation without blocking.
|
// Try to complete the operation without blocking.
|
||||||
asio::error_code ec;
|
asio::error_code ec;
|
||||||
socket_holder new_socket;
|
socket_holder new_socket;
|
||||||
socket_addr_len_type addr_len = 0;
|
std::size_t addr_len = 0;
|
||||||
if (peer_endpoint)
|
if (peer_endpoint)
|
||||||
{
|
{
|
||||||
addr_len = peer_endpoint->capacity();
|
addr_len = peer_endpoint->capacity();
|
||||||
@ -1327,7 +1327,7 @@ public:
|
|||||||
// Accept the waiting connection.
|
// Accept the waiting connection.
|
||||||
asio::error_code ec;
|
asio::error_code ec;
|
||||||
socket_holder new_socket;
|
socket_holder new_socket;
|
||||||
socket_addr_len_type addr_len = 0;
|
std::size_t addr_len = 0;
|
||||||
if (peer_endpoint_)
|
if (peer_endpoint_)
|
||||||
{
|
{
|
||||||
addr_len = peer_endpoint_->capacity();
|
addr_len = peer_endpoint_->capacity();
|
||||||
|
@ -26,9 +26,6 @@
|
|||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <boost/detail/workaround.hpp>
|
#include <boost/detail/workaround.hpp>
|
||||||
#include <new>
|
#include <new>
|
||||||
#if defined(__MACH__) && defined(__APPLE__)
|
|
||||||
# include <AvailabilityMacros.h>
|
|
||||||
#endif // defined(__MACH__) && defined(__APPLE__)
|
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#include "asio/error.hpp"
|
#include "asio/error.hpp"
|
||||||
@ -38,6 +35,10 @@ namespace asio {
|
|||||||
namespace detail {
|
namespace detail {
|
||||||
namespace socket_ops {
|
namespace socket_ops {
|
||||||
|
|
||||||
|
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
|
struct msghdr { int msg_namelen; };
|
||||||
|
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
|
|
||||||
inline void clear_error(asio::error_code& ec)
|
inline void clear_error(asio::error_code& ec)
|
||||||
{
|
{
|
||||||
errno = 0;
|
errno = 0;
|
||||||
@ -60,15 +61,28 @@ inline ReturnType error_wrapper(ReturnType return_value,
|
|||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename SockLenType>
|
||||||
|
inline socket_type call_accept(SockLenType msghdr::*,
|
||||||
|
socket_type s, socket_addr_type* addr, std::size_t* addrlen)
|
||||||
|
{
|
||||||
|
SockLenType tmp_addrlen = addrlen ? (SockLenType)*addrlen : 0;
|
||||||
|
socket_type result = ::accept(s, addr, addrlen ? &tmp_addrlen : 0);
|
||||||
|
if (addrlen)
|
||||||
|
*addrlen = (std::size_t)tmp_addrlen;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
inline socket_type accept(socket_type s, socket_addr_type* addr,
|
inline socket_type accept(socket_type s, socket_addr_type* addr,
|
||||||
socket_addr_len_type* addrlen, asio::error_code& ec)
|
std::size_t* addrlen, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
|
|
||||||
socket_type new_s = error_wrapper(::accept(s, addr, addrlen), ec);
|
socket_type new_s = error_wrapper(call_accept(
|
||||||
|
&msghdr::msg_namelen, s, addr, addrlen), ec);
|
||||||
if (new_s == invalid_socket)
|
if (new_s == invalid_socket)
|
||||||
return new_s;
|
return new_s;
|
||||||
|
|
||||||
|
#if defined(__MACH__) && defined(__APPLE__) || defined(__FreeBSD__)
|
||||||
int optval = 1;
|
int optval = 1;
|
||||||
int result = error_wrapper(::setsockopt(new_s,
|
int result = error_wrapper(::setsockopt(new_s,
|
||||||
SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);
|
SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval)), ec);
|
||||||
@ -77,18 +91,23 @@ inline socket_type accept(socket_type s, socket_addr_type* addr,
|
|||||||
::close(new_s);
|
::close(new_s);
|
||||||
return invalid_socket;
|
return invalid_socket;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return new_s;
|
return new_s;
|
||||||
#else
|
}
|
||||||
return error_wrapper(::accept(s, addr, addrlen), ec);
|
|
||||||
#endif
|
template <typename SockLenType>
|
||||||
|
inline int call_bind(SockLenType msghdr::*,
|
||||||
|
socket_type s, const socket_addr_type* addr, std::size_t addrlen)
|
||||||
|
{
|
||||||
|
return ::bind(s, addr, (SockLenType)addrlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int bind(socket_type s, const socket_addr_type* addr,
|
inline int bind(socket_type s, const socket_addr_type* addr,
|
||||||
socket_addr_len_type addrlen, asio::error_code& ec)
|
std::size_t addrlen, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
return error_wrapper(::bind(s, addr, addrlen), ec);
|
return error_wrapper(call_bind(&msghdr::msg_namelen, s, addr, addrlen), ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int close(socket_type s, asio::error_code& ec)
|
inline int close(socket_type s, asio::error_code& ec)
|
||||||
@ -107,11 +126,19 @@ inline int shutdown(socket_type s, int what, asio::error_code& ec)
|
|||||||
return error_wrapper(::shutdown(s, what), ec);
|
return error_wrapper(::shutdown(s, what), ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename SockLenType>
|
||||||
|
inline int call_connect(SockLenType msghdr::*,
|
||||||
|
socket_type s, const socket_addr_type* addr, std::size_t addrlen)
|
||||||
|
{
|
||||||
|
return ::connect(s, addr, (SockLenType)addrlen);
|
||||||
|
}
|
||||||
|
|
||||||
inline int connect(socket_type s, const socket_addr_type* addr,
|
inline int connect(socket_type s, const socket_addr_type* addr,
|
||||||
socket_addr_len_type addrlen, asio::error_code& ec)
|
std::size_t addrlen, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
return error_wrapper(::connect(s, addr, addrlen), ec);
|
return error_wrapper(call_connect(
|
||||||
|
&msghdr::msg_namelen, s, addr, addrlen), ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int listen(socket_type s, int backlog, asio::error_code& ec)
|
inline int listen(socket_type s, int backlog, asio::error_code& ec)
|
||||||
@ -148,6 +175,28 @@ inline void init_buf(buf& b, const void* data, size_t size)
|
|||||||
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void init_msghdr_msg_name(void*& name, socket_addr_type* addr)
|
||||||
|
{
|
||||||
|
name = addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void init_msghdr_msg_name(void*& name, const socket_addr_type* addr)
|
||||||
|
{
|
||||||
|
name = const_cast<socket_addr_type*>(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void init_msghdr_msg_name(T& name, socket_addr_type* addr)
|
||||||
|
{
|
||||||
|
name = reinterpret_cast<T>(addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void init_msghdr_msg_name(T& name, const socket_addr_type* addr)
|
||||||
|
{
|
||||||
|
name = reinterpret_cast<T>(const_cast<socket_addr_type*>(addr));
|
||||||
|
}
|
||||||
|
|
||||||
inline int recv(socket_type s, buf* bufs, size_t count, int flags,
|
inline int recv(socket_type s, buf* bufs, size_t count, int flags,
|
||||||
asio::error_code& ec)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
@ -163,20 +212,15 @@ inline int recv(socket_type s, buf* bufs, size_t count, int flags,
|
|||||||
return -1;
|
return -1;
|
||||||
return bytes_transferred;
|
return bytes_transferred;
|
||||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
msghdr msg;
|
msghdr msg = msghdr();
|
||||||
msg.msg_name = 0;
|
|
||||||
msg.msg_namelen = 0;
|
|
||||||
msg.msg_iov = bufs;
|
msg.msg_iov = bufs;
|
||||||
msg.msg_iovlen = count;
|
msg.msg_iovlen = count;
|
||||||
msg.msg_control = 0;
|
|
||||||
msg.msg_controllen = 0;
|
|
||||||
msg.msg_flags = 0;
|
|
||||||
return error_wrapper(::recvmsg(s, &msg, flags), ec);
|
return error_wrapper(::recvmsg(s, &msg, flags), ec);
|
||||||
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int recvfrom(socket_type s, buf* bufs, size_t count, int flags,
|
inline int recvfrom(socket_type s, buf* bufs, size_t count, int flags,
|
||||||
socket_addr_type* addr, socket_addr_len_type* addrlen,
|
socket_addr_type* addr, std::size_t* addrlen,
|
||||||
asio::error_code& ec)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
@ -185,25 +229,19 @@ inline int recvfrom(socket_type s, buf* bufs, size_t count, int flags,
|
|||||||
DWORD recv_buf_count = static_cast<DWORD>(count);
|
DWORD recv_buf_count = static_cast<DWORD>(count);
|
||||||
DWORD bytes_transferred = 0;
|
DWORD bytes_transferred = 0;
|
||||||
DWORD recv_flags = flags;
|
DWORD recv_flags = flags;
|
||||||
|
int tmp_addrlen = (int)*addrlen;
|
||||||
int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count,
|
int result = error_wrapper(::WSARecvFrom(s, bufs, recv_buf_count,
|
||||||
&bytes_transferred, &recv_flags, addr, addrlen, 0, 0), ec);
|
&bytes_transferred, &recv_flags, addr, &tmp_addrlen, 0, 0), ec);
|
||||||
|
*addrlen = (std::size_t)tmp_addrlen;
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
return -1;
|
return -1;
|
||||||
return bytes_transferred;
|
return bytes_transferred;
|
||||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
msghdr msg;
|
msghdr msg = msghdr();
|
||||||
#if defined(__MACH__) && defined(__APPLE__) \
|
init_msghdr_msg_name(msg.msg_name, addr);
|
||||||
&& (MAC_OS_X_VERSION_MAX_ALLOWED < 1040)
|
|
||||||
msg.msg_name = reinterpret_cast<char*>(addr);
|
|
||||||
#else
|
|
||||||
msg.msg_name = addr;
|
|
||||||
#endif
|
|
||||||
msg.msg_namelen = *addrlen;
|
msg.msg_namelen = *addrlen;
|
||||||
msg.msg_iov = bufs;
|
msg.msg_iov = bufs;
|
||||||
msg.msg_iovlen = count;
|
msg.msg_iovlen = count;
|
||||||
msg.msg_control = 0;
|
|
||||||
msg.msg_controllen = 0;
|
|
||||||
msg.msg_flags = 0;
|
|
||||||
int result = error_wrapper(::recvmsg(s, &msg, flags), ec);
|
int result = error_wrapper(::recvmsg(s, &msg, flags), ec);
|
||||||
*addrlen = msg.msg_namelen;
|
*addrlen = msg.msg_namelen;
|
||||||
return result;
|
return result;
|
||||||
@ -225,14 +263,9 @@ inline int send(socket_type s, const buf* bufs, size_t count, int flags,
|
|||||||
return -1;
|
return -1;
|
||||||
return bytes_transferred;
|
return bytes_transferred;
|
||||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
msghdr msg;
|
msghdr msg = msghdr();
|
||||||
msg.msg_name = 0;
|
|
||||||
msg.msg_namelen = 0;
|
|
||||||
msg.msg_iov = const_cast<buf*>(bufs);
|
msg.msg_iov = const_cast<buf*>(bufs);
|
||||||
msg.msg_iovlen = count;
|
msg.msg_iovlen = count;
|
||||||
msg.msg_control = 0;
|
|
||||||
msg.msg_controllen = 0;
|
|
||||||
msg.msg_flags = 0;
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
flags |= MSG_NOSIGNAL;
|
flags |= MSG_NOSIGNAL;
|
||||||
#endif // defined(__linux__)
|
#endif // defined(__linux__)
|
||||||
@ -241,7 +274,7 @@ inline int send(socket_type s, const buf* bufs, size_t count, int flags,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline int sendto(socket_type s, const buf* bufs, size_t count, int flags,
|
inline int sendto(socket_type s, const buf* bufs, size_t count, int flags,
|
||||||
const socket_addr_type* addr, socket_addr_len_type addrlen,
|
const socket_addr_type* addr, std::size_t addrlen,
|
||||||
asio::error_code& ec)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
@ -255,19 +288,11 @@ inline int sendto(socket_type s, const buf* bufs, size_t count, int flags,
|
|||||||
return -1;
|
return -1;
|
||||||
return bytes_transferred;
|
return bytes_transferred;
|
||||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
msghdr msg;
|
msghdr msg = msghdr();
|
||||||
#if defined(__MACH__) && defined(__APPLE__) \
|
init_msghdr_msg_name(msg.msg_name, addr);
|
||||||
&& (MAC_OS_X_VERSION_MAX_ALLOWED < 1040)
|
|
||||||
msg.msg_name = reinterpret_cast<char*>(const_cast<socket_addr_type*>(addr));
|
|
||||||
#else
|
|
||||||
msg.msg_name = const_cast<socket_addr_type*>(addr);
|
|
||||||
#endif
|
|
||||||
msg.msg_namelen = addrlen;
|
msg.msg_namelen = addrlen;
|
||||||
msg.msg_iov = const_cast<buf*>(bufs);
|
msg.msg_iov = const_cast<buf*>(bufs);
|
||||||
msg.msg_iovlen = count;
|
msg.msg_iovlen = count;
|
||||||
msg.msg_control = 0;
|
|
||||||
msg.msg_controllen = 0;
|
|
||||||
msg.msg_flags = 0;
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
flags |= MSG_NOSIGNAL;
|
flags |= MSG_NOSIGNAL;
|
||||||
#endif // defined(__linux__)
|
#endif // defined(__linux__)
|
||||||
@ -316,8 +341,17 @@ inline socket_type socket(int af, int type, int protocol,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename SockLenType>
|
||||||
|
inline int call_setsockopt(SockLenType msghdr::*,
|
||||||
|
socket_type s, int level, int optname,
|
||||||
|
const void* optval, std::size_t optlen)
|
||||||
|
{
|
||||||
|
return ::setsockopt(s, level, optname,
|
||||||
|
(const char*)optval, (SockLenType)optlen);
|
||||||
|
}
|
||||||
|
|
||||||
inline int setsockopt(socket_type s, int level, int optname,
|
inline int setsockopt(socket_type s, int level, int optname,
|
||||||
const void* optval, size_t optlen, asio::error_code& ec)
|
const void* optval, std::size_t optlen, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
if (level == custom_socket_option_level && optname == always_fail_option)
|
if (level == custom_socket_option_level && optname == always_fail_option)
|
||||||
{
|
{
|
||||||
@ -342,15 +376,22 @@ inline int setsockopt(socket_type s, int level, int optname,
|
|||||||
}
|
}
|
||||||
ec = asio::error::fault;
|
ec = asio::error::fault;
|
||||||
return -1;
|
return -1;
|
||||||
#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#else // defined(__BORLANDC__)
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
return error_wrapper(::setsockopt(s, level, optname,
|
return error_wrapper(call_setsockopt(&msghdr::msg_namelen,
|
||||||
reinterpret_cast<const char*>(optval), static_cast<int>(optlen)), ec);
|
s, level, optname, optval, optlen), ec);
|
||||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#endif // defined(__BORLANDC__)
|
||||||
clear_error(ec);
|
}
|
||||||
return error_wrapper(::setsockopt(s, level, optname, optval,
|
|
||||||
static_cast<socklen_t>(optlen)), ec);
|
template <typename SockLenType>
|
||||||
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
inline int call_getsockopt(SockLenType msghdr::*,
|
||||||
|
socket_type s, int level, int optname,
|
||||||
|
void* optval, std::size_t* optlen)
|
||||||
|
{
|
||||||
|
SockLenType tmp_optlen = (SockLenType)*optlen;
|
||||||
|
int result = ::getsockopt(s, level, optname, (char*)optval, &tmp_optlen);
|
||||||
|
*optlen = (std::size_t)tmp_optlen;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int getsockopt(socket_type s, int level, int optname, void* optval,
|
inline int getsockopt(socket_type s, int level, int optname, void* optval,
|
||||||
@ -394,10 +435,8 @@ inline int getsockopt(socket_type s, int level, int optname, void* optval,
|
|||||||
return -1;
|
return -1;
|
||||||
#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
int tmp_optlen = static_cast<int>(*optlen);
|
int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,
|
||||||
int result = error_wrapper(::getsockopt(s, level, optname,
|
s, level, optname, optval, optlen), ec);
|
||||||
reinterpret_cast<char*>(optval), &tmp_optlen), ec);
|
|
||||||
*optlen = static_cast<size_t>(tmp_optlen);
|
|
||||||
if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY
|
if (result != 0 && level == IPPROTO_IPV6 && optname == IPV6_V6ONLY
|
||||||
&& ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD))
|
&& ec.value() == WSAENOPROTOOPT && *optlen == sizeof(DWORD))
|
||||||
{
|
{
|
||||||
@ -412,10 +451,8 @@ inline int getsockopt(socket_type s, int level, int optname, void* optval,
|
|||||||
return result;
|
return result;
|
||||||
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#else // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
socklen_t tmp_optlen = static_cast<socklen_t>(*optlen);
|
int result = error_wrapper(call_getsockopt(&msghdr::msg_namelen,
|
||||||
int result = error_wrapper(::getsockopt(s, level, optname,
|
s, level, optname, optval, optlen), ec);
|
||||||
optval, &tmp_optlen), ec);
|
|
||||||
*optlen = static_cast<size_t>(tmp_optlen);
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
if (result == 0 && level == SOL_SOCKET && *optlen == sizeof(int)
|
if (result == 0 && level == SOL_SOCKET && *optlen == sizeof(int)
|
||||||
&& (optname == SO_SNDBUF || optname == SO_RCVBUF))
|
&& (optname == SO_SNDBUF || optname == SO_RCVBUF))
|
||||||
@ -432,18 +469,40 @@ inline int getsockopt(socket_type s, int level, int optname, void* optval,
|
|||||||
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#endif // defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename SockLenType>
|
||||||
|
inline int call_getpeername(SockLenType msghdr::*,
|
||||||
|
socket_type s, socket_addr_type* addr, std::size_t* addrlen)
|
||||||
|
{
|
||||||
|
SockLenType tmp_addrlen = (SockLenType)*addrlen;
|
||||||
|
int result = ::getpeername(s, addr, &tmp_addrlen);
|
||||||
|
*addrlen = (std::size_t)tmp_addrlen;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
inline int getpeername(socket_type s, socket_addr_type* addr,
|
inline int getpeername(socket_type s, socket_addr_type* addr,
|
||||||
socket_addr_len_type* addrlen, asio::error_code& ec)
|
std::size_t* addrlen, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
return error_wrapper(::getpeername(s, addr, addrlen), ec);
|
return error_wrapper(call_getpeername(
|
||||||
|
&msghdr::msg_namelen, s, addr, addrlen), ec);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename SockLenType>
|
||||||
|
inline int call_getsockname(SockLenType msghdr::*,
|
||||||
|
socket_type s, socket_addr_type* addr, std::size_t* addrlen)
|
||||||
|
{
|
||||||
|
SockLenType tmp_addrlen = (SockLenType)*addrlen;
|
||||||
|
int result = ::getsockname(s, addr, &tmp_addrlen);
|
||||||
|
*addrlen = (std::size_t)tmp_addrlen;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int getsockname(socket_type s, socket_addr_type* addr,
|
inline int getsockname(socket_type s, socket_addr_type* addr,
|
||||||
socket_addr_len_type* addrlen, asio::error_code& ec)
|
std::size_t* addrlen, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
clear_error(ec);
|
clear_error(ec);
|
||||||
return error_wrapper(::getsockname(s, addr, addrlen), ec);
|
return error_wrapper(call_getsockname(
|
||||||
|
&msghdr::msg_namelen, s, addr, addrlen), ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int ioctl(socket_type s, long cmd, ioctl_arg_type* arg,
|
inline int ioctl(socket_type s, long cmd, ioctl_arg_type* arg,
|
||||||
@ -1373,7 +1432,7 @@ inline int getaddrinfo_emulation(const char* host, const char* service,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline asio::error_code getnameinfo_emulation(
|
inline asio::error_code getnameinfo_emulation(
|
||||||
const socket_addr_type* sa, socket_addr_len_type salen, char* host,
|
const socket_addr_type* sa, std::size_t salen, char* host,
|
||||||
std::size_t hostlen, char* serv, std::size_t servlen, int flags,
|
std::size_t hostlen, char* serv, std::size_t servlen, int flags,
|
||||||
asio::error_code& ec)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
@ -1595,7 +1654,7 @@ inline void freeaddrinfo(addrinfo_type* ai)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline asio::error_code getnameinfo(const socket_addr_type* addr,
|
inline asio::error_code getnameinfo(const socket_addr_type* addr,
|
||||||
socket_addr_len_type addrlen, char* host, std::size_t hostlen,
|
std::size_t addrlen, char* host, std::size_t hostlen,
|
||||||
char* serv, std::size_t servlen, int flags, asio::error_code& ec)
|
char* serv, std::size_t servlen, int flags, asio::error_code& ec)
|
||||||
{
|
{
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
@ -1608,7 +1667,7 @@ inline asio::error_code getnameinfo(const socket_addr_type* addr,
|
|||||||
# else
|
# else
|
||||||
// Building for Windows 2000 or earlier.
|
// Building for Windows 2000 or earlier.
|
||||||
typedef int (WSAAPI *gni_t)(const socket_addr_type*,
|
typedef int (WSAAPI *gni_t)(const socket_addr_type*,
|
||||||
socket_addr_len_type, char*, std::size_t, char*, std::size_t, int);
|
int, char*, std::size_t, char*, std::size_t, int);
|
||||||
if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
|
if (HMODULE winsock_module = ::GetModuleHandleA("ws2_32"))
|
||||||
{
|
{
|
||||||
if (gni_t gni = (gni_t)::GetProcAddress(winsock_module, "getnameinfo"))
|
if (gni_t gni = (gni_t)::GetProcAddress(winsock_module, "getnameinfo"))
|
||||||
@ -1662,6 +1721,8 @@ inline u_short_type host_to_network_short(u_short_type value)
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
|
|
||||||
|
#undef ASIO_SOCKET_CALL
|
||||||
|
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
#endif // ASIO_DETAIL_SOCKET_OPS_HPP
|
#endif // ASIO_DETAIL_SOCKET_OPS_HPP
|
||||||
|
@ -52,7 +52,7 @@ public:
|
|||||||
|
|
||||||
using namespace std; // For memset.
|
using namespace std; // For memset.
|
||||||
sockaddr_in4_type addr;
|
sockaddr_in4_type addr;
|
||||||
socket_addr_len_type addr_len = sizeof(addr);
|
std::size_t addr_len = sizeof(addr);
|
||||||
memset(&addr, 0, sizeof(addr));
|
memset(&addr, 0, sizeof(addr));
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
addr.sin_addr.s_addr = inet_addr("127.0.0.1");
|
||||||
|
@ -116,7 +116,6 @@ const int socket_error_retval = SOCKET_ERROR;
|
|||||||
const int max_addr_v4_str_len = 256;
|
const int max_addr_v4_str_len = 256;
|
||||||
const int max_addr_v6_str_len = 256;
|
const int max_addr_v6_str_len = 256;
|
||||||
typedef sockaddr socket_addr_type;
|
typedef sockaddr socket_addr_type;
|
||||||
typedef int socket_addr_len_type;
|
|
||||||
typedef in_addr in4_addr_type;
|
typedef in_addr in4_addr_type;
|
||||||
typedef ip_mreq in4_mreq_type;
|
typedef ip_mreq in4_mreq_type;
|
||||||
typedef sockaddr_in sockaddr_in4_type;
|
typedef sockaddr_in sockaddr_in4_type;
|
||||||
@ -154,7 +153,6 @@ const int socket_error_retval = -1;
|
|||||||
const int max_addr_v4_str_len = INET_ADDRSTRLEN;
|
const int max_addr_v4_str_len = INET_ADDRSTRLEN;
|
||||||
const int max_addr_v6_str_len = INET6_ADDRSTRLEN + 1 + IF_NAMESIZE;
|
const int max_addr_v6_str_len = INET6_ADDRSTRLEN + 1 + IF_NAMESIZE;
|
||||||
typedef sockaddr socket_addr_type;
|
typedef sockaddr socket_addr_type;
|
||||||
typedef socklen_t socket_addr_len_type;
|
|
||||||
typedef in_addr in4_addr_type;
|
typedef in_addr in4_addr_type;
|
||||||
typedef ip_mreq in4_mreq_type;
|
typedef ip_mreq in4_mreq_type;
|
||||||
typedef sockaddr_in sockaddr_in4_type;
|
typedef sockaddr_in sockaddr_in4_type;
|
||||||
|
@ -135,9 +135,9 @@ public:
|
|||||||
handler_base* last_waiter_;
|
handler_base* last_waiter_;
|
||||||
|
|
||||||
// Storage for posted handlers.
|
// Storage for posted handlers.
|
||||||
typedef boost::aligned_storage<64> handler_storage_type;
|
typedef boost::aligned_storage<128> handler_storage_type;
|
||||||
#if defined(__BORLANDC__)
|
#if defined(__BORLANDC__)
|
||||||
boost::aligned_storage<64> handler_storage_;
|
boost::aligned_storage<128> handler_storage_;
|
||||||
#else
|
#else
|
||||||
handler_storage_type handler_storage_;
|
handler_storage_type handler_storage_;
|
||||||
#endif
|
#endif
|
||||||
@ -235,7 +235,7 @@ public:
|
|||||||
void* do_handler_allocate(std::size_t size)
|
void* do_handler_allocate(std::size_t size)
|
||||||
{
|
{
|
||||||
#if defined(__BORLANDC__)
|
#if defined(__BORLANDC__)
|
||||||
BOOST_ASSERT(size <= boost::aligned_storage<64>::size);
|
BOOST_ASSERT(size <= boost::aligned_storage<128>::size);
|
||||||
#else
|
#else
|
||||||
BOOST_ASSERT(size <= strand_impl::handler_storage_type::size);
|
BOOST_ASSERT(size <= strand_impl::handler_storage_type::size);
|
||||||
#endif
|
#endif
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include "asio/detail/event.hpp"
|
#include "asio/detail/event.hpp"
|
||||||
#include "asio/detail/handler_alloc_helpers.hpp"
|
#include "asio/detail/handler_alloc_helpers.hpp"
|
||||||
#include "asio/detail/handler_invoke_helpers.hpp"
|
#include "asio/detail/handler_invoke_helpers.hpp"
|
||||||
|
#include "asio/detail/handler_queue.hpp"
|
||||||
#include "asio/detail/mutex.hpp"
|
#include "asio/detail/mutex.hpp"
|
||||||
#include "asio/detail/service_base.hpp"
|
#include "asio/detail/service_base.hpp"
|
||||||
#include "asio/detail/task_io_service_fwd.hpp"
|
#include "asio/detail/task_io_service_fwd.hpp"
|
||||||
@ -42,12 +43,11 @@ public:
|
|||||||
task_(use_service<Task>(io_service)),
|
task_(use_service<Task>(io_service)),
|
||||||
task_interrupted_(true),
|
task_interrupted_(true),
|
||||||
outstanding_work_(0),
|
outstanding_work_(0),
|
||||||
handler_queue_(&task_handler_),
|
|
||||||
handler_queue_end_(&task_handler_),
|
|
||||||
stopped_(false),
|
stopped_(false),
|
||||||
shutdown_(false),
|
shutdown_(false),
|
||||||
first_idle_thread_(0)
|
first_idle_thread_(0)
|
||||||
{
|
{
|
||||||
|
handler_queue_.push(&task_handler_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void init(size_t /*concurrency_hint*/)
|
void init(size_t /*concurrency_hint*/)
|
||||||
@ -62,17 +62,16 @@ public:
|
|||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
// Destroy handler objects.
|
// Destroy handler objects.
|
||||||
while (handler_queue_)
|
while (!handler_queue_.empty())
|
||||||
{
|
{
|
||||||
handler_base* h = handler_queue_;
|
handler_queue::handler* h = handler_queue_.front();
|
||||||
handler_queue_ = h->next_;
|
handler_queue_.pop();
|
||||||
if (h != &task_handler_)
|
if (h != &task_handler_)
|
||||||
h->destroy();
|
h->destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset handler queue to initial state.
|
// Reset handler queue to initial state.
|
||||||
handler_queue_ = &task_handler_;
|
handler_queue_.push(&task_handler_);
|
||||||
handler_queue_end_ = &task_handler_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run the event loop until interrupted or no more work.
|
// Run the event loop until interrupted or no more work.
|
||||||
@ -173,10 +172,7 @@ public:
|
|||||||
void post(Handler handler)
|
void post(Handler handler)
|
||||||
{
|
{
|
||||||
// Allocate and construct an operation to wrap the handler.
|
// Allocate and construct an operation to wrap the handler.
|
||||||
typedef handler_wrapper<Handler> value_type;
|
handler_queue::scoped_ptr ptr(handler_queue::wrap(handler));
|
||||||
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
|
|
||||||
raw_handler_ptr<alloc_traits> raw_ptr(handler);
|
|
||||||
handler_ptr<alloc_traits> ptr(raw_ptr, handler);
|
|
||||||
|
|
||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
|
|
||||||
@ -185,15 +181,7 @@ public:
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Add the handler to the end of the queue.
|
// Add the handler to the end of the queue.
|
||||||
if (handler_queue_end_)
|
handler_queue_.push(ptr.get());
|
||||||
{
|
|
||||||
handler_queue_end_->next_ = ptr.get();
|
|
||||||
handler_queue_end_ = ptr.get();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
handler_queue_ = handler_queue_end_ = ptr.get();
|
|
||||||
}
|
|
||||||
ptr.release();
|
ptr.release();
|
||||||
|
|
||||||
// An undelivered handler is treated as unfinished work.
|
// An undelivered handler is treated as unfinished work.
|
||||||
@ -227,18 +215,15 @@ private:
|
|||||||
bool task_has_run = false;
|
bool task_has_run = false;
|
||||||
while (!stopped_)
|
while (!stopped_)
|
||||||
{
|
{
|
||||||
if (handler_queue_)
|
if (!handler_queue_.empty())
|
||||||
{
|
{
|
||||||
// Prepare to execute first handler from queue.
|
// Prepare to execute first handler from queue.
|
||||||
handler_base* h = handler_queue_;
|
handler_queue::handler* h = handler_queue_.front();
|
||||||
handler_queue_ = h->next_;
|
handler_queue_.pop();
|
||||||
if (handler_queue_ == 0)
|
|
||||||
handler_queue_end_ = 0;
|
|
||||||
h->next_ = 0;
|
|
||||||
|
|
||||||
if (h == &task_handler_)
|
if (h == &task_handler_)
|
||||||
{
|
{
|
||||||
bool more_handlers = (handler_queue_ != 0);
|
bool more_handlers = (!handler_queue_.empty());
|
||||||
task_interrupted_ = more_handlers || polling;
|
task_interrupted_ = more_handlers || polling;
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
|
|
||||||
@ -263,7 +248,7 @@ private:
|
|||||||
handler_cleanup c(lock, *this);
|
handler_cleanup c(lock, *this);
|
||||||
|
|
||||||
// Invoke the handler. May throw an exception.
|
// Invoke the handler. May throw an exception.
|
||||||
h->call(); // call() deletes the handler object
|
h->invoke(); // invoke() deletes the handler object
|
||||||
|
|
||||||
ec = asio::error_code();
|
ec = asio::error_code();
|
||||||
return 1;
|
return 1;
|
||||||
@ -330,93 +315,6 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class task_cleanup;
|
|
||||||
friend class task_cleanup;
|
|
||||||
|
|
||||||
// The base class for all handler wrappers. A function pointer is used
|
|
||||||
// instead of virtual functions to avoid the associated overhead.
|
|
||||||
class handler_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef void (*call_func_type)(handler_base*);
|
|
||||||
typedef void (*destroy_func_type)(handler_base*);
|
|
||||||
|
|
||||||
handler_base(call_func_type call_func, destroy_func_type destroy_func)
|
|
||||||
: next_(0),
|
|
||||||
call_func_(call_func),
|
|
||||||
destroy_func_(destroy_func)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void call()
|
|
||||||
{
|
|
||||||
call_func_(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void destroy()
|
|
||||||
{
|
|
||||||
destroy_func_(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Prevent deletion through this type.
|
|
||||||
~handler_base()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
friend class task_io_service<Task>;
|
|
||||||
friend class task_cleanup;
|
|
||||||
handler_base* next_;
|
|
||||||
call_func_type call_func_;
|
|
||||||
destroy_func_type destroy_func_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Template wrapper for handlers.
|
|
||||||
template <typename Handler>
|
|
||||||
class handler_wrapper
|
|
||||||
: public handler_base
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
handler_wrapper(Handler handler)
|
|
||||||
: handler_base(&handler_wrapper<Handler>::do_call,
|
|
||||||
&handler_wrapper<Handler>::do_destroy),
|
|
||||||
handler_(handler)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void do_call(handler_base* base)
|
|
||||||
{
|
|
||||||
// Take ownership of the handler object.
|
|
||||||
typedef handler_wrapper<Handler> this_type;
|
|
||||||
this_type* h(static_cast<this_type*>(base));
|
|
||||||
typedef handler_alloc_traits<Handler, this_type> alloc_traits;
|
|
||||||
handler_ptr<alloc_traits> ptr(h->handler_, h);
|
|
||||||
|
|
||||||
// Make a copy of the handler so that the memory can be deallocated before
|
|
||||||
// the upcall is made.
|
|
||||||
Handler handler(h->handler_);
|
|
||||||
|
|
||||||
// Free the memory associated with the handler.
|
|
||||||
ptr.reset();
|
|
||||||
|
|
||||||
// Make the upcall.
|
|
||||||
asio_handler_invoke_helpers::invoke(handler, &handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void do_destroy(handler_base* base)
|
|
||||||
{
|
|
||||||
// Take ownership of the handler object.
|
|
||||||
typedef handler_wrapper<Handler> this_type;
|
|
||||||
this_type* h(static_cast<this_type*>(base));
|
|
||||||
typedef handler_alloc_traits<Handler, this_type> alloc_traits;
|
|
||||||
handler_ptr<alloc_traits> ptr(h->handler_, h);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Handler handler_;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Helper class to perform task-related operations on block exit.
|
// Helper class to perform task-related operations on block exit.
|
||||||
class task_cleanup
|
class task_cleanup
|
||||||
{
|
{
|
||||||
@ -433,20 +331,7 @@ private:
|
|||||||
// Reinsert the task at the end of the handler queue.
|
// Reinsert the task at the end of the handler queue.
|
||||||
lock_.lock();
|
lock_.lock();
|
||||||
task_io_service_.task_interrupted_ = true;
|
task_io_service_.task_interrupted_ = true;
|
||||||
task_io_service_.task_handler_.next_ = 0;
|
task_io_service_.handler_queue_.push(&task_io_service_.task_handler_);
|
||||||
if (task_io_service_.handler_queue_end_)
|
|
||||||
{
|
|
||||||
task_io_service_.handler_queue_end_->next_
|
|
||||||
= &task_io_service_.task_handler_;
|
|
||||||
task_io_service_.handler_queue_end_
|
|
||||||
= &task_io_service_.task_handler_;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
task_io_service_.handler_queue_
|
|
||||||
= task_io_service_.handler_queue_end_
|
|
||||||
= &task_io_service_.task_handler_;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -487,11 +372,11 @@ private:
|
|||||||
|
|
||||||
// Handler object to represent the position of the task in the queue.
|
// Handler object to represent the position of the task in the queue.
|
||||||
class task_handler
|
class task_handler
|
||||||
: public handler_base
|
: public handler_queue::handler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
task_handler()
|
task_handler()
|
||||||
: handler_base(0, 0)
|
: handler_queue::handler(0, 0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
} task_handler_;
|
} task_handler_;
|
||||||
@ -502,11 +387,8 @@ private:
|
|||||||
// The count of unfinished work.
|
// The count of unfinished work.
|
||||||
int outstanding_work_;
|
int outstanding_work_;
|
||||||
|
|
||||||
// The start of a linked list of handlers that are ready to be delivered.
|
// The queue of handlers that are ready to be delivered.
|
||||||
handler_base* handler_queue_;
|
handler_queue handler_queue_;
|
||||||
|
|
||||||
// The end of a linked list of handlers that are ready to be delivered.
|
|
||||||
handler_base* handler_queue_end_;
|
|
||||||
|
|
||||||
// Flag to indicate that the dispatcher has been stopped.
|
// Flag to indicate that the dispatcher has been stopped.
|
||||||
bool stopped_;
|
bool stopped_;
|
||||||
|
@ -561,7 +561,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
endpoint_type endpoint;
|
endpoint_type endpoint;
|
||||||
socket_addr_len_type addr_len = endpoint.capacity();
|
std::size_t addr_len = endpoint.capacity();
|
||||||
if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec))
|
if (socket_ops::getsockname(impl.socket_, endpoint.data(), &addr_len, ec))
|
||||||
return endpoint_type();
|
return endpoint_type();
|
||||||
endpoint.resize(addr_len);
|
endpoint.resize(addr_len);
|
||||||
@ -600,7 +600,7 @@ public:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
endpoint_type endpoint;
|
endpoint_type endpoint;
|
||||||
socket_addr_len_type addr_len = endpoint.capacity();
|
std::size_t addr_len = endpoint.capacity();
|
||||||
if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec))
|
if (socket_ops::getpeername(impl.socket_, endpoint.data(), &addr_len, ec))
|
||||||
return endpoint_type();
|
return endpoint_type();
|
||||||
endpoint.resize(addr_len);
|
endpoint.resize(addr_len);
|
||||||
@ -1261,7 +1261,7 @@ public:
|
|||||||
// Receive some data.
|
// Receive some data.
|
||||||
DWORD bytes_transferred = 0;
|
DWORD bytes_transferred = 0;
|
||||||
DWORD recv_flags = flags;
|
DWORD recv_flags = flags;
|
||||||
int endpoint_size = sender_endpoint.capacity();
|
int endpoint_size = static_cast<int>(sender_endpoint.capacity());
|
||||||
int result = ::WSARecvFrom(impl.socket_, bufs, i, &bytes_transferred,
|
int result = ::WSARecvFrom(impl.socket_, bufs, i, &bytes_transferred,
|
||||||
&recv_flags, sender_endpoint.data(), &endpoint_size, 0, 0);
|
&recv_flags, sender_endpoint.data(), &endpoint_size, 0, 0);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
@ -1279,7 +1279,7 @@ public:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sender_endpoint.resize(endpoint_size);
|
sender_endpoint.resize(static_cast<std::size_t>(endpoint_size));
|
||||||
|
|
||||||
ec = asio::error_code();
|
ec = asio::error_code();
|
||||||
return bytes_transferred;
|
return bytes_transferred;
|
||||||
@ -1299,7 +1299,7 @@ public:
|
|||||||
&receive_from_operation<
|
&receive_from_operation<
|
||||||
MutableBufferSequence, Handler>::destroy_impl),
|
MutableBufferSequence, Handler>::destroy_impl),
|
||||||
endpoint_(endpoint),
|
endpoint_(endpoint),
|
||||||
endpoint_size_(endpoint.capacity()),
|
endpoint_size_(static_cast<int>(endpoint.capacity())),
|
||||||
work_(io_service),
|
work_(io_service),
|
||||||
buffers_(buffers),
|
buffers_(buffers),
|
||||||
handler_(handler)
|
handler_(handler)
|
||||||
@ -1463,7 +1463,7 @@ public:
|
|||||||
{
|
{
|
||||||
asio::error_code ec;
|
asio::error_code ec;
|
||||||
socket_holder new_socket;
|
socket_holder new_socket;
|
||||||
socket_addr_len_type addr_len = 0;
|
std::size_t addr_len = 0;
|
||||||
if (peer_endpoint)
|
if (peer_endpoint)
|
||||||
{
|
{
|
||||||
addr_len = peer_endpoint->capacity();
|
addr_len = peer_endpoint->capacity();
|
||||||
@ -1618,7 +1618,8 @@ public:
|
|||||||
GetAcceptExSockaddrs(handler_op->output_buffer(), 0,
|
GetAcceptExSockaddrs(handler_op->output_buffer(), 0,
|
||||||
handler_op->address_length(), handler_op->address_length(),
|
handler_op->address_length(), handler_op->address_length(),
|
||||||
&local_addr, &local_addr_length, &remote_addr, &remote_addr_length);
|
&local_addr, &local_addr_length, &remote_addr, &remote_addr_length);
|
||||||
if (remote_addr_length > peer_endpoint.capacity())
|
if (static_cast<std::size_t>(remote_addr_length)
|
||||||
|
> peer_endpoint.capacity())
|
||||||
{
|
{
|
||||||
last_error = WSAEINVAL;
|
last_error = WSAEINVAL;
|
||||||
}
|
}
|
||||||
@ -1626,7 +1627,7 @@ public:
|
|||||||
{
|
{
|
||||||
using namespace std; // For memcpy.
|
using namespace std; // For memcpy.
|
||||||
memcpy(peer_endpoint.data(), remote_addr, remote_addr_length);
|
memcpy(peer_endpoint.data(), remote_addr, remote_addr_length);
|
||||||
peer_endpoint.resize(remote_addr_length);
|
peer_endpoint.resize(static_cast<std::size_t>(remote_addr_length));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +54,9 @@ namespace error
|
|||||||
};
|
};
|
||||||
} // namespace error
|
} // namespace error
|
||||||
|
|
||||||
|
/// Bring error category type into the asio namespace.
|
||||||
|
typedef asio::error::error_category error_category;
|
||||||
|
|
||||||
/// Class to represent an error code value.
|
/// Class to represent an error code value.
|
||||||
class error_code
|
class error_code
|
||||||
{
|
{
|
||||||
@ -69,7 +72,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Construct with specific error code and category.
|
/// Construct with specific error code and category.
|
||||||
error_code(value_type v, error::error_category c)
|
error_code(value_type v, error_category c)
|
||||||
: value_(v),
|
: value_(v),
|
||||||
category_(c)
|
category_(c)
|
||||||
{
|
{
|
||||||
@ -89,7 +92,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the error category.
|
/// Get the error category.
|
||||||
error::error_category category() const
|
error_category category() const
|
||||||
{
|
{
|
||||||
return category_;
|
return category_;
|
||||||
}
|
}
|
||||||
@ -135,7 +138,7 @@ private:
|
|||||||
value_type value_;
|
value_type value_;
|
||||||
|
|
||||||
// The category associated with the error code.
|
// The category associated with the error code.
|
||||||
error::error_category category_;
|
error_category category_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
|
@ -39,6 +39,11 @@
|
|||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
|
|
||||||
|
class io_service;
|
||||||
|
template <typename Service> Service& use_service(io_service& ios);
|
||||||
|
template <typename Service> void add_service(io_service& ios, Service* svc);
|
||||||
|
template <typename Service> bool has_service(io_service& ios);
|
||||||
|
|
||||||
/// Provides core I/O functionality.
|
/// Provides core I/O functionality.
|
||||||
/**
|
/**
|
||||||
* The io_service class provides the core I/O functionality for users of the
|
* The io_service class provides the core I/O functionality for users of the
|
||||||
|
@ -268,7 +268,12 @@ std::basic_ostream<Elem, Traits>& operator<<(
|
|||||||
asio::error_code ec;
|
asio::error_code ec;
|
||||||
std::string s = addr.to_string(ec);
|
std::string s = addr.to_string(ec);
|
||||||
if (ec)
|
if (ec)
|
||||||
os.setstate(std::ios_base::failbit);
|
{
|
||||||
|
if (os.exceptions() & std::ios::failbit)
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
else
|
||||||
|
os.setstate(std::ios_base::failbit);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
for (std::string::iterator i = s.begin(); i != s.end(); ++i)
|
for (std::string::iterator i = s.begin(); i != s.end(); ++i)
|
||||||
os << os.widen(*i);
|
os << os.widen(*i);
|
||||||
|
@ -386,7 +386,12 @@ std::basic_ostream<Elem, Traits>& operator<<(
|
|||||||
asio::error_code ec;
|
asio::error_code ec;
|
||||||
std::string s = addr.to_string(ec);
|
std::string s = addr.to_string(ec);
|
||||||
if (ec)
|
if (ec)
|
||||||
os.setstate(std::ios_base::failbit);
|
{
|
||||||
|
if (os.exceptions() & std::ios::failbit)
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
else
|
||||||
|
os.setstate(std::ios_base::failbit);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
for (std::string::iterator i = s.begin(); i != s.end(); ++i)
|
for (std::string::iterator i = s.begin(); i != s.end(); ++i)
|
||||||
os << os.widen(*i);
|
os << os.widen(*i);
|
||||||
|
@ -61,14 +61,6 @@ public:
|
|||||||
typedef asio::detail::socket_addr_type data_type;
|
typedef asio::detail::socket_addr_type data_type;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// The type for the size of the endpoint structure. This type is dependent on
|
|
||||||
/// the underlying implementation of the socket layer.
|
|
||||||
#if defined(GENERATING_DOCUMENTATION)
|
|
||||||
typedef implementation_defined size_type;
|
|
||||||
#else
|
|
||||||
typedef asio::detail::socket_addr_len_type size_type;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// Default constructor.
|
/// Default constructor.
|
||||||
basic_endpoint()
|
basic_endpoint()
|
||||||
: data_()
|
: data_()
|
||||||
@ -190,7 +182,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the underlying size of the endpoint in the native type.
|
/// Get the underlying size of the endpoint in the native type.
|
||||||
size_type size() const
|
std::size_t size() const
|
||||||
{
|
{
|
||||||
if (is_v4(data_))
|
if (is_v4(data_))
|
||||||
return sizeof(asio::detail::sockaddr_in4_type);
|
return sizeof(asio::detail::sockaddr_in4_type);
|
||||||
@ -199,9 +191,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Set the underlying size of the endpoint in the native type.
|
/// Set the underlying size of the endpoint in the native type.
|
||||||
void resize(size_type size)
|
void resize(std::size_t size)
|
||||||
{
|
{
|
||||||
if (size > size_type(sizeof(data_)))
|
if (size > sizeof(data_))
|
||||||
{
|
{
|
||||||
asio::system_error e(asio::error::invalid_argument);
|
asio::system_error e(asio::error::invalid_argument);
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
@ -209,7 +201,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Get the capacity of the endpoint in the native type.
|
/// Get the capacity of the endpoint in the native type.
|
||||||
size_type capacity() const
|
std::size_t capacity() const
|
||||||
{
|
{
|
||||||
return sizeof(data_);
|
return sizeof(data_);
|
||||||
}
|
}
|
||||||
@ -349,11 +341,23 @@ std::ostream& operator<<(std::ostream& os,
|
|||||||
const basic_endpoint<InternetProtocol>& endpoint)
|
const basic_endpoint<InternetProtocol>& endpoint)
|
||||||
{
|
{
|
||||||
const address& addr = endpoint.address();
|
const address& addr = endpoint.address();
|
||||||
if (addr.is_v4())
|
asio::error_code ec;
|
||||||
os << addr.to_string();
|
std::string a = addr.to_string(ec);
|
||||||
|
if (ec)
|
||||||
|
{
|
||||||
|
if (os.exceptions() & std::ios::failbit)
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
else
|
||||||
|
os.setstate(std::ios_base::failbit);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
os << '[' << addr.to_string() << ']';
|
{
|
||||||
os << ':' << endpoint.port();
|
if (addr.is_v4())
|
||||||
|
os << a;
|
||||||
|
else
|
||||||
|
os << '[' << a << ']';
|
||||||
|
os << ':' << endpoint.port();
|
||||||
|
}
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||||
@ -363,11 +367,23 @@ std::basic_ostream<Elem, Traits>& operator<<(
|
|||||||
const basic_endpoint<InternetProtocol>& endpoint)
|
const basic_endpoint<InternetProtocol>& endpoint)
|
||||||
{
|
{
|
||||||
const address& addr = endpoint.address();
|
const address& addr = endpoint.address();
|
||||||
if (addr.is_v4())
|
asio::error_code ec;
|
||||||
os << addr.to_string();
|
std::string a = addr.to_string(ec);
|
||||||
|
if (ec)
|
||||||
|
{
|
||||||
|
if (os.exceptions() & std::ios::failbit)
|
||||||
|
asio::detail::throw_error(ec);
|
||||||
|
else
|
||||||
|
os.setstate(std::ios_base::failbit);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
os << '[' << addr.to_string() << ']';
|
{
|
||||||
os << ':' << endpoint.port();
|
if (addr.is_v4())
|
||||||
|
os << a;
|
||||||
|
else
|
||||||
|
os << '[' << a << ']';
|
||||||
|
os << ':' << endpoint.port();
|
||||||
|
}
|
||||||
return os;
|
return os;
|
||||||
}
|
}
|
||||||
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
|
||||||
|
@ -80,9 +80,7 @@ public:
|
|||||||
{
|
{
|
||||||
using namespace std; // For memcpy.
|
using namespace std; // For memcpy.
|
||||||
typename InternetProtocol::endpoint endpoint;
|
typename InternetProtocol::endpoint endpoint;
|
||||||
endpoint.resize(
|
endpoint.resize(static_cast<std::size_t>(address_info->ai_addrlen));
|
||||||
static_cast<asio::detail::socket_addr_len_type>(
|
|
||||||
address_info->ai_addrlen));
|
|
||||||
memcpy(endpoint.data(), address_info->ai_addr,
|
memcpy(endpoint.data(), address_info->ai_addr,
|
||||||
address_info->ai_addrlen);
|
address_info->ai_addrlen);
|
||||||
iter.values_->push_back(
|
iter.values_->push_back(
|
||||||
|
@ -37,7 +37,7 @@ template <int IPv4_Level, int IPv4_Name, int IPv6_Level, int IPv6_Name>
|
|||||||
class boolean
|
class boolean
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
#if defined(__sun)
|
#if defined(__sun) || defined(_AIX)
|
||||||
typedef unsigned char value_type;
|
typedef unsigned char value_type;
|
||||||
#else
|
#else
|
||||||
typedef int value_type;
|
typedef int value_type;
|
||||||
|
@ -168,6 +168,10 @@ namespace libtorrent
|
|||||||
// thread started to run the main downloader loop
|
// thread started to run the main downloader loop
|
||||||
struct session_impl: boost::noncopyable
|
struct session_impl: boost::noncopyable
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// the size of each allocation that is chained in the send buffer
|
||||||
|
enum { send_buffer_size = 200 };
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
friend class ::libtorrent::peer_connection;
|
friend class ::libtorrent::peer_connection;
|
||||||
#endif
|
#endif
|
||||||
@ -329,6 +333,24 @@ namespace libtorrent
|
|||||||
{ return m_dht_proxy; }
|
{ return m_dht_proxy; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef TORRENT_STATS
|
||||||
|
void log_buffer_usage()
|
||||||
|
{
|
||||||
|
int send_buffer_capacity = 0;
|
||||||
|
int used_send_buffer = 0;
|
||||||
|
for (connection_map::const_iterator i = m_connections.begin()
|
||||||
|
, end(m_connections.end()); i != end; ++i)
|
||||||
|
{
|
||||||
|
send_buffer_capacity += i->second->send_buffer_capacity();
|
||||||
|
used_send_buffer += i->second->send_buffer_size();
|
||||||
|
}
|
||||||
|
assert(send_buffer_capacity >= used_send_buffer);
|
||||||
|
m_buffer_usage_logger << log_time() << " send_buffer_size: " << send_buffer_capacity << std::endl;
|
||||||
|
m_buffer_usage_logger << log_time() << " used_send_buffer: " << used_send_buffer << std::endl;
|
||||||
|
m_buffer_usage_logger << log_time() << " send_buffer_utilization: "
|
||||||
|
<< (used_send_buffer * 100.f / send_buffer_capacity) << std::endl;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
void start_lsd();
|
void start_lsd();
|
||||||
void start_natpmp();
|
void start_natpmp();
|
||||||
void start_upnp();
|
void start_upnp();
|
||||||
@ -339,11 +361,25 @@ namespace libtorrent
|
|||||||
|
|
||||||
// handles delayed alerts
|
// handles delayed alerts
|
||||||
alert_manager m_alerts;
|
alert_manager m_alerts;
|
||||||
|
|
||||||
|
std::pair<char*, int> allocate_buffer(int size);
|
||||||
|
void free_buffer(char* buf, int size);
|
||||||
|
void free_disk_buffer(char* buf);
|
||||||
|
|
||||||
// private:
|
// private:
|
||||||
|
|
||||||
void on_lsd_peer(tcp::endpoint peer, sha1_hash const& ih);
|
void on_lsd_peer(tcp::endpoint peer, sha1_hash const& ih);
|
||||||
|
|
||||||
|
// handles disk io requests asynchronously
|
||||||
|
// peers have pointers into the disk buffer
|
||||||
|
// pool, and must be destructed before this
|
||||||
|
// object.
|
||||||
|
disk_io_thread m_disk_thread;
|
||||||
|
|
||||||
|
// this pool is used to allocate and recycle send
|
||||||
|
// buffers from.
|
||||||
|
boost::pool<> m_send_buffers;
|
||||||
|
|
||||||
// this is where all active sockets are stored.
|
// this is where all active sockets are stored.
|
||||||
// the selector can sleep while there's no activity on
|
// the selector can sleep while there's no activity on
|
||||||
// them
|
// them
|
||||||
@ -358,9 +394,6 @@ namespace libtorrent
|
|||||||
// when they are destructed.
|
// when they are destructed.
|
||||||
file_pool m_files;
|
file_pool m_files;
|
||||||
|
|
||||||
// handles disk io requests asynchronously
|
|
||||||
disk_io_thread m_disk_thread;
|
|
||||||
|
|
||||||
// this is a list of half-open tcp connections
|
// this is a list of half-open tcp connections
|
||||||
// (only outgoing connections)
|
// (only outgoing connections)
|
||||||
// this has to be one of the last
|
// this has to be one of the last
|
||||||
@ -507,9 +540,9 @@ namespace libtorrent
|
|||||||
pe_settings m_pe_settings;
|
pe_settings m_pe_settings;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
boost::shared_ptr<natpmp> m_natpmp;
|
boost::intrusive_ptr<natpmp> m_natpmp;
|
||||||
boost::shared_ptr<upnp> m_upnp;
|
boost::intrusive_ptr<upnp> m_upnp;
|
||||||
boost::shared_ptr<lsd> m_lsd;
|
boost::intrusive_ptr<lsd> m_lsd;
|
||||||
|
|
||||||
// the timer used to fire the second_tick
|
// the timer used to fire the second_tick
|
||||||
deadline_timer m_timer;
|
deadline_timer m_timer;
|
||||||
@ -526,6 +559,10 @@ namespace libtorrent
|
|||||||
// logger used to write bandwidth usage statistics
|
// logger used to write bandwidth usage statistics
|
||||||
std::ofstream m_stats_logger;
|
std::ofstream m_stats_logger;
|
||||||
int m_second_counter;
|
int m_second_counter;
|
||||||
|
// used to log send buffer usage statistics
|
||||||
|
std::ofstream m_buffer_usage_logger;
|
||||||
|
// the number of send buffers that are allocated
|
||||||
|
int m_buffer_allocations;
|
||||||
#endif
|
#endif
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
boost::shared_ptr<logger> create_log(std::string const& name
|
boost::shared_ptr<logger> create_log(std::string const& name
|
||||||
|
@ -208,7 +208,7 @@ namespace libtorrent
|
|||||||
void write_cancel(peer_request const& r);
|
void write_cancel(peer_request const& r);
|
||||||
void write_bitfield(std::vector<bool> const& bitfield);
|
void write_bitfield(std::vector<bool> const& bitfield);
|
||||||
void write_have(int index);
|
void write_have(int index);
|
||||||
void write_piece(peer_request const& r, char const* buffer);
|
void write_piece(peer_request const& r, char* buffer);
|
||||||
void write_handshake();
|
void write_handshake();
|
||||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||||
void write_extensions();
|
void write_extensions();
|
||||||
@ -270,8 +270,17 @@ namespace libtorrent
|
|||||||
// these functions encrypt the send buffer if m_rc4_encrypted
|
// these functions encrypt the send buffer if m_rc4_encrypted
|
||||||
// is true, otherwise it passes the call to the
|
// is true, otherwise it passes the call to the
|
||||||
// peer_connection functions of the same names
|
// peer_connection functions of the same names
|
||||||
void send_buffer(char* begin, char* end);
|
void send_buffer(char* buf, int size);
|
||||||
buffer::interval allocate_send_buffer(int size);
|
buffer::interval allocate_send_buffer(int size);
|
||||||
|
template <class Destructor>
|
||||||
|
void append_send_buffer(char* buffer, int size, Destructor const& destructor)
|
||||||
|
{
|
||||||
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
|
if (m_rc4_encrypted)
|
||||||
|
m_RC4_handler->encrypt(buffer, size);
|
||||||
|
#endif
|
||||||
|
peer_connection::append_send_buffer(buffer, size, destructor);
|
||||||
|
}
|
||||||
void setup_send();
|
void setup_send();
|
||||||
|
|
||||||
// Returns offset at which bytestream (src, src + src_size)
|
// Returns offset at which bytestream (src, src + src_size)
|
||||||
|
192
libtorrent/include/libtorrent/chained_buffer.hpp
Normal file
192
libtorrent/include/libtorrent/chained_buffer.hpp
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2007, Arvid Norberg
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the author nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TORRENT_CHAINED_BUFFER_HPP_INCLUDED
|
||||||
|
#define TORRENT_CHAINED_BUFFER_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <boost/function.hpp>
|
||||||
|
#include <asio.hpp>
|
||||||
|
#include <list>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
namespace libtorrent
|
||||||
|
{
|
||||||
|
struct chained_buffer
|
||||||
|
{
|
||||||
|
chained_buffer(): m_bytes(0), m_capacity(0) {}
|
||||||
|
|
||||||
|
struct buffer_t
|
||||||
|
{
|
||||||
|
boost::function<void(char*)> free; // destructs the buffer
|
||||||
|
char* buf; // the first byte of the buffer
|
||||||
|
int size; // the total size of the buffer
|
||||||
|
|
||||||
|
char* start; // the first byte to send/receive in the buffer
|
||||||
|
int used_size; // this is the number of bytes to send/receive
|
||||||
|
};
|
||||||
|
|
||||||
|
bool empty() const { return m_bytes == 0; }
|
||||||
|
int size() const { return m_bytes; }
|
||||||
|
int capacity() const { return m_capacity; }
|
||||||
|
|
||||||
|
void pop_front(int bytes_to_pop)
|
||||||
|
{
|
||||||
|
assert(bytes_to_pop <= m_bytes);
|
||||||
|
while (bytes_to_pop > 0 && !m_vec.empty())
|
||||||
|
{
|
||||||
|
buffer_t& b = m_vec.front();
|
||||||
|
if (b.used_size > bytes_to_pop)
|
||||||
|
{
|
||||||
|
b.start += bytes_to_pop;
|
||||||
|
b.used_size -= bytes_to_pop;
|
||||||
|
m_bytes -= bytes_to_pop;
|
||||||
|
assert(m_bytes <= m_capacity);
|
||||||
|
assert(m_bytes >= 0);
|
||||||
|
assert(m_capacity >= 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
b.free(b.buf);
|
||||||
|
m_bytes -= b.used_size;
|
||||||
|
m_capacity -= b.size;
|
||||||
|
bytes_to_pop -= b.used_size;
|
||||||
|
assert(m_bytes >= 0);
|
||||||
|
assert(m_capacity >= 0);
|
||||||
|
assert(m_bytes <= m_capacity);
|
||||||
|
m_vec.pop_front();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class D>
|
||||||
|
void append_buffer(char* buffer, int size, int used_size, D const& destructor)
|
||||||
|
{
|
||||||
|
assert(size >= used_size);
|
||||||
|
buffer_t b;
|
||||||
|
b.buf = buffer;
|
||||||
|
b.size = size;
|
||||||
|
b.start = buffer;
|
||||||
|
b.used_size = used_size;
|
||||||
|
b.free = destructor;
|
||||||
|
m_vec.push_back(b);
|
||||||
|
|
||||||
|
m_bytes += used_size;
|
||||||
|
m_capacity += size;
|
||||||
|
assert(m_bytes <= m_capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns the number of bytes available at the
|
||||||
|
// end of the last chained buffer.
|
||||||
|
int space_in_last_buffer()
|
||||||
|
{
|
||||||
|
if (m_vec.empty()) return 0;
|
||||||
|
buffer_t& b = m_vec.back();
|
||||||
|
return b.size - b.used_size - (b.start - b.buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// tries to copy the given buffer to the end of the
|
||||||
|
// last chained buffer. If there's not enough room
|
||||||
|
// it returns false
|
||||||
|
bool append(char const* buf, int size)
|
||||||
|
{
|
||||||
|
char* insert = allocate_appendix(size);
|
||||||
|
if (insert == 0) return false;
|
||||||
|
std::memcpy(insert, buf, size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tries to allocate memory from the end
|
||||||
|
// of the last buffer. If there isn't
|
||||||
|
// enough room, returns 0
|
||||||
|
char* allocate_appendix(int size)
|
||||||
|
{
|
||||||
|
if (m_vec.empty()) return 0;
|
||||||
|
buffer_t& b = m_vec.back();
|
||||||
|
char* insert = b.start + b.used_size;
|
||||||
|
if (insert + size > b.buf + b.size) return 0;
|
||||||
|
b.used_size += size;
|
||||||
|
m_bytes += size;
|
||||||
|
assert(m_bytes <= m_capacity);
|
||||||
|
return insert;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::list<asio::const_buffer> const& build_iovec(int to_send)
|
||||||
|
{
|
||||||
|
m_tmp_vec.clear();
|
||||||
|
|
||||||
|
for (std::list<buffer_t>::iterator i = m_vec.begin()
|
||||||
|
, end(m_vec.end()); to_send > 0 && i != end; ++i)
|
||||||
|
{
|
||||||
|
if (i->used_size > to_send)
|
||||||
|
{
|
||||||
|
assert(to_send > 0);
|
||||||
|
m_tmp_vec.push_back(asio::const_buffer(i->start, to_send));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert(i->used_size > 0);
|
||||||
|
m_tmp_vec.push_back(asio::const_buffer(i->start, i->used_size));
|
||||||
|
to_send -= i->used_size;
|
||||||
|
}
|
||||||
|
return m_tmp_vec;
|
||||||
|
}
|
||||||
|
|
||||||
|
~chained_buffer()
|
||||||
|
{
|
||||||
|
for (std::list<buffer_t>::iterator i = m_vec.begin()
|
||||||
|
, end(m_vec.end()); i != end; ++i)
|
||||||
|
{
|
||||||
|
i->free(i->buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// this is the list of all the buffers we want to
|
||||||
|
// send
|
||||||
|
std::list<buffer_t> m_vec;
|
||||||
|
|
||||||
|
// this is the number of bytes in the send buf.
|
||||||
|
// this will always be equal to the sum of the
|
||||||
|
// size of all buffers in vec
|
||||||
|
int m_bytes;
|
||||||
|
|
||||||
|
// the total size of all buffers in the chain
|
||||||
|
// including unused space
|
||||||
|
int m_capacity;
|
||||||
|
|
||||||
|
// this is the vector of buffers used when
|
||||||
|
// invoking the async write call
|
||||||
|
std::list<asio::const_buffer> m_tmp_vec;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
@ -94,6 +94,11 @@ namespace libtorrent
|
|||||||
disk_io_thread(int block_size = 16 * 1024);
|
disk_io_thread(int block_size = 16 * 1024);
|
||||||
~disk_io_thread();
|
~disk_io_thread();
|
||||||
|
|
||||||
|
#ifdef TORRENT_STATS
|
||||||
|
int disk_allocations() const
|
||||||
|
{ return m_allocations; }
|
||||||
|
#endif
|
||||||
|
|
||||||
// aborts read operations
|
// aborts read operations
|
||||||
void stop(boost::intrusive_ptr<piece_manager> s);
|
void stop(boost::intrusive_ptr<piece_manager> s);
|
||||||
void add_job(disk_io_job const& j
|
void add_job(disk_io_job const& j
|
||||||
@ -110,6 +115,7 @@ namespace libtorrent
|
|||||||
void operator()();
|
void operator()();
|
||||||
|
|
||||||
char* allocate_buffer();
|
char* allocate_buffer();
|
||||||
|
void free_buffer(char* buf);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -129,6 +135,9 @@ namespace libtorrent
|
|||||||
#ifdef TORRENT_DISK_STATS
|
#ifdef TORRENT_DISK_STATS
|
||||||
std::ofstream m_log;
|
std::ofstream m_log;
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef TORRENT_STATS
|
||||||
|
int m_allocations;
|
||||||
|
#endif
|
||||||
|
|
||||||
// thread for performing blocking disk io operations
|
// thread for performing blocking disk io operations
|
||||||
boost::thread m_disk_io_thread;
|
boost::thread m_disk_io_thread;
|
||||||
|
@ -69,13 +69,20 @@ namespace libtorrent
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
http_parser();
|
http_parser();
|
||||||
template <class T>
|
std::string const& header(char const* key) const
|
||||||
T header(char const* key) const;
|
{
|
||||||
|
static std::string empty;
|
||||||
|
std::map<std::string, std::string>::const_iterator i
|
||||||
|
= m_header.find(key);
|
||||||
|
if (i == m_header.end()) return empty;
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
|
||||||
std::string const& protocol() const { return m_protocol; }
|
std::string const& protocol() const { return m_protocol; }
|
||||||
int status_code() const { return m_status_code; }
|
int status_code() const { return m_status_code; }
|
||||||
std::string const& method() const { return m_method; }
|
std::string const& method() const { return m_method; }
|
||||||
std::string const& path() const { return m_path; }
|
std::string const& path() const { return m_path; }
|
||||||
std::string message() const { return m_server_message; }
|
std::string const& message() const { return m_server_message; }
|
||||||
buffer::const_interval get_body() const;
|
buffer::const_interval get_body() const;
|
||||||
bool header_finished() const { return m_state == read_body; }
|
bool header_finished() const { return m_state == read_body; }
|
||||||
bool finished() const { return m_finished; }
|
bool finished() const { return m_finished; }
|
||||||
@ -103,15 +110,6 @@ namespace libtorrent
|
|||||||
bool m_finished;
|
bool m_finished;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
|
||||||
T http_parser::header(char const* key) const
|
|
||||||
{
|
|
||||||
std::map<std::string, std::string>::const_iterator i
|
|
||||||
= m_header.find(key);
|
|
||||||
if (i == m_header.end()) return T();
|
|
||||||
return boost::lexical_cast<T>(i->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
class TORRENT_EXPORT http_tracker_connection
|
class TORRENT_EXPORT http_tracker_connection
|
||||||
: public tracker_connection
|
: public tracker_connection
|
||||||
{
|
{
|
||||||
|
@ -60,6 +60,12 @@ namespace libtorrent
|
|||||||
delete static_cast<T const*>(s);
|
delete static_cast<T const*>(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::intrusive_ptr<T> self()
|
||||||
|
{ return boost::intrusive_ptr<T>((T*)this); }
|
||||||
|
|
||||||
|
boost::intrusive_ptr<const T> self() const
|
||||||
|
{ return boost::intrusive_ptr<const T>((T const*)this); }
|
||||||
|
|
||||||
int refcount() const { return m_refs; }
|
int refcount() const { return m_refs; }
|
||||||
|
|
||||||
intrusive_ptr_base(): m_refs(0) {}
|
intrusive_ptr_base(): m_refs(0) {}
|
||||||
|
@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
#include "libtorrent/peer_id.hpp"
|
#include "libtorrent/peer_id.hpp"
|
||||||
#include "libtorrent/broadcast_socket.hpp"
|
#include "libtorrent/broadcast_socket.hpp"
|
||||||
|
#include "libtorrent/intrusive_ptr_base.hpp"
|
||||||
|
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
@ -52,7 +53,7 @@ namespace libtorrent
|
|||||||
|
|
||||||
typedef boost::function<void(tcp::endpoint, sha1_hash)> peer_callback_t;
|
typedef boost::function<void(tcp::endpoint, sha1_hash)> peer_callback_t;
|
||||||
|
|
||||||
class lsd : boost::noncopyable
|
class lsd : public intrusive_ptr_base<lsd>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
lsd(io_service& ios, address const& listen_interface
|
lsd(io_service& ios, address const& listen_interface
|
||||||
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#define TORRENT_NATPMP_HPP
|
#define TORRENT_NATPMP_HPP
|
||||||
|
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
|
#include "libtorrent/intrusive_ptr_base.hpp"
|
||||||
|
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
|
|
||||||
@ -49,7 +50,7 @@ namespace libtorrent
|
|||||||
// std::string: error message
|
// std::string: error message
|
||||||
typedef boost::function<void(int, int, std::string const&)> portmap_callback_t;
|
typedef boost::function<void(int, int, std::string const&)> portmap_callback_t;
|
||||||
|
|
||||||
class natpmp
|
class natpmp : public intrusive_ptr_base<natpmp>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
natpmp(io_service& ios, address const& listen_interface, portmap_callback_t const& cb);
|
natpmp(io_service& ios, address const& listen_interface, portmap_callback_t const& cb);
|
||||||
|
@ -51,6 +51,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include <boost/array.hpp>
|
#include <boost/array.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
|
#include <boost/pool/pool.hpp>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
@ -73,6 +74,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "libtorrent/socket_type.hpp"
|
#include "libtorrent/socket_type.hpp"
|
||||||
#include "libtorrent/intrusive_ptr_base.hpp"
|
#include "libtorrent/intrusive_ptr_base.hpp"
|
||||||
#include "libtorrent/assert.hpp"
|
#include "libtorrent/assert.hpp"
|
||||||
|
#include "libtorrent/chained_buffer.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
@ -356,14 +358,23 @@ namespace libtorrent
|
|||||||
virtual boost::optional<piece_block_progress>
|
virtual boost::optional<piece_block_progress>
|
||||||
downloading_piece_progress() const
|
downloading_piece_progress() const
|
||||||
{
|
{
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
(*m_logger) << "downloading_piece_progress() dispatched to the base class!\n";
|
(*m_logger) << "downloading_piece_progress() dispatched to the base class!\n";
|
||||||
#endif
|
#endif
|
||||||
return boost::optional<piece_block_progress>();
|
return boost::optional<piece_block_progress>();
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_buffer(char const* begin, char const* end);
|
void send_buffer(char const* begin, int size);
|
||||||
buffer::interval allocate_send_buffer(int size);
|
buffer::interval allocate_send_buffer(int size);
|
||||||
|
template <class Destructor>
|
||||||
|
void append_send_buffer(char* buffer, int size, Destructor const& destructor)
|
||||||
|
{
|
||||||
|
m_send_buffer.append_buffer(buffer, size, size, destructor);
|
||||||
|
#ifdef TORRENT_STATS
|
||||||
|
m_ses.m_buffer_usage_logger << log_time() << " append_send_buffer: " << size << std::endl;
|
||||||
|
m_ses.log_buffer_usage();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
void setup_send();
|
void setup_send();
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
#ifndef TORRENT_DISABLE_RESOLVE_COUNTRIES
|
||||||
@ -376,6 +387,12 @@ namespace libtorrent
|
|||||||
bool has_country() const { return m_country[0] != 0; }
|
bool has_country() const { return m_country[0] != 0; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int send_buffer_size() const
|
||||||
|
{ return m_send_buffer.size(); }
|
||||||
|
|
||||||
|
int send_buffer_capacity() const
|
||||||
|
{ return m_send_buffer.capacity(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void get_specific_peer_info(peer_info& p) const = 0;
|
virtual void get_specific_peer_info(peer_info& p) const = 0;
|
||||||
@ -388,7 +405,7 @@ namespace libtorrent
|
|||||||
virtual void write_cancel(peer_request const& r) = 0;
|
virtual void write_cancel(peer_request const& r) = 0;
|
||||||
virtual void write_have(int index) = 0;
|
virtual void write_have(int index) = 0;
|
||||||
virtual void write_keepalive() = 0;
|
virtual void write_keepalive() = 0;
|
||||||
virtual void write_piece(peer_request const& r, char const* buffer) = 0;
|
virtual void write_piece(peer_request const& r, char* buffer) = 0;
|
||||||
|
|
||||||
virtual void write_reject_request(peer_request const& r) = 0;
|
virtual void write_reject_request(peer_request const& r) = 0;
|
||||||
virtual void write_allow_fast(int piece) = 0;
|
virtual void write_allow_fast(int piece) = 0;
|
||||||
@ -401,13 +418,6 @@ namespace libtorrent
|
|||||||
virtual void on_sent(asio::error_code const& error
|
virtual void on_sent(asio::error_code const& error
|
||||||
, std::size_t bytes_transferred) = 0;
|
, std::size_t bytes_transferred) = 0;
|
||||||
|
|
||||||
int send_buffer_size() const
|
|
||||||
{
|
|
||||||
return (int)m_send_buffer[0].size()
|
|
||||||
+ (int)m_send_buffer[1].size()
|
|
||||||
- m_write_pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
buffer::interval wr_recv_buffer()
|
buffer::interval wr_recv_buffer()
|
||||||
{
|
{
|
||||||
@ -512,31 +522,13 @@ namespace libtorrent
|
|||||||
int m_recv_pos;
|
int m_recv_pos;
|
||||||
buffer m_recv_buffer;
|
buffer m_recv_buffer;
|
||||||
|
|
||||||
// this is the buffer where data that is
|
chained_buffer m_send_buffer;
|
||||||
// to be sent is stored until it gets
|
|
||||||
// consumed by send(). Since asio requires
|
|
||||||
// the memory buffer that is given to async.
|
|
||||||
// operations to remain valid until the operation
|
|
||||||
// finishes, there has to be two buffers. While
|
|
||||||
// waiting for a async_write operation on one
|
|
||||||
// buffer, the other is used to write data to
|
|
||||||
// be queued up.
|
|
||||||
buffer m_send_buffer[2];
|
|
||||||
// the current send buffer is the one to write to.
|
|
||||||
// (m_current_send_buffer + 1) % 2 is the
|
|
||||||
// buffer we're currently waiting for.
|
|
||||||
int m_current_send_buffer;
|
|
||||||
|
|
||||||
// the number of bytes we are currently reading
|
// the number of bytes we are currently reading
|
||||||
// from disk, that will be added to the send
|
// from disk, that will be added to the send
|
||||||
// buffer as soon as they complete
|
// buffer as soon as they complete
|
||||||
int m_reading_bytes;
|
int m_reading_bytes;
|
||||||
|
|
||||||
// if the sending buffer doesn't finish in one send
|
|
||||||
// operation, this is the position within that buffer
|
|
||||||
// where the next operation should continue
|
|
||||||
int m_write_pos;
|
|
||||||
|
|
||||||
// timeouts
|
// timeouts
|
||||||
ptime m_last_receive;
|
ptime m_last_receive;
|
||||||
ptime m_last_sent;
|
ptime m_last_sent;
|
||||||
|
@ -184,6 +184,9 @@ namespace libtorrent
|
|||||||
std::pair<bool, float> check_files(std::vector<bool>& pieces
|
std::pair<bool, float> check_files(std::vector<bool>& pieces
|
||||||
, int& num_pieces, boost::recursive_mutex& mutex);
|
, int& num_pieces, boost::recursive_mutex& mutex);
|
||||||
|
|
||||||
|
// frees a buffer that was returned from a read operation
|
||||||
|
void free_buffer(char* buf);
|
||||||
|
|
||||||
void write_resume_data(entry& rd) const;
|
void write_resume_data(entry& rd) const;
|
||||||
bool verify_resume_data(entry& rd, std::string& error);
|
bool verify_resume_data(entry& rd, std::string& error);
|
||||||
|
|
||||||
|
@ -49,6 +49,8 @@ namespace libtorrent
|
|||||||
std::strftime(str, 200, "%b %d %X", timeinfo);
|
std::strftime(str, 200, "%b %d %X", timeinfo);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::string log_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (!defined (__MACH__) && !defined (_WIN32) && (!defined(_POSIX_MONOTONIC_CLOCK) \
|
#if (!defined (__MACH__) && !defined (_WIN32) && (!defined(_POSIX_MONOTONIC_CLOCK) \
|
||||||
@ -389,5 +391,6 @@ namespace libtorrent
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#include "libtorrent/broadcast_socket.hpp"
|
#include "libtorrent/broadcast_socket.hpp"
|
||||||
#include "libtorrent/http_connection.hpp"
|
#include "libtorrent/http_connection.hpp"
|
||||||
#include "libtorrent/connection_queue.hpp"
|
#include "libtorrent/connection_queue.hpp"
|
||||||
|
#include "libtorrent/intrusive_ptr_base.hpp"
|
||||||
|
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
@ -62,7 +63,7 @@ namespace libtorrent
|
|||||||
// std::string: error message
|
// std::string: error message
|
||||||
typedef boost::function<void(int, int, std::string const&)> portmap_callback_t;
|
typedef boost::function<void(int, int, std::string const&)> portmap_callback_t;
|
||||||
|
|
||||||
class upnp : boost::noncopyable
|
class upnp : public intrusive_ptr_base<upnp>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
upnp(io_service& ios, connection_queue& cc
|
upnp(io_service& ios, connection_queue& cc
|
||||||
|
@ -122,7 +122,7 @@ namespace libtorrent
|
|||||||
void write_request(peer_request const& r);
|
void write_request(peer_request const& r);
|
||||||
void write_cancel(peer_request const& r) {}
|
void write_cancel(peer_request const& r) {}
|
||||||
void write_have(int index) {}
|
void write_have(int index) {}
|
||||||
void write_piece(peer_request const& r, char const* buffer) { assert(false); }
|
void write_piece(peer_request const& r, char* buffer) { assert(false); }
|
||||||
void write_keepalive() {}
|
void write_keepalive() {}
|
||||||
void on_connected();
|
void on_connected();
|
||||||
void write_reject_request(peer_request const&) {}
|
void write_reject_request(peer_request const&) {}
|
||||||
|
@ -58,6 +58,7 @@ $(top_srcdir)/include/libtorrent/intrusive_ptr_base.hpp \
|
|||||||
$(top_srcdir)/include/libtorrent/invariant_check.hpp \
|
$(top_srcdir)/include/libtorrent/invariant_check.hpp \
|
||||||
$(top_srcdir)/include/libtorrent/io.hpp \
|
$(top_srcdir)/include/libtorrent/io.hpp \
|
||||||
$(top_srcdir)/include/libtorrent/ip_filter.hpp \
|
$(top_srcdir)/include/libtorrent/ip_filter.hpp \
|
||||||
|
$(top_srcdir)/include/libtorrent/chained_buffer.hpp \
|
||||||
$(top_srcdir)/include/libtorrent/lsd.hpp \
|
$(top_srcdir)/include/libtorrent/lsd.hpp \
|
||||||
$(top_srcdir)/include/libtorrent/peer.hpp \
|
$(top_srcdir)/include/libtorrent/peer.hpp \
|
||||||
$(top_srcdir)/include/libtorrent/peer_connection.hpp \
|
$(top_srcdir)/include/libtorrent/peer_connection.hpp \
|
||||||
|
@ -251,12 +251,10 @@ namespace libtorrent
|
|||||||
(*m_logger) << time_now_string()
|
(*m_logger) << time_now_string()
|
||||||
<< " ==> DHT_PORT [ " << listen_port << " ]\n";
|
<< " ==> DHT_PORT [ " << listen_port << " ]\n";
|
||||||
#endif
|
#endif
|
||||||
buffer::interval packet = allocate_send_buffer(7);
|
char msg[] = {0,0,0,3, msg_dht_port, 0, 0};
|
||||||
detail::write_uint32(3, packet.begin);
|
char* ptr = msg + 5;
|
||||||
detail::write_uint8(msg_dht_port, packet.begin);
|
detail::write_uint16(listen_port, ptr);
|
||||||
detail::write_uint16(listen_port, packet.begin);
|
send_buffer(msg, sizeof(msg));
|
||||||
assert(packet.begin == packet.end);
|
|
||||||
setup_send();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_peer_connection::write_have_all()
|
void bt_peer_connection::write_have_all()
|
||||||
@ -270,8 +268,8 @@ namespace libtorrent
|
|||||||
(*m_logger) << time_now_string()
|
(*m_logger) << time_now_string()
|
||||||
<< " ==> HAVE_ALL\n";
|
<< " ==> HAVE_ALL\n";
|
||||||
#endif
|
#endif
|
||||||
char buf[] = {0,0,0,1, msg_have_all};
|
char msg[] = {0,0,0,1, msg_have_all};
|
||||||
send_buffer(buf, buf + sizeof(buf));
|
send_buffer(msg, sizeof(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_peer_connection::write_have_none()
|
void bt_peer_connection::write_have_none()
|
||||||
@ -285,8 +283,8 @@ namespace libtorrent
|
|||||||
(*m_logger) << time_now_string()
|
(*m_logger) << time_now_string()
|
||||||
<< " ==> HAVE_NONE\n";
|
<< " ==> HAVE_NONE\n";
|
||||||
#endif
|
#endif
|
||||||
char buf[] = {0,0,0,1, msg_have_none};
|
char msg[] = {0,0,0,1, msg_have_none};
|
||||||
send_buffer(buf, buf + sizeof(buf));
|
send_buffer(msg, sizeof(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_peer_connection::write_reject_request(peer_request const& r)
|
void bt_peer_connection::write_reject_request(peer_request const& r)
|
||||||
@ -296,22 +294,12 @@ namespace libtorrent
|
|||||||
assert(m_sent_handshake && m_sent_bitfield);
|
assert(m_sent_handshake && m_sent_bitfield);
|
||||||
assert(associated_torrent().lock()->valid_metadata());
|
assert(associated_torrent().lock()->valid_metadata());
|
||||||
|
|
||||||
char buf[] = {0,0,0,13, msg_reject_request};
|
char msg[] = {0,0,0,13, msg_reject_request,0,0,0,0, 0,0,0,0, 0,0,0,0};
|
||||||
|
char* ptr = msg + 5;
|
||||||
buffer::interval i = allocate_send_buffer(17);
|
detail::write_int32(r.piece, ptr); // index
|
||||||
|
detail::write_int32(r.start, ptr); // begin
|
||||||
std::copy(buf, buf + 5, i.begin);
|
detail::write_int32(r.length, ptr); // length
|
||||||
i.begin += 5;
|
send_buffer(msg, sizeof(msg));
|
||||||
|
|
||||||
// index
|
|
||||||
detail::write_int32(r.piece, i.begin);
|
|
||||||
// begin
|
|
||||||
detail::write_int32(r.start, i.begin);
|
|
||||||
// length
|
|
||||||
detail::write_int32(r.length, i.begin);
|
|
||||||
assert(i.begin == i.end);
|
|
||||||
|
|
||||||
setup_send();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_peer_connection::write_allow_fast(int piece)
|
void bt_peer_connection::write_allow_fast(int piece)
|
||||||
@ -321,11 +309,10 @@ namespace libtorrent
|
|||||||
assert(m_sent_handshake && m_sent_bitfield);
|
assert(m_sent_handshake && m_sent_bitfield);
|
||||||
assert(associated_torrent().lock()->valid_metadata());
|
assert(associated_torrent().lock()->valid_metadata());
|
||||||
|
|
||||||
char buf[] = {0,0,0,5, msg_allowed_fast, 0, 0, 0, 0};
|
char msg[] = {0,0,0,5, msg_allowed_fast, 0, 0, 0, 0};
|
||||||
|
char* ptr = msg + 5;
|
||||||
char* ptr = buf + 5;
|
|
||||||
detail::write_int32(piece, ptr);
|
detail::write_int32(piece, ptr);
|
||||||
send_buffer(buf, buf + sizeof(buf));
|
send_buffer(msg, sizeof(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_peer_connection::get_specific_peer_info(peer_info& p) const
|
void bt_peer_connection::get_specific_peer_info(peer_info& p) const
|
||||||
@ -556,8 +543,8 @@ namespace libtorrent
|
|||||||
assert(secret);
|
assert(secret);
|
||||||
|
|
||||||
hasher h;
|
hasher h;
|
||||||
const char keyA[] = "keyA";
|
static const char keyA[] = "keyA";
|
||||||
const char keyB[] = "keyB";
|
static const char keyB[] = "keyB";
|
||||||
|
|
||||||
// encryption rc4 longkeys
|
// encryption rc4 longkeys
|
||||||
// outgoing connection : hash ('keyA',S,SKEY)
|
// outgoing connection : hash ('keyA',S,SKEY)
|
||||||
@ -587,17 +574,16 @@ namespace libtorrent
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_peer_connection::send_buffer(char* begin, char* end)
|
void bt_peer_connection::send_buffer(char* buf, int size)
|
||||||
{
|
{
|
||||||
assert (begin);
|
assert(buf);
|
||||||
assert (end);
|
assert(size > 0);
|
||||||
assert (end > begin);
|
assert(!m_rc4_encrypted || m_encrypted);
|
||||||
assert (!m_rc4_encrypted || m_encrypted);
|
|
||||||
|
|
||||||
if (m_rc4_encrypted)
|
if (m_rc4_encrypted)
|
||||||
m_RC4_handler->encrypt(begin, end - begin);
|
m_RC4_handler->encrypt(buf, size);
|
||||||
|
|
||||||
peer_connection::send_buffer(begin, end);
|
peer_connection::send_buffer(buf, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer::interval bt_peer_connection::allocate_send_buffer(int size)
|
buffer::interval bt_peer_connection::allocate_send_buffer(int size)
|
||||||
@ -606,6 +592,7 @@ namespace libtorrent
|
|||||||
|
|
||||||
if (m_rc4_encrypted)
|
if (m_rc4_encrypted)
|
||||||
{
|
{
|
||||||
|
assert(m_enc_send_buffer.left() == 0);
|
||||||
m_enc_send_buffer = peer_connection::allocate_send_buffer(size);
|
m_enc_send_buffer = peer_connection::allocate_send_buffer(size);
|
||||||
return m_enc_send_buffer;
|
return m_enc_send_buffer;
|
||||||
}
|
}
|
||||||
@ -620,24 +607,24 @@ namespace libtorrent
|
|||||||
{
|
{
|
||||||
assert(!m_rc4_encrypted || m_encrypted);
|
assert(!m_rc4_encrypted || m_encrypted);
|
||||||
|
|
||||||
if (m_rc4_encrypted)
|
if (m_rc4_encrypted && m_enc_send_buffer.left())
|
||||||
{
|
{
|
||||||
assert (m_enc_send_buffer.begin);
|
assert(m_enc_send_buffer.begin);
|
||||||
assert (m_enc_send_buffer.end);
|
assert(m_enc_send_buffer.end);
|
||||||
assert (m_enc_send_buffer.left() > 0);
|
|
||||||
|
|
||||||
m_RC4_handler->encrypt (m_enc_send_buffer.begin, m_enc_send_buffer.left());
|
m_RC4_handler->encrypt(m_enc_send_buffer.begin, m_enc_send_buffer.left());
|
||||||
|
m_enc_send_buffer.end = m_enc_send_buffer.begin;
|
||||||
}
|
}
|
||||||
peer_connection::setup_send();
|
peer_connection::setup_send();
|
||||||
}
|
}
|
||||||
|
|
||||||
int bt_peer_connection::get_syncoffset(char const* src, int src_size,
|
int bt_peer_connection::get_syncoffset(char const* src, int src_size,
|
||||||
char const* target, int target_size) const
|
char const* target, int target_size) const
|
||||||
{
|
{
|
||||||
assert (target_size >= src_size);
|
assert(target_size >= src_size);
|
||||||
assert (src_size > 0);
|
assert(src_size > 0);
|
||||||
assert (src);
|
assert(src);
|
||||||
assert (target);
|
assert(target);
|
||||||
|
|
||||||
int traverse_limit = target_size - src_size;
|
int traverse_limit = target_size - src_size;
|
||||||
|
|
||||||
@ -1288,8 +1275,8 @@ namespace libtorrent
|
|||||||
|
|
||||||
assert(m_sent_handshake && m_sent_bitfield);
|
assert(m_sent_handshake && m_sent_bitfield);
|
||||||
|
|
||||||
char buf[] = {0,0,0,0};
|
char msg[] = {0,0,0,0};
|
||||||
send_buffer(buf, buf + sizeof(buf));
|
send_buffer(msg, sizeof(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_peer_connection::write_cancel(peer_request const& r)
|
void bt_peer_connection::write_cancel(peer_request const& r)
|
||||||
@ -1299,22 +1286,12 @@ namespace libtorrent
|
|||||||
assert(m_sent_handshake && m_sent_bitfield);
|
assert(m_sent_handshake && m_sent_bitfield);
|
||||||
assert(associated_torrent().lock()->valid_metadata());
|
assert(associated_torrent().lock()->valid_metadata());
|
||||||
|
|
||||||
char buf[] = {0,0,0,13, msg_cancel};
|
char msg[17] = {0,0,0,13, msg_cancel};
|
||||||
|
char* ptr = msg + 5;
|
||||||
buffer::interval i = allocate_send_buffer(17);
|
detail::write_int32(r.piece, ptr); // index
|
||||||
|
detail::write_int32(r.start, ptr); // begin
|
||||||
std::copy(buf, buf + 5, i.begin);
|
detail::write_int32(r.length, ptr); // length
|
||||||
i.begin += 5;
|
send_buffer(msg, sizeof(msg));
|
||||||
|
|
||||||
// index
|
|
||||||
detail::write_int32(r.piece, i.begin);
|
|
||||||
// begin
|
|
||||||
detail::write_int32(r.start, i.begin);
|
|
||||||
// length
|
|
||||||
detail::write_int32(r.length, i.begin);
|
|
||||||
assert(i.begin == i.end);
|
|
||||||
|
|
||||||
setup_send();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_peer_connection::write_request(peer_request const& r)
|
void bt_peer_connection::write_request(peer_request const& r)
|
||||||
@ -1324,22 +1301,13 @@ namespace libtorrent
|
|||||||
assert(m_sent_handshake && m_sent_bitfield);
|
assert(m_sent_handshake && m_sent_bitfield);
|
||||||
assert(associated_torrent().lock()->valid_metadata());
|
assert(associated_torrent().lock()->valid_metadata());
|
||||||
|
|
||||||
char buf[] = {0,0,0,13, msg_request};
|
char msg[17] = {0,0,0,13, msg_request};
|
||||||
|
char* ptr = msg + 5;
|
||||||
|
|
||||||
buffer::interval i = allocate_send_buffer(17);
|
detail::write_int32(r.piece, ptr); // index
|
||||||
|
detail::write_int32(r.start, ptr); // begin
|
||||||
std::copy(buf, buf + 5, i.begin);
|
detail::write_int32(r.length, ptr); // length
|
||||||
i.begin += 5;
|
send_buffer(msg, sizeof(msg));
|
||||||
|
|
||||||
// index
|
|
||||||
detail::write_int32(r.piece, i.begin);
|
|
||||||
// begin
|
|
||||||
detail::write_int32(r.start, i.begin);
|
|
||||||
// length
|
|
||||||
detail::write_int32(r.length, i.begin);
|
|
||||||
assert(i.begin == i.end);
|
|
||||||
|
|
||||||
setup_send();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_peer_connection::write_bitfield(std::vector<bool> const& bitfield)
|
void bt_peer_connection::write_bitfield(std::vector<bool> const& bitfield)
|
||||||
@ -1526,7 +1494,7 @@ namespace libtorrent
|
|||||||
|
|
||||||
if (is_choked()) return;
|
if (is_choked()) return;
|
||||||
char msg[] = {0,0,0,1,msg_choke};
|
char msg[] = {0,0,0,1,msg_choke};
|
||||||
send_buffer(msg, msg + sizeof(msg));
|
send_buffer(msg, sizeof(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_peer_connection::write_unchoke()
|
void bt_peer_connection::write_unchoke()
|
||||||
@ -1536,7 +1504,7 @@ namespace libtorrent
|
|||||||
assert(m_sent_handshake && m_sent_bitfield);
|
assert(m_sent_handshake && m_sent_bitfield);
|
||||||
|
|
||||||
char msg[] = {0,0,0,1,msg_unchoke};
|
char msg[] = {0,0,0,1,msg_unchoke};
|
||||||
send_buffer(msg, msg + sizeof(msg));
|
send_buffer(msg, sizeof(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_peer_connection::write_interested()
|
void bt_peer_connection::write_interested()
|
||||||
@ -1546,7 +1514,7 @@ namespace libtorrent
|
|||||||
assert(m_sent_handshake && m_sent_bitfield);
|
assert(m_sent_handshake && m_sent_bitfield);
|
||||||
|
|
||||||
char msg[] = {0,0,0,1,msg_interested};
|
char msg[] = {0,0,0,1,msg_interested};
|
||||||
send_buffer(msg, msg + sizeof(msg));
|
send_buffer(msg, sizeof(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_peer_connection::write_not_interested()
|
void bt_peer_connection::write_not_interested()
|
||||||
@ -1556,7 +1524,7 @@ namespace libtorrent
|
|||||||
assert(m_sent_handshake && m_sent_bitfield);
|
assert(m_sent_handshake && m_sent_bitfield);
|
||||||
|
|
||||||
char msg[] = {0,0,0,1,msg_not_interested};
|
char msg[] = {0,0,0,1,msg_not_interested};
|
||||||
send_buffer(msg, msg + sizeof(msg));
|
send_buffer(msg, sizeof(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_peer_connection::write_have(int index)
|
void bt_peer_connection::write_have(int index)
|
||||||
@ -1567,34 +1535,39 @@ namespace libtorrent
|
|||||||
assert(index < associated_torrent().lock()->torrent_file().num_pieces());
|
assert(index < associated_torrent().lock()->torrent_file().num_pieces());
|
||||||
assert(m_sent_handshake && m_sent_bitfield);
|
assert(m_sent_handshake && m_sent_bitfield);
|
||||||
|
|
||||||
const int packet_size = 9;
|
char msg[] = {0,0,0,5,msg_have,0,0,0,0};
|
||||||
char msg[packet_size] = {0,0,0,5,msg_have};
|
|
||||||
char* ptr = msg + 5;
|
char* ptr = msg + 5;
|
||||||
detail::write_int32(index, ptr);
|
detail::write_int32(index, ptr);
|
||||||
send_buffer(msg, msg + packet_size);
|
send_buffer(msg, sizeof(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
void bt_peer_connection::write_piece(peer_request const& r, char const* buffer)
|
void bt_peer_connection::write_piece(peer_request const& r, char* buffer)
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
assert(m_sent_handshake && m_sent_bitfield);
|
assert(m_sent_handshake && m_sent_bitfield);
|
||||||
|
|
||||||
const int packet_size = 4 + 5 + 4 + r.length;
|
|
||||||
|
|
||||||
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
||||||
assert(t);
|
assert(t);
|
||||||
|
|
||||||
buffer::interval i = allocate_send_buffer(packet_size);
|
char msg[4 + 1 + 4 + 4];
|
||||||
|
char* ptr = msg;
|
||||||
detail::write_int32(packet_size-4, i.begin);
|
assert(r.length <= 16 * 1024);
|
||||||
detail::write_uint8(msg_piece, i.begin);
|
detail::write_int32(r.length + 1 + 4 + 4, ptr);
|
||||||
detail::write_int32(r.piece, i.begin);
|
detail::write_uint8(msg_piece, ptr);
|
||||||
detail::write_int32(r.start, i.begin);
|
detail::write_int32(r.piece, ptr);
|
||||||
|
detail::write_int32(r.start, ptr);
|
||||||
|
send_buffer(msg, sizeof(msg));
|
||||||
|
|
||||||
|
append_send_buffer(buffer, r.length
|
||||||
|
, boost::bind(&session_impl::free_disk_buffer
|
||||||
|
, boost::ref(m_ses), _1));
|
||||||
|
|
||||||
|
/*
|
||||||
|
buffer::interval i = allocate_send_buffer(r.length);
|
||||||
std::memcpy(i.begin, buffer, r.length);
|
std::memcpy(i.begin, buffer, r.length);
|
||||||
|
t->filesystem().free_buffer(buffer);
|
||||||
assert(i.begin + r.length == i.end);
|
*/
|
||||||
|
|
||||||
m_payloads.push_back(range(send_buffer_size() - r.length, r.length));
|
m_payloads.push_back(range(send_buffer_size() - r.length, r.length));
|
||||||
setup_send();
|
setup_send();
|
||||||
}
|
}
|
||||||
|
@ -37,18 +37,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||||||
#ifdef TORRENT_DISK_STATS
|
#ifdef TORRENT_DISK_STATS
|
||||||
|
|
||||||
#include "libtorrent/time.hpp"
|
#include "libtorrent/time.hpp"
|
||||||
#include <boost/lexical_cast.hpp>
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
std::string log_time()
|
|
||||||
{
|
|
||||||
using namespace libtorrent;
|
|
||||||
static ptime start = time_now();
|
|
||||||
return boost::lexical_cast<std::string>(
|
|
||||||
total_milliseconds(time_now() - start));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -64,7 +52,9 @@ namespace libtorrent
|
|||||||
#endif
|
#endif
|
||||||
, m_disk_io_thread(boost::ref(*this))
|
, m_disk_io_thread(boost::ref(*this))
|
||||||
{
|
{
|
||||||
|
#ifdef TORRENT_STATS
|
||||||
|
m_allocations = 0;
|
||||||
|
#endif
|
||||||
#ifdef TORRENT_DISK_STATS
|
#ifdef TORRENT_DISK_STATS
|
||||||
m_log.open("disk_io_thread.log", std::ios::trunc);
|
m_log.open("disk_io_thread.log", std::ios::trunc);
|
||||||
#endif
|
#endif
|
||||||
@ -188,9 +178,21 @@ namespace libtorrent
|
|||||||
char* disk_io_thread::allocate_buffer()
|
char* disk_io_thread::allocate_buffer()
|
||||||
{
|
{
|
||||||
boost::mutex::scoped_lock l(m_mutex);
|
boost::mutex::scoped_lock l(m_mutex);
|
||||||
|
#ifdef TORRENT_STATS
|
||||||
|
++m_allocations;
|
||||||
|
#endif
|
||||||
return (char*)m_pool.ordered_malloc();
|
return (char*)m_pool.ordered_malloc();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void disk_io_thread::free_buffer(char* buf)
|
||||||
|
{
|
||||||
|
boost::mutex::scoped_lock l(m_mutex);
|
||||||
|
#ifdef TORRENT_STATS
|
||||||
|
--m_allocations;
|
||||||
|
#endif
|
||||||
|
m_pool.ordered_free(buf);
|
||||||
|
}
|
||||||
|
|
||||||
void disk_io_thread::operator()()
|
void disk_io_thread::operator()()
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
@ -225,10 +227,14 @@ namespace libtorrent
|
|||||||
#ifdef TORRENT_DISK_STATS
|
#ifdef TORRENT_DISK_STATS
|
||||||
m_log << log_time() << " read " << j.buffer_size << std::endl;
|
m_log << log_time() << " read " << j.buffer_size << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
free_buffer = false;
|
||||||
if (j.buffer == 0)
|
if (j.buffer == 0)
|
||||||
{
|
{
|
||||||
l.lock();
|
l.lock();
|
||||||
j.buffer = (char*)m_pool.ordered_malloc();
|
j.buffer = (char*)m_pool.ordered_malloc();
|
||||||
|
#ifdef TORRENT_STATS
|
||||||
|
++m_allocations;
|
||||||
|
#endif
|
||||||
l.unlock();
|
l.unlock();
|
||||||
assert(j.buffer_size <= m_block_size);
|
assert(j.buffer_size <= m_block_size);
|
||||||
if (j.buffer == 0)
|
if (j.buffer == 0)
|
||||||
@ -238,10 +244,6 @@ namespace libtorrent
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
free_buffer = false;
|
|
||||||
}
|
|
||||||
ret = j.storage->read_impl(j.buffer, j.piece, j.offset
|
ret = j.storage->read_impl(j.buffer, j.piece, j.offset
|
||||||
, j.buffer_size);
|
, j.buffer_size);
|
||||||
|
|
||||||
@ -301,6 +303,9 @@ namespace libtorrent
|
|||||||
{
|
{
|
||||||
l.lock();
|
l.lock();
|
||||||
m_pool.ordered_free(j.buffer);
|
m_pool.ordered_free(j.buffer);
|
||||||
|
#ifdef TORRENT_STATS
|
||||||
|
--m_allocations;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,7 +263,7 @@ void http_connection::on_read(asio::error_code const& e
|
|||||||
if (code >= 300 && code < 400)
|
if (code >= 300 && code < 400)
|
||||||
{
|
{
|
||||||
// attempt a redirect
|
// attempt a redirect
|
||||||
std::string url = m_parser.header<std::string>("location");
|
std::string const& url = m_parser.header("location");
|
||||||
if (url.empty())
|
if (url.empty())
|
||||||
{
|
{
|
||||||
// missing location header
|
// missing location header
|
||||||
|
@ -679,7 +679,7 @@ namespace libtorrent
|
|||||||
|
|
||||||
if (m_parser.header_finished())
|
if (m_parser.header_finished())
|
||||||
{
|
{
|
||||||
int cl = m_parser.header<int>("content-length");
|
int cl = atoi(m_parser.header("content-length").c_str());
|
||||||
if (cl > m_settings.tracker_maximum_response_length)
|
if (cl > m_settings.tracker_maximum_response_length)
|
||||||
{
|
{
|
||||||
fail(-1, "content-length is greater than maximum response length");
|
fail(-1, "content-length is greater than maximum response length");
|
||||||
@ -718,7 +718,7 @@ namespace libtorrent
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string location = m_parser.header<std::string>("location");
|
std::string location = m_parser.header("location");
|
||||||
|
|
||||||
boost::shared_ptr<request_callback> cb = requester();
|
boost::shared_ptr<request_callback> cb = requester();
|
||||||
|
|
||||||
@ -763,7 +763,7 @@ namespace libtorrent
|
|||||||
|
|
||||||
buffer::const_interval buf(&m_buffer[0] + m_parser.body_start(), &m_buffer[0] + m_recv_pos);
|
buffer::const_interval buf(&m_buffer[0] + m_parser.body_start(), &m_buffer[0] + m_recv_pos);
|
||||||
|
|
||||||
std::string content_encoding = m_parser.header<std::string>("content-encoding");
|
std::string content_encoding = m_parser.header("content-encoding");
|
||||||
|
|
||||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
if (cb) cb->debug_log("content-encoding: \"" + content_encoding + "\"");
|
if (cb) cb->debug_log("content-encoding: \"" + content_encoding + "\"");
|
||||||
|
@ -58,7 +58,7 @@ lsd::lsd(io_service& ios, address const& listen_interface
|
|||||||
: m_callback(cb)
|
: m_callback(cb)
|
||||||
, m_retry_count(0)
|
, m_retry_count(0)
|
||||||
, m_socket(ios, udp::endpoint(address_v4::from_string("239.192.152.143"), 6771)
|
, m_socket(ios, udp::endpoint(address_v4::from_string("239.192.152.143"), 6771)
|
||||||
, bind(&lsd::on_announce, this, _1, _2, _3))
|
, bind(&lsd::on_announce, self(), _1, _2, _3))
|
||||||
, m_broadcast_timer(ios)
|
, m_broadcast_timer(ios)
|
||||||
, m_disabled(false)
|
, m_disabled(false)
|
||||||
{
|
{
|
||||||
@ -96,7 +96,7 @@ void lsd::announce(sha1_hash const& ih, int listen_port)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_broadcast_timer.expires_from_now(milliseconds(250 * m_retry_count));
|
m_broadcast_timer.expires_from_now(milliseconds(250 * m_retry_count));
|
||||||
m_broadcast_timer.async_wait(bind(&lsd::resend_announce, this, _1, msg));
|
m_broadcast_timer.async_wait(bind(&lsd::resend_announce, self(), _1, msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
void lsd::resend_announce(asio::error_code const& e, std::string msg) try
|
void lsd::resend_announce(asio::error_code const& e, std::string msg) try
|
||||||
@ -111,7 +111,7 @@ void lsd::resend_announce(asio::error_code const& e, std::string msg) try
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_broadcast_timer.expires_from_now(milliseconds(250 * m_retry_count));
|
m_broadcast_timer.expires_from_now(milliseconds(250 * m_retry_count));
|
||||||
m_broadcast_timer.async_wait(bind(&lsd::resend_announce, this, _1, msg));
|
m_broadcast_timer.async_wait(bind(&lsd::resend_announce, self(), _1, msg));
|
||||||
}
|
}
|
||||||
catch (std::exception&)
|
catch (std::exception&)
|
||||||
{}
|
{}
|
||||||
@ -121,48 +121,53 @@ void lsd::on_announce(udp::endpoint const& from, char* buffer
|
|||||||
{
|
{
|
||||||
using namespace libtorrent::detail;
|
using namespace libtorrent::detail;
|
||||||
|
|
||||||
char* p = buffer;
|
http_parser p;
|
||||||
char* end = buffer + bytes_transferred;
|
|
||||||
char* line = std::find(p, end, '\n');
|
p.incoming(buffer::const_interval(buffer, buffer + bytes_transferred));
|
||||||
for (char* i = p; i < line; ++i) *i = std::tolower(*i);
|
|
||||||
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
|
if (!p.header_finished())
|
||||||
m_log << time_now_string()
|
|
||||||
<< " <== announce: " << std::string(p, line) << std::endl;
|
|
||||||
#endif
|
|
||||||
if (line == end || (line - p >= 9 && std::memcmp("bt-search", p, 9)))
|
|
||||||
{
|
{
|
||||||
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
|
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
|
||||||
m_log << time_now_string()
|
m_log << time_now_string()
|
||||||
<< " *** assumed 'bt-search', ignoring" << std::endl;
|
<< " <== announce: incomplete HTTP message\n";
|
||||||
#endif
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
p = line + 1;
|
|
||||||
int port = 0;
|
if (p.method() != "bt-search")
|
||||||
sha1_hash ih(0);
|
|
||||||
while (p != end)
|
|
||||||
{
|
{
|
||||||
line = std::find(p, end, '\n');
|
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
|
||||||
if (line == end) break;
|
m_log << time_now_string()
|
||||||
*line = 0;
|
<< " <== announce: invalid HTTP method: " << p.method() << std::endl;
|
||||||
for (char* i = p; i < line; ++i) *i = std::tolower(*i);
|
#endif
|
||||||
if (line - p >= 5 && memcmp(p, "port:", 5) == 0)
|
return;
|
||||||
{
|
|
||||||
p += 5;
|
|
||||||
while (*p == ' ') ++p;
|
|
||||||
port = atoi(p);
|
|
||||||
}
|
|
||||||
else if (line - p >= 9 && memcmp(p, "infohash:", 9) == 0)
|
|
||||||
{
|
|
||||||
p += 9;
|
|
||||||
while (*p == ' ') ++p;
|
|
||||||
if (line - p > 40) p[40] = 0;
|
|
||||||
try { ih = boost::lexical_cast<sha1_hash>(p); }
|
|
||||||
catch (std::exception&) {}
|
|
||||||
}
|
|
||||||
p = line + 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string const& port_str = p.header("port");
|
||||||
|
if (port_str.empty())
|
||||||
|
{
|
||||||
|
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
|
||||||
|
m_log << time_now_string()
|
||||||
|
<< " <== announce: invalid BT-SEARCH, missing port" << std::endl;
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string const& ih_str = p.header("infohash");
|
||||||
|
if (ih_str.empty())
|
||||||
|
{
|
||||||
|
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
|
||||||
|
m_log << time_now_string()
|
||||||
|
<< " <== announce: invalid BT-SEARCH, missing infohash" << std::endl;
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sha1_hash ih(0);
|
||||||
|
std::istringstream ih_sstr(ih_str);
|
||||||
|
ih_sstr >> ih;
|
||||||
|
int port = atoi(port_str.c_str());
|
||||||
|
|
||||||
if (!ih.is_all_zeros() && port != 0)
|
if (!ih.is_all_zeros() && port != 0)
|
||||||
{
|
{
|
||||||
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
|
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
|
||||||
|
@ -161,7 +161,7 @@ void natpmp::update_mapping(int i, int port)
|
|||||||
m_retry_count = 0;
|
m_retry_count = 0;
|
||||||
send_map_request(i);
|
send_map_request(i);
|
||||||
m_socket.async_receive_from(asio::buffer(&m_response_buffer, 16)
|
m_socket.async_receive_from(asio::buffer(&m_response_buffer, 16)
|
||||||
, m_remote, bind(&natpmp::on_reply, this, _1, _2));
|
, m_remote, bind(&natpmp::on_reply, self(), _1, _2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +194,7 @@ void natpmp::send_map_request(int i) try
|
|||||||
// linear back-off instead of exponential
|
// linear back-off instead of exponential
|
||||||
++m_retry_count;
|
++m_retry_count;
|
||||||
m_send_timer.expires_from_now(milliseconds(250 * m_retry_count));
|
m_send_timer.expires_from_now(milliseconds(250 * m_retry_count));
|
||||||
m_send_timer.async_wait(bind(&natpmp::resend_request, this, i, _1));
|
m_send_timer.async_wait(bind(&natpmp::resend_request, self(), i, _1));
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
@ -227,7 +227,7 @@ void natpmp::on_reply(asio::error_code const& e
|
|||||||
if (m_remote != m_nat_endpoint)
|
if (m_remote != m_nat_endpoint)
|
||||||
{
|
{
|
||||||
m_socket.async_receive_from(asio::buffer(&m_response_buffer, 16)
|
m_socket.async_receive_from(asio::buffer(&m_response_buffer, 16)
|
||||||
, m_remote, bind(&natpmp::on_reply, this, _1, _2));
|
, m_remote, bind(&natpmp::on_reply, self(), _1, _2));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,7 +346,7 @@ void natpmp::update_expiration_timer()
|
|||||||
if (min_index >= 0)
|
if (min_index >= 0)
|
||||||
{
|
{
|
||||||
m_refresh_timer.expires_from_now(min_expire - now);
|
m_refresh_timer.expires_from_now(min_expire - now);
|
||||||
m_refresh_timer.async_wait(bind(&natpmp::mapping_expired, this, _1, min_index));
|
m_refresh_timer.async_wait(bind(&natpmp::mapping_expired, self(), _1, min_index));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,7 +369,7 @@ void natpmp::refresh_mapping(int i)
|
|||||||
m_retry_count = 0;
|
m_retry_count = 0;
|
||||||
send_map_request(i);
|
send_map_request(i);
|
||||||
m_socket.async_receive_from(asio::buffer(&m_response_buffer, 16)
|
m_socket.async_receive_from(asio::buffer(&m_response_buffer, 16)
|
||||||
, m_remote, bind(&natpmp::on_reply, this, _1, _2));
|
, m_remote, bind(&natpmp::on_reply, self(), _1, _2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,9 +81,7 @@ namespace libtorrent
|
|||||||
, m_last_unchoke(min_time())
|
, m_last_unchoke(min_time())
|
||||||
, m_packet_size(0)
|
, m_packet_size(0)
|
||||||
, m_recv_pos(0)
|
, m_recv_pos(0)
|
||||||
, m_current_send_buffer(0)
|
|
||||||
, m_reading_bytes(0)
|
, m_reading_bytes(0)
|
||||||
, m_write_pos(0)
|
|
||||||
, m_last_receive(time_now())
|
, m_last_receive(time_now())
|
||||||
, m_last_sent(time_now())
|
, m_last_sent(time_now())
|
||||||
, m_socket(s)
|
, m_socket(s)
|
||||||
@ -161,9 +159,7 @@ namespace libtorrent
|
|||||||
, m_last_unchoke(min_time())
|
, m_last_unchoke(min_time())
|
||||||
, m_packet_size(0)
|
, m_packet_size(0)
|
||||||
, m_recv_pos(0)
|
, m_recv_pos(0)
|
||||||
, m_current_send_buffer(0)
|
|
||||||
, m_reading_bytes(0)
|
, m_reading_bytes(0)
|
||||||
, m_write_pos(0)
|
|
||||||
, m_last_receive(time_now())
|
, m_last_receive(time_now())
|
||||||
, m_last_sent(time_now())
|
, m_last_sent(time_now())
|
||||||
, m_socket(s)
|
, m_socket(s)
|
||||||
@ -2082,8 +2078,7 @@ namespace libtorrent
|
|||||||
p.remote_dl_rate = 0;
|
p.remote_dl_rate = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
p.send_buffer_size = int(m_send_buffer[0].capacity()
|
p.send_buffer_size = m_send_buffer.capacity();
|
||||||
+ m_send_buffer[1].capacity());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void peer_connection::cut_receive_buffer(int size, int packet_size)
|
void peer_connection::cut_receive_buffer(int size, int packet_size)
|
||||||
@ -2386,8 +2381,7 @@ namespace libtorrent
|
|||||||
shared_ptr<torrent> t = m_torrent.lock();
|
shared_ptr<torrent> t = m_torrent.lock();
|
||||||
|
|
||||||
if (m_bandwidth_limit[upload_channel].quota_left() == 0
|
if (m_bandwidth_limit[upload_channel].quota_left() == 0
|
||||||
&& (!m_send_buffer[m_current_send_buffer].empty()
|
&& !m_send_buffer.empty()
|
||||||
|| !m_send_buffer[(m_current_send_buffer + 1) & 1].empty())
|
|
||||||
&& !m_connecting
|
&& !m_connecting
|
||||||
&& t
|
&& t
|
||||||
&& !m_ignore_bandwidth_limits)
|
&& !m_ignore_bandwidth_limits)
|
||||||
@ -2415,32 +2409,21 @@ namespace libtorrent
|
|||||||
|
|
||||||
assert(!m_writing);
|
assert(!m_writing);
|
||||||
|
|
||||||
int sending_buffer = (m_current_send_buffer + 1) & 1;
|
|
||||||
if (m_send_buffer[sending_buffer].empty())
|
|
||||||
{
|
|
||||||
// this means we have to swap buffer, because there's no
|
|
||||||
// previous buffer we're still waiting for.
|
|
||||||
std::swap(m_current_send_buffer, sending_buffer);
|
|
||||||
m_write_pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// send the actual buffer
|
// send the actual buffer
|
||||||
if (!m_send_buffer[sending_buffer].empty())
|
if (!m_send_buffer.empty())
|
||||||
{
|
{
|
||||||
int amount_to_send = (int)m_send_buffer[sending_buffer].size() - m_write_pos;
|
int amount_to_send = m_send_buffer.size();
|
||||||
int quota_left = m_bandwidth_limit[upload_channel].quota_left();
|
int quota_left = m_bandwidth_limit[upload_channel].quota_left();
|
||||||
if (!m_ignore_bandwidth_limits && amount_to_send > quota_left)
|
if (!m_ignore_bandwidth_limits && amount_to_send > quota_left)
|
||||||
amount_to_send = quota_left;
|
amount_to_send = quota_left;
|
||||||
|
|
||||||
assert(amount_to_send > 0);
|
assert(amount_to_send > 0);
|
||||||
|
|
||||||
assert(m_write_pos < (int)m_send_buffer[sending_buffer].size());
|
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
(*m_logger) << "async_write " << amount_to_send << " bytes\n";
|
(*m_logger) << "async_write " << amount_to_send << " bytes\n";
|
||||||
#endif
|
#endif
|
||||||
m_socket->async_write_some(asio::buffer(
|
std::list<asio::const_buffer> const& vec = m_send_buffer.build_iovec(amount_to_send);
|
||||||
&m_send_buffer[sending_buffer][m_write_pos], amount_to_send)
|
m_socket->async_write_some(vec, bind(&peer_connection::on_send_data, self(), _1, _2));
|
||||||
, bind(&peer_connection::on_send_data, self(), _1, _2));
|
|
||||||
|
|
||||||
m_writing = true;
|
m_writing = true;
|
||||||
}
|
}
|
||||||
@ -2511,10 +2494,32 @@ namespace libtorrent
|
|||||||
m_recv_buffer.resize(m_packet_size);
|
m_recv_buffer.resize(m_packet_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void peer_connection::send_buffer(char const* begin, char const* end)
|
void peer_connection::send_buffer(char const* buf, int size)
|
||||||
{
|
{
|
||||||
buffer& buf = m_send_buffer[m_current_send_buffer];
|
int free_space = m_send_buffer.space_in_last_buffer();
|
||||||
buf.insert(buf.end(), begin, end);
|
if (free_space > size) free_space = size;
|
||||||
|
if (free_space > 0)
|
||||||
|
{
|
||||||
|
m_send_buffer.append(buf, free_space);
|
||||||
|
size -= free_space;
|
||||||
|
buf += free_space;
|
||||||
|
#ifdef TORRENT_STATS
|
||||||
|
m_ses.m_buffer_usage_logger << log_time() << " send_buffer: "
|
||||||
|
<< free_space << std::endl;
|
||||||
|
m_ses.log_buffer_usage();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (size <= 0) return;
|
||||||
|
|
||||||
|
std::pair<char*, int> buffer = m_ses.allocate_buffer(size);
|
||||||
|
assert(buffer.second >= size);
|
||||||
|
std::memcpy(buffer.first, buf, size);
|
||||||
|
m_send_buffer.append_buffer(buffer.first, buffer.second, size
|
||||||
|
, bind(&session_impl::free_buffer, boost::ref(m_ses), _1, buffer.second));
|
||||||
|
#ifdef TORRENT_STATS
|
||||||
|
m_ses.m_buffer_usage_logger << log_time() << " send_buffer_alloc: " << size << std::endl;
|
||||||
|
m_ses.log_buffer_usage();
|
||||||
|
#endif
|
||||||
setup_send();
|
setup_send();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2522,10 +2527,29 @@ namespace libtorrent
|
|||||||
// return value is destructed
|
// return value is destructed
|
||||||
buffer::interval peer_connection::allocate_send_buffer(int size)
|
buffer::interval peer_connection::allocate_send_buffer(int size)
|
||||||
{
|
{
|
||||||
buffer& buf = m_send_buffer[m_current_send_buffer];
|
char* insert = m_send_buffer.allocate_appendix(size);
|
||||||
buf.resize(buf.size() + size);
|
if (insert == 0)
|
||||||
buffer::interval ret(&buf[0] + buf.size() - size, &buf[0] + buf.size());
|
{
|
||||||
return ret;
|
std::pair<char*, int> buffer = m_ses.allocate_buffer(size);
|
||||||
|
assert(buffer.second >= size);
|
||||||
|
m_send_buffer.append_buffer(buffer.first, buffer.second, size
|
||||||
|
, bind(&session_impl::free_buffer, boost::ref(m_ses), _1, buffer.second));
|
||||||
|
buffer::interval ret(buffer.first, buffer.first + size);
|
||||||
|
#ifdef TORRENT_STATS
|
||||||
|
m_ses.m_buffer_usage_logger << log_time() << " allocate_buffer_alloc: " << size << std::endl;
|
||||||
|
m_ses.log_buffer_usage();
|
||||||
|
#endif
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef TORRENT_STATS
|
||||||
|
m_ses.m_buffer_usage_logger << log_time() << " allocate_buffer: " << size << std::endl;
|
||||||
|
m_ses.log_buffer_usage();
|
||||||
|
#endif
|
||||||
|
buffer::interval ret(insert, insert + size);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
@ -2647,8 +2671,7 @@ namespace libtorrent
|
|||||||
|
|
||||||
// if we have requests or pending data to be sent or announcements to be made
|
// if we have requests or pending data to be sent or announcements to be made
|
||||||
// we want to send data
|
// we want to send data
|
||||||
return (!m_send_buffer[m_current_send_buffer].empty()
|
return !m_send_buffer.empty()
|
||||||
|| !m_send_buffer[(m_current_send_buffer + 1) & 1].empty())
|
|
||||||
&& (m_bandwidth_limit[upload_channel].quota_left() > 0
|
&& (m_bandwidth_limit[upload_channel].quota_left() > 0
|
||||||
|| m_ignore_bandwidth_limits)
|
|| m_ignore_bandwidth_limits)
|
||||||
&& !m_connecting;
|
&& !m_connecting;
|
||||||
@ -2763,6 +2786,9 @@ namespace libtorrent
|
|||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
assert(m_writing);
|
assert(m_writing);
|
||||||
|
|
||||||
|
m_send_buffer.pop_front(bytes_transferred);
|
||||||
|
|
||||||
m_writing = false;
|
m_writing = false;
|
||||||
|
|
||||||
if (!m_ignore_bandwidth_limits)
|
if (!m_ignore_bandwidth_limits)
|
||||||
@ -2772,9 +2798,6 @@ namespace libtorrent
|
|||||||
(*m_logger) << "wrote " << bytes_transferred << " bytes\n";
|
(*m_logger) << "wrote " << bytes_transferred << " bytes\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_write_pos += bytes_transferred;
|
|
||||||
|
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
@ -2787,34 +2810,11 @@ namespace libtorrent
|
|||||||
assert(!m_connecting);
|
assert(!m_connecting);
|
||||||
assert(bytes_transferred > 0);
|
assert(bytes_transferred > 0);
|
||||||
|
|
||||||
int sending_buffer = (m_current_send_buffer + 1) & 1;
|
|
||||||
|
|
||||||
assert(int(m_send_buffer[sending_buffer].size()) >= m_write_pos);
|
|
||||||
if (int(m_send_buffer[sending_buffer].size()) == m_write_pos)
|
|
||||||
{
|
|
||||||
m_send_buffer[sending_buffer].clear();
|
|
||||||
m_write_pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_last_sent = time_now();
|
m_last_sent = time_now();
|
||||||
|
|
||||||
on_sent(error, bytes_transferred);
|
on_sent(error, bytes_transferred);
|
||||||
fill_send_buffer();
|
fill_send_buffer();
|
||||||
|
|
||||||
if (m_choked)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 2; ++i)
|
|
||||||
{
|
|
||||||
if (int(m_send_buffer[i].size()) < 64
|
|
||||||
&& int(m_send_buffer[i].capacity()) > 128)
|
|
||||||
{
|
|
||||||
buffer tmp(m_send_buffer[i]);
|
|
||||||
tmp.swap(m_send_buffer[i]);
|
|
||||||
assert(m_send_buffer[i].capacity() == m_send_buffer[i].size());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_send();
|
setup_send();
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
@ -2876,8 +2876,6 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
assert(m_write_pos <= int(m_send_buffer[
|
|
||||||
(m_current_send_buffer + 1) & 1].size()));
|
|
||||||
|
|
||||||
// extremely expensive invariant check
|
// extremely expensive invariant check
|
||||||
/*
|
/*
|
||||||
|
@ -1426,16 +1426,16 @@ namespace libtorrent
|
|||||||
int nonempty_connections = 0;
|
int nonempty_connections = 0;
|
||||||
|
|
||||||
std::set<address> unique_test;
|
std::set<address> unique_test;
|
||||||
std::set<tcp::endpoint> unique_test2;
|
// std::set<tcp::endpoint> unique_test2;
|
||||||
for (const_iterator i = m_peers.begin();
|
for (const_iterator i = m_peers.begin();
|
||||||
i != m_peers.end(); ++i)
|
i != m_peers.end(); ++i)
|
||||||
{
|
{
|
||||||
peer const& p = *i;
|
peer const& p = *i;
|
||||||
if (!m_torrent->settings().allow_multiple_connections_per_ip)
|
// if (!m_torrent->settings().allow_multiple_connections_per_ip)
|
||||||
assert(unique_test.find(p.ip.address()) == unique_test.end());
|
// assert(unique_test.find(p.ip.address()) == unique_test.end());
|
||||||
assert(unique_test2.find(p.ip) == unique_test2.end());
|
// assert(unique_test2.find(p.ip) == unique_test2.end());
|
||||||
unique_test.insert(p.ip.address());
|
// unique_test.insert(p.ip.address());
|
||||||
unique_test2.insert(p.ip);
|
// unique_test2.insert(p.ip);
|
||||||
++total_connections;
|
++total_connections;
|
||||||
if (!p.connection)
|
if (!p.connection)
|
||||||
{
|
{
|
||||||
|
@ -83,6 +83,14 @@ using libtorrent::aux::session_impl;
|
|||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
|
||||||
|
std::string log_time()
|
||||||
|
{
|
||||||
|
static const ptime start = time_now();
|
||||||
|
char ret[200];
|
||||||
|
std::sprintf(ret, "%d", total_milliseconds(time_now() - start));
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
namespace aux
|
namespace aux
|
||||||
{
|
{
|
||||||
filesystem_init::filesystem_init()
|
filesystem_init::filesystem_init()
|
||||||
|
@ -507,7 +507,8 @@ namespace detail
|
|||||||
std::pair<int, int> listen_port_range
|
std::pair<int, int> listen_port_range
|
||||||
, fingerprint const& cl_fprint
|
, fingerprint const& cl_fprint
|
||||||
, char const* listen_interface)
|
, char const* listen_interface)
|
||||||
: m_strand(m_io_service)
|
: m_send_buffers(send_buffer_size)
|
||||||
|
, m_strand(m_io_service)
|
||||||
, m_files(40)
|
, m_files(40)
|
||||||
, m_half_open(m_io_service)
|
, m_half_open(m_io_service)
|
||||||
, m_download_channel(m_io_service, peer_connection::download_channel)
|
, m_download_channel(m_io_service, peer_connection::download_channel)
|
||||||
@ -546,7 +547,7 @@ namespace detail
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TORRENT_STATS
|
#ifdef TORRENT_STATS
|
||||||
m_stats_logger.open("session_stats.log");
|
m_stats_logger.open("session_stats.log", std::ios::trunc);
|
||||||
m_stats_logger <<
|
m_stats_logger <<
|
||||||
"1. second\n"
|
"1. second\n"
|
||||||
"2. upload rate\n"
|
"2. upload rate\n"
|
||||||
@ -555,7 +556,9 @@ namespace detail
|
|||||||
"5. seeding torrents\n"
|
"5. seeding torrents\n"
|
||||||
"6. peers\n"
|
"6. peers\n"
|
||||||
"7. connecting peers\n"
|
"7. connecting peers\n"
|
||||||
|
"8. disk block buffers\n"
|
||||||
"\n";
|
"\n";
|
||||||
|
m_buffer_usage_logger.open("buffer_stats.log", std::ios::trunc);
|
||||||
m_second_counter = 0;
|
m_second_counter = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -999,7 +1002,8 @@ namespace detail
|
|||||||
{
|
{
|
||||||
session_impl::mutex_t::scoped_lock l(m_mutex);
|
session_impl::mutex_t::scoped_lock l(m_mutex);
|
||||||
|
|
||||||
INVARIANT_CHECK;
|
// too expensive
|
||||||
|
// INVARIANT_CHECK;
|
||||||
|
|
||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
@ -1031,7 +1035,7 @@ namespace detail
|
|||||||
else
|
else
|
||||||
++downloading_torrents;
|
++downloading_torrents;
|
||||||
}
|
}
|
||||||
int num_connections = 0;
|
int num_complete_connections = 0;
|
||||||
int num_half_open = 0;
|
int num_half_open = 0;
|
||||||
for (connection_map::iterator i = m_connections.begin()
|
for (connection_map::iterator i = m_connections.begin()
|
||||||
, end(m_connections.end()); i != end; ++i)
|
, end(m_connections.end()); i != end; ++i)
|
||||||
@ -1039,7 +1043,7 @@ namespace detail
|
|||||||
if (i->second->is_connecting())
|
if (i->second->is_connecting())
|
||||||
++num_half_open;
|
++num_half_open;
|
||||||
else
|
else
|
||||||
++num_connections;
|
++num_complete_connections;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stats_logger
|
m_stats_logger
|
||||||
@ -1048,8 +1052,9 @@ namespace detail
|
|||||||
<< m_stat.download_rate() << "\t"
|
<< m_stat.download_rate() << "\t"
|
||||||
<< downloading_torrents << "\t"
|
<< downloading_torrents << "\t"
|
||||||
<< seeding_torrents << "\t"
|
<< seeding_torrents << "\t"
|
||||||
<< num_connections << "\t"
|
<< num_complete_connections << "\t"
|
||||||
<< num_half_open << "\t"
|
<< num_half_open << "\t"
|
||||||
|
<< m_disk_thread.disk_allocations() << "\t"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -2195,9 +2200,9 @@ namespace detail
|
|||||||
|
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
m_lsd.reset(new lsd(m_io_service
|
m_lsd = new lsd(m_io_service
|
||||||
, m_listen_interface.address()
|
, m_listen_interface.address()
|
||||||
, bind(&session_impl::on_lsd_peer, this, _1, _2)));
|
, bind(&session_impl::on_lsd_peer, this, _1, _2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_impl::start_natpmp()
|
void session_impl::start_natpmp()
|
||||||
@ -2206,10 +2211,10 @@ namespace detail
|
|||||||
|
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
m_natpmp.reset(new natpmp(m_io_service
|
m_natpmp = new natpmp(m_io_service
|
||||||
, m_listen_interface.address()
|
, m_listen_interface.address()
|
||||||
, bind(&session_impl::on_port_mapping
|
, bind(&session_impl::on_port_mapping
|
||||||
, this, _1, _2, _3)));
|
, this, _1, _2, _3));
|
||||||
|
|
||||||
m_natpmp->set_mappings(m_listen_interface.port(),
|
m_natpmp->set_mappings(m_listen_interface.port(),
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
@ -2224,11 +2229,11 @@ namespace detail
|
|||||||
|
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
m_upnp.reset(new upnp(m_io_service, m_half_open
|
m_upnp = new upnp(m_io_service, m_half_open
|
||||||
, m_listen_interface.address()
|
, m_listen_interface.address()
|
||||||
, m_settings.user_agent
|
, m_settings.user_agent
|
||||||
, bind(&session_impl::on_port_mapping
|
, bind(&session_impl::on_port_mapping
|
||||||
, this, _1, _2, _3)));
|
, this, _1, _2, _3));
|
||||||
|
|
||||||
m_upnp->set_mappings(m_listen_interface.port(),
|
m_upnp->set_mappings(m_listen_interface.port(),
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
@ -2240,7 +2245,7 @@ namespace detail
|
|||||||
void session_impl::stop_lsd()
|
void session_impl::stop_lsd()
|
||||||
{
|
{
|
||||||
mutex_t::scoped_lock l(m_mutex);
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
m_lsd.reset();
|
m_lsd = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_impl::stop_natpmp()
|
void session_impl::stop_natpmp()
|
||||||
@ -2248,7 +2253,7 @@ namespace detail
|
|||||||
mutex_t::scoped_lock l(m_mutex);
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
if (m_natpmp.get())
|
if (m_natpmp.get())
|
||||||
m_natpmp->close();
|
m_natpmp->close();
|
||||||
m_natpmp.reset();
|
m_natpmp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_impl::stop_upnp()
|
void session_impl::stop_upnp()
|
||||||
@ -2256,9 +2261,38 @@ namespace detail
|
|||||||
mutex_t::scoped_lock l(m_mutex);
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
if (m_upnp.get())
|
if (m_upnp.get())
|
||||||
m_upnp->close();
|
m_upnp->close();
|
||||||
m_upnp.reset();
|
m_upnp = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void session_impl::free_disk_buffer(char* buf)
|
||||||
|
{
|
||||||
|
m_disk_thread.free_buffer(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<char*, int> session_impl::allocate_buffer(int size)
|
||||||
|
{
|
||||||
|
int num_buffers = (size + send_buffer_size - 1) / send_buffer_size;
|
||||||
|
#ifdef TORRENT_STATS
|
||||||
|
m_buffer_allocations += num_buffers;
|
||||||
|
m_buffer_usage_logger << log_time() << " protocol_buffer: "
|
||||||
|
<< (m_buffer_allocations * send_buffer_size) << std::endl;
|
||||||
|
#endif
|
||||||
|
return std::make_pair((char*)m_send_buffers.ordered_malloc(num_buffers)
|
||||||
|
, num_buffers * send_buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void session_impl::free_buffer(char* buf, int size)
|
||||||
|
{
|
||||||
|
assert(size % send_buffer_size == 0);
|
||||||
|
int num_buffers = size / send_buffer_size;
|
||||||
|
#ifdef TORRENT_STATS
|
||||||
|
m_buffer_allocations -= num_buffers;
|
||||||
|
assert(m_buffer_allocations >= 0);
|
||||||
|
m_buffer_usage_logger << log_time() << " protocol_buffer: "
|
||||||
|
<< (m_buffer_allocations * send_buffer_size) << std::endl;
|
||||||
|
#endif
|
||||||
|
m_send_buffers.ordered_free(buf, num_buffers);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void session_impl::check_invariant() const
|
void session_impl::check_invariant() const
|
||||||
|
@ -1065,6 +1065,11 @@ namespace libtorrent
|
|||||||
return m_storage->verify_resume_data(rd, error);
|
return m_storage->verify_resume_data(rd, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void piece_manager::free_buffer(char* buf)
|
||||||
|
{
|
||||||
|
m_io_thread.free_buffer(buf);
|
||||||
|
}
|
||||||
|
|
||||||
void piece_manager::async_release_files(
|
void piece_manager::async_release_files(
|
||||||
boost::function<void(int, disk_io_job const&)> const& handler)
|
boost::function<void(int, disk_io_job const&)> const& handler)
|
||||||
{
|
{
|
||||||
|
@ -1464,9 +1464,6 @@ namespace libtorrent
|
|||||||
m_policy->connection_closed(*p);
|
m_policy->connection_closed(*p);
|
||||||
p->set_peer_info(0);
|
p->set_peer_info(0);
|
||||||
m_connections.erase(i);
|
m_connections.erase(i);
|
||||||
#ifndef NDEBUG
|
|
||||||
m_policy->check_invariant();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
@ -2940,4 +2937,3 @@ namespace libtorrent
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -901,4 +901,3 @@ namespace libtorrent
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ upnp::upnp(io_service& ios, connection_queue& cc
|
|||||||
, m_io_service(ios)
|
, m_io_service(ios)
|
||||||
, m_strand(ios)
|
, m_strand(ios)
|
||||||
, m_socket(ios, udp::endpoint(address_v4::from_string("239.255.255.250"), 1900)
|
, m_socket(ios, udp::endpoint(address_v4::from_string("239.255.255.250"), 1900)
|
||||||
, m_strand.wrap(bind(&upnp::on_reply, this, _1, _2, _3)), false)
|
, m_strand.wrap(bind(&upnp::on_reply, self(), _1, _2, _3)), false)
|
||||||
, m_broadcast_timer(ios)
|
, m_broadcast_timer(ios)
|
||||||
, m_refresh_timer(ios)
|
, m_refresh_timer(ios)
|
||||||
, m_disabled(false)
|
, m_disabled(false)
|
||||||
@ -119,7 +119,7 @@ void upnp::discover_device() try
|
|||||||
++m_retry_count;
|
++m_retry_count;
|
||||||
m_broadcast_timer.expires_from_now(milliseconds(250 * m_retry_count));
|
m_broadcast_timer.expires_from_now(milliseconds(250 * m_retry_count));
|
||||||
m_broadcast_timer.async_wait(m_strand.wrap(bind(&upnp::resend_request
|
m_broadcast_timer.async_wait(m_strand.wrap(bind(&upnp::resend_request
|
||||||
, this, _1)));
|
, self(), _1)));
|
||||||
|
|
||||||
#ifdef TORRENT_UPNP_LOGGING
|
#ifdef TORRENT_UPNP_LOGGING
|
||||||
m_log << time_now_string()
|
m_log << time_now_string()
|
||||||
@ -203,7 +203,7 @@ try
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
d.upnp_connection.reset(new http_connection(m_io_service
|
d.upnp_connection.reset(new http_connection(m_io_service
|
||||||
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_xml, this, _1, _2
|
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_xml, self(), _1, _2
|
||||||
, boost::ref(d)))));
|
, boost::ref(d)))));
|
||||||
d.upnp_connection->get(d.url);
|
d.upnp_connection->get(d.url);
|
||||||
}
|
}
|
||||||
@ -300,7 +300,7 @@ try
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string url = p.header<std::string>("location");
|
std::string url = p.header("location");
|
||||||
if (url.empty())
|
if (url.empty())
|
||||||
{
|
{
|
||||||
#ifdef TORRENT_UPNP_LOGGING
|
#ifdef TORRENT_UPNP_LOGGING
|
||||||
@ -393,7 +393,7 @@ try
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
d.upnp_connection.reset(new http_connection(m_io_service
|
d.upnp_connection.reset(new http_connection(m_io_service
|
||||||
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_xml, this, _1, _2
|
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_xml, self(), _1, _2
|
||||||
, boost::ref(d)))));
|
, boost::ref(d)))));
|
||||||
d.upnp_connection->get(d.url);
|
d.upnp_connection->get(d.url);
|
||||||
}
|
}
|
||||||
@ -480,9 +480,9 @@ void upnp::map_port(rootdevice& d, int i)
|
|||||||
assert(d.service_namespace);
|
assert(d.service_namespace);
|
||||||
|
|
||||||
d.upnp_connection.reset(new http_connection(m_io_service
|
d.upnp_connection.reset(new http_connection(m_io_service
|
||||||
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_map_response, this, _1, _2
|
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_map_response, self(), _1, _2
|
||||||
, boost::ref(d), i)), true
|
, boost::ref(d), i)), true
|
||||||
, bind(&upnp::create_port_mapping, this, _1, boost::ref(d), i)));
|
, bind(&upnp::create_port_mapping, self(), _1, boost::ref(d), i)));
|
||||||
|
|
||||||
d.upnp_connection->start(d.hostname, boost::lexical_cast<std::string>(d.port)
|
d.upnp_connection->start(d.hostname, boost::lexical_cast<std::string>(d.port)
|
||||||
, seconds(10));
|
, seconds(10));
|
||||||
@ -523,9 +523,9 @@ void upnp::unmap_port(rootdevice& d, int i)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
d.upnp_connection.reset(new http_connection(m_io_service
|
d.upnp_connection.reset(new http_connection(m_io_service
|
||||||
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_unmap_response, this, _1, _2
|
, m_cc, m_strand.wrap(bind(&upnp::on_upnp_unmap_response, self(), _1, _2
|
||||||
, boost::ref(d), i)), true
|
, boost::ref(d), i)), true
|
||||||
, bind(&upnp::delete_port_mapping, this, boost::ref(d), i)));
|
, bind(&upnp::delete_port_mapping, self(), boost::ref(d), i)));
|
||||||
|
|
||||||
d.upnp_connection->start(d.hostname, boost::lexical_cast<std::string>(d.port)
|
d.upnp_connection->start(d.hostname, boost::lexical_cast<std::string>(d.port)
|
||||||
, seconds(10));
|
, seconds(10));
|
||||||
@ -851,7 +851,7 @@ void upnp::on_upnp_map_response(asio::error_code const& e
|
|||||||
|| next_expire > d.mapping[mapping].expires)
|
|| next_expire > d.mapping[mapping].expires)
|
||||||
{
|
{
|
||||||
m_refresh_timer.expires_at(d.mapping[mapping].expires);
|
m_refresh_timer.expires_at(d.mapping[mapping].expires);
|
||||||
m_refresh_timer.async_wait(m_strand.wrap(bind(&upnp::on_expire, this, _1)));
|
m_refresh_timer.async_wait(m_strand.wrap(bind(&upnp::on_expire, self(), _1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -962,7 +962,7 @@ void upnp::on_expire(asio::error_code const& e) try
|
|||||||
if (next_expire != max_time())
|
if (next_expire != max_time())
|
||||||
{
|
{
|
||||||
m_refresh_timer.expires_at(next_expire);
|
m_refresh_timer.expires_at(next_expire);
|
||||||
m_refresh_timer.async_wait(m_strand.wrap(bind(&upnp::on_expire, this, _1)));
|
m_refresh_timer.async_wait(m_strand.wrap(bind(&upnp::on_expire, self(), _1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception&)
|
catch (std::exception&)
|
||||||
|
@ -297,7 +297,7 @@ namespace libtorrent
|
|||||||
(*m_logger) << request << "\n";
|
(*m_logger) << request << "\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
send_buffer(request.c_str(), request.c_str() + request.size());
|
send_buffer(request.c_str(), request.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------
|
// --------------------------
|
||||||
@ -387,7 +387,7 @@ namespace libtorrent
|
|||||||
{
|
{
|
||||||
// this means we got a redirection request
|
// this means we got a redirection request
|
||||||
// look for the location header
|
// look for the location header
|
||||||
std::string location = m_parser.header<std::string>("location");
|
std::string location = m_parser.header("location");
|
||||||
|
|
||||||
if (location.empty())
|
if (location.empty())
|
||||||
{
|
{
|
||||||
@ -423,7 +423,7 @@ namespace libtorrent
|
|||||||
throw std::runtime_error("redirecting to " + location);
|
throw std::runtime_error("redirecting to " + location);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string server_version = m_parser.header<std::string>("server");
|
std::string const& server_version = m_parser.header("server");
|
||||||
if (!server_version.empty())
|
if (!server_version.empty())
|
||||||
{
|
{
|
||||||
m_server_string = "URL seed @ ";
|
m_server_string = "URL seed @ ";
|
||||||
@ -445,7 +445,7 @@ namespace libtorrent
|
|||||||
size_type range_end;
|
size_type range_end;
|
||||||
if (m_parser.status_code() == 206)
|
if (m_parser.status_code() == 206)
|
||||||
{
|
{
|
||||||
std::stringstream range_str(m_parser.header<std::string>("content-range"));
|
std::stringstream range_str(m_parser.header("content-range"));
|
||||||
char dummy;
|
char dummy;
|
||||||
std::string bytes;
|
std::string bytes;
|
||||||
range_str >> bytes >> range_start >> dummy >> range_end;
|
range_str >> bytes >> range_start >> dummy >> range_end;
|
||||||
@ -461,7 +461,7 @@ namespace libtorrent
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
range_start = 0;
|
range_start = 0;
|
||||||
range_end = m_parser.header<size_type>("content-length");
|
range_end = atol(m_parser.header("content-length").c_str());
|
||||||
if (range_end == -1)
|
if (range_end == -1)
|
||||||
{
|
{
|
||||||
// we should not try this server again.
|
// we should not try this server again.
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
plugin_name = _("Move Torrent")
|
plugin_name = _("Move Torrent")
|
||||||
plugin_author = "Marcos Pinto"
|
plugin_author = "Marcos Pinto"
|
||||||
plugin_version = "0.1"
|
plugin_version = "0.2"
|
||||||
plugin_description = _("This plugin allows users to move the torrent to a \
|
plugin_description = _("This plugin allows users to move the torrent to a \
|
||||||
different directory without having to remove and re-add the torrent. This \
|
different directory without having to remove and re-add the torrent. This \
|
||||||
feature can be found by right-clicking on a torrent.\nFurthermore, it \
|
feature can be found by right-clicking on a torrent.\nFurthermore, it \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user