Allocate memory for read/write handlers inplace inside peer_connection instance.

This commit is contained in:
Daniel Wallin 2009-05-20 08:57:08 +00:00
parent 98ee6daddc
commit 6014ac1e7a
3 changed files with 105 additions and 5 deletions

View File

@ -138,6 +138,13 @@ POSSIBILITY OF SUCH DAMAGE.
#define TORRENT_USE_LOCALE_FILENAMES 0
#endif
#if !defined(TORRENT_READ_HANDLER_MAX_SIZE)
# define TORRENT_READ_HANDLER_MAX_SIZE 100
#endif
#if !defined(TORRENT_WRITE_HANDLER_MAX_SIZE)
# define TORRENT_WRITE_HANDLER_MAX_SIZE 100
#endif
#endif // TORRENT_CONFIG_HPP_INCLUDED

View File

@ -985,6 +985,91 @@ namespace libtorrent
// pick any pieces from this peer
bool m_no_download:1;
template <std::size_t Size>
struct handler_storage
{
#ifdef TORRENT_DEBUG
handler_storage()
: used(false)
{}
bool used;
#endif
boost::aligned_storage<Size> bytes;
};
handler_storage<TORRENT_READ_HANDLER_MAX_SIZE> m_read_handler_storage;
handler_storage<TORRENT_WRITE_HANDLER_MAX_SIZE> m_write_handler_storage;
template <class Handler, std::size_t Size>
struct allocating_handler
{
allocating_handler(
Handler const& handler, handler_storage<Size>& storage
)
: handler(handler)
, storage(storage)
{}
template <class A0>
void operator()(A0 const& a0) const
{
handler(a0);
}
template <class A0, class A1>
void operator()(A0 const& a0, A1 const& a1) const
{
handler(a0, a1);
}
template <class A0, class A1, class A2>
void operator()(A0 const& a0, A1 const& a1, A2 const& a2) const
{
handler(a0, a1, a2);
}
friend void* asio_handler_allocate(
std::size_t size, allocating_handler<Handler, Size>* ctx)
{
assert(size <= Size);
#ifdef TORRENT_DEBUG
assert(!ctx->storage.used);
ctx->storage.used = true;
#endif
return &ctx->storage.bytes;
}
friend void asio_handler_deallocate(
void*, std::size_t, allocating_handler<Handler, Size>* ctx)
{
#ifdef TORRENT_DEBUG
ctx->storage.used = false;
#endif
}
Handler handler;
handler_storage<Size>& storage;
};
template <class Handler>
allocating_handler<Handler, TORRENT_READ_HANDLER_MAX_SIZE>
make_read_handler(Handler const& handler)
{
return allocating_handler<Handler, TORRENT_READ_HANDLER_MAX_SIZE>(
handler, m_read_handler_storage
);
}
template <class Handler>
allocating_handler<Handler, TORRENT_WRITE_HANDLER_MAX_SIZE>
make_write_handler(Handler const& handler)
{
return allocating_handler<Handler, TORRENT_WRITE_HANDLER_MAX_SIZE>(
handler, m_write_handler_storage
);
}
#ifdef TORRENT_DEBUG
public:
bool m_in_constructor:1;

View File

@ -3680,7 +3680,9 @@ namespace libtorrent
(*m_logger) << time_now_string() << " *** ASYNC_WRITE [ bytes: " << amount_to_send << " ]\n";
#endif
std::list<asio::const_buffer> const& vec = m_send_buffer.build_iovec(amount_to_send);
m_socket->async_write_some(vec, bind(&peer_connection::on_send_data, self(), _1, _2));
m_socket->async_write_some(
vec, make_write_handler(bind(
&peer_connection::on_send_data, self(), _1, _2)));
m_channel_state[upload_channel] = peer_info::bw_network;
}
@ -3763,7 +3765,10 @@ namespace libtorrent
// only receive into regular buffer
TORRENT_ASSERT(m_recv_pos + max_receive <= int(m_recv_buffer.size()));
m_socket->async_read_some(asio::buffer(&m_recv_buffer[m_recv_pos]
, max_receive), bind(&peer_connection::on_receive_data, self(), _1, _2));
, max_receive)
, make_read_handler(
bind(&peer_connection::on_receive_data, self(), _1, _2)
));
}
else if (m_recv_pos >= regular_buffer_size)
{
@ -3772,7 +3777,9 @@ namespace libtorrent
TORRENT_ASSERT(m_recv_pos - regular_buffer_size + max_receive <= m_disk_recv_buffer_size);
m_socket->async_read_some(asio::buffer(m_disk_recv_buffer.get() + m_recv_pos - regular_buffer_size
, max_receive)
, bind(&peer_connection::on_receive_data, self(), _1, _2));
, make_read_handler(
bind(&peer_connection::on_receive_data, self(), _1, _2)
));
}
else
{
@ -3787,8 +3794,9 @@ namespace libtorrent
, regular_buffer_size - m_recv_pos);
vec[1] = asio::buffer(m_disk_recv_buffer.get()
, max_receive - regular_buffer_size + m_recv_pos);
m_socket->async_read_some(vec, bind(&peer_connection::on_receive_data
, self(), _1, _2));
m_socket->async_read_some(
vec, make_read_handler(
bind(&peer_connection::on_receive_data, self(), _1, _2)));
}
m_channel_state[download_channel] = peer_info::bw_network;
}