From 1b470e0961091080cf25e0390a84ca52294e7b70 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Sat, 13 Aug 2011 23:01:38 +0000 Subject: [PATCH] move the code of chained buffer out to its own cpp file --- CMakeLists.txt | 1 + Jamfile | 1 + include/libtorrent/chained_buffer.hpp | 113 +++--------------- src/Makefile.am | 1 + src/chained_buffer.cpp | 159 ++++++++++++++++++++++++++ 5 files changed, 180 insertions(+), 95 deletions(-) create mode 100644 src/chained_buffer.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d62603d6a..ce6e97247 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,7 @@ set(sources bandwidth_manager bandwidth_queue_entry bloom_filter + chained_buffer connection_queue create_torrent disk_buffer_holder diff --git a/Jamfile b/Jamfile index c9d40adea..e10e24b19 100755 --- a/Jamfile +++ b/Jamfile @@ -390,6 +390,7 @@ SOURCES = bandwidth_manager bandwidth_queue_entry bloom_filter + chained_buffer connection_queue create_torrent disk_buffer_holder diff --git a/include/libtorrent/chained_buffer.hpp b/include/libtorrent/chained_buffer.hpp index acfb26fa2..46e34e01f 100644 --- a/include/libtorrent/chained_buffer.hpp +++ b/include/libtorrent/chained_buffer.hpp @@ -50,7 +50,12 @@ namespace libtorrent #endif struct chained_buffer { - chained_buffer(): m_bytes(0), m_capacity(0) {} + chained_buffer(): m_bytes(0), m_capacity(0) + { +#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS + m_destructed = false; +#endif + } struct buffer_t { @@ -66,114 +71,28 @@ namespace libtorrent int size() const { return m_bytes; } int capacity() const { return m_capacity; } - void pop_front(int bytes_to_pop) - { - TORRENT_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; - TORRENT_ASSERT(m_bytes <= m_capacity); - TORRENT_ASSERT(m_bytes >= 0); - TORRENT_ASSERT(m_capacity >= 0); - break; - } + void pop_front(int bytes_to_pop); - b.free(b.buf); - m_bytes -= b.used_size; - m_capacity -= b.size; - bytes_to_pop -= b.used_size; - TORRENT_ASSERT(m_bytes >= 0); - TORRENT_ASSERT(m_capacity >= 0); - TORRENT_ASSERT(m_bytes <= m_capacity); - m_vec.pop_front(); - } - } - - template - void append_buffer(char* buffer, int s, int used_size, D const& destructor) - { - TORRENT_ASSERT(s >= used_size); - buffer_t b; - b.buf = buffer; - b.size = s; - b.start = buffer; - b.used_size = used_size; - b.free = destructor; - m_vec.push_back(b); - - m_bytes += used_size; - m_capacity += s; - TORRENT_ASSERT(m_bytes <= m_capacity); - } + void append_buffer(char* buffer, int s, int used_size + , boost::function const& destructor); // 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); - } + int space_in_last_buffer(); // tries to copy the given buffer to the end of the // last chained buffer. If there's not enough room // it returns false - char* append(char const* buf, int s) - { - char* insert = allocate_appendix(s); - if (insert == 0) return 0; - memcpy(insert, buf, s); - return insert; - } + char* append(char const* buf, int s); // tries to allocate memory from the end // of the last buffer. If there isn't // enough room, returns 0 - char* allocate_appendix(int s) - { - if (m_vec.empty()) return 0; - buffer_t& b = m_vec.back(); - char* insert = b.start + b.used_size; - if (insert + s > b.buf + b.size) return 0; - b.used_size += s; - m_bytes += s; - TORRENT_ASSERT(m_bytes <= m_capacity); - return insert; - } + char* allocate_appendix(int s); - std::list const& build_iovec(int to_send) - { - m_tmp_vec.clear(); + std::list const& build_iovec(int to_send); - for (std::list::iterator i = m_vec.begin() - , end(m_vec.end()); to_send > 0 && i != end; ++i) - { - if (i->used_size > to_send) - { - TORRENT_ASSERT(to_send > 0); - m_tmp_vec.push_back(asio::const_buffer(i->start, to_send)); - break; - } - TORRENT_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::iterator i = m_vec.begin() - , end(m_vec.end()); i != end; ++i) - { - i->free(i->buf); - } - } + ~chained_buffer(); private: @@ -193,6 +112,10 @@ namespace libtorrent // this is the vector of buffers used when // invoking the async write call std::list m_tmp_vec; + +#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS + bool m_destructed; +#endif }; } diff --git a/src/Makefile.am b/src/Makefile.am index 30c8e2471..0ac812152 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -27,6 +27,7 @@ libtorrent_rasterbar_la_SOURCES = \ bloom_filter.cpp \ broadcast_socket.cpp \ bt_peer_connection.cpp \ + chained_buffer.cpp \ connection_queue.cpp \ ConvertUTF.cpp \ create_torrent.cpp \ diff --git a/src/chained_buffer.cpp b/src/chained_buffer.cpp new file mode 100644 index 000000000..9750daebf --- /dev/null +++ b/src/chained_buffer.cpp @@ -0,0 +1,159 @@ +/* + +Copyright (c) 2007-2011, 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. + +*/ + +#include "libtorrent/chained_buffer.hpp" +#include "libtorrent/assert.hpp" + +namespace libtorrent +{ + void chained_buffer::pop_front(int bytes_to_pop) + { + TORRENT_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; + TORRENT_ASSERT(m_bytes <= m_capacity); + TORRENT_ASSERT(m_bytes >= 0); + TORRENT_ASSERT(m_capacity >= 0); + break; + } + + b.free(b.buf); + m_bytes -= b.used_size; + m_capacity -= b.size; + bytes_to_pop -= b.used_size; + TORRENT_ASSERT(m_bytes >= 0); + TORRENT_ASSERT(m_capacity >= 0); + TORRENT_ASSERT(m_bytes <= m_capacity); + m_vec.pop_front(); + } + } + + void chained_buffer::append_buffer(char* buffer, int s, int used_size + , boost::function const& destructor) + { + TORRENT_ASSERT(s >= used_size); + buffer_t b; + b.buf = buffer; + b.size = s; + b.start = buffer; + b.used_size = used_size; + b.free = destructor; + m_vec.push_back(b); + + m_bytes += used_size; + m_capacity += s; + TORRENT_ASSERT(m_bytes <= m_capacity); + } + + // returns the number of bytes available at the + // end of the last chained buffer. + int chained_buffer::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 + char* chained_buffer::append(char const* buf, int s) + { + char* insert = allocate_appendix(s); + if (insert == 0) return 0; + memcpy(insert, buf, s); + return insert; + } + + // tries to allocate memory from the end + // of the last buffer. If there isn't + // enough room, returns 0 + char* chained_buffer::allocate_appendix(int s) + { + if (m_vec.empty()) return 0; + buffer_t& b = m_vec.back(); + char* insert = b.start + b.used_size; + if (insert + s > b.buf + b.size) return 0; + b.used_size += s; + m_bytes += s; + TORRENT_ASSERT(m_bytes <= m_capacity); + return insert; + } + + std::list const& chained_buffer::build_iovec(int to_send) + { + m_tmp_vec.clear(); + + for (std::list::iterator i = m_vec.begin() + , end(m_vec.end()); to_send > 0 && i != end; ++i) + { + if (i->used_size > to_send) + { + TORRENT_ASSERT(to_send > 0); + m_tmp_vec.push_back(asio::const_buffer(i->start, to_send)); + break; + } + TORRENT_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::~chained_buffer() + { +#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS + TORRENT_ASSERT(!m_destructed); + m_destructed = true; +#endif + TORRENT_ASSERT(m_bytes >= 0); + TORRENT_ASSERT(m_capacity >= 0); + for (std::list::iterator i = m_vec.begin() + , end(m_vec.end()); i != end; ++i) + { + i->free(i->buf); + } +#ifdef TORRENT_DEBUG + m_bytes = -1; + m_capacity = -1; + m_vec.clear(); +#endif + } + +}; +