honor IOV_MAX when using writev and readv
This commit is contained in:
parent
bc1e47a486
commit
43c9e640ab
|
@ -90,6 +90,7 @@
|
||||||
incoming connection
|
incoming connection
|
||||||
* added more detailed instrumentation of the disk I/O thread
|
* added more detailed instrumentation of the disk I/O thread
|
||||||
|
|
||||||
|
* honor IOV_MAX when using writev and readv
|
||||||
* don't post 'operation aborted' UDP errors when changing listen port
|
* don't post 'operation aborted' UDP errors when changing listen port
|
||||||
* fix tracker retry logic, where in some configurations the next tier would not be tried
|
* fix tracker retry logic, where in some configurations the next tier would not be tried
|
||||||
* fixed bug in http seeding logic (introduced in 0.15.7)
|
* fixed bug in http seeding logic (introduced in 0.15.7)
|
||||||
|
@ -98,7 +99,7 @@
|
||||||
* add reset_piece_deadline function
|
* add reset_piece_deadline function
|
||||||
* fix merkle tree torrent assert
|
* fix merkle tree torrent assert
|
||||||
|
|
||||||
0.15.67 release
|
0.15.7 release
|
||||||
|
|
||||||
* exposed set_peer_id to python binding
|
* exposed set_peer_id to python binding
|
||||||
* improve support for merkle tree torrent creation
|
* improve support for merkle tree torrent creation
|
||||||
|
|
|
@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include <boost/version.hpp>
|
#include <boost/version.hpp>
|
||||||
#include <stdio.h> // for snprintf
|
#include <stdio.h> // for snprintf
|
||||||
|
#include <limits.h> // for IOV_MAX
|
||||||
|
|
||||||
#if defined TORRENT_DEBUG_BUFFERS && !defined TORRENT_DISABLE_POOL_ALLOCATOR
|
#if defined TORRENT_DEBUG_BUFFERS && !defined TORRENT_DISABLE_POOL_ALLOCATOR
|
||||||
#error TORRENT_DEBUG_BUFFERS only works if you also disable pool allocators
|
#error TORRENT_DEBUG_BUFFERS only works if you also disable pool allocators
|
||||||
|
@ -393,6 +394,14 @@ inline int snprintf(char* buf, int len, char const* fmt, ...)
|
||||||
#define TORRENT_HAS_STRDUP 1
|
#define TORRENT_HAS_STRDUP 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !defined TORRENT_IOV_MAX
|
||||||
|
#ifdef IOV_MAX
|
||||||
|
#define TORRENT_IOV_MAX IOV_MAX
|
||||||
|
#else
|
||||||
|
#define TORRENT_IOV_MAX INT_MAX
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if !defined(TORRENT_READ_HANDLER_MAX_SIZE)
|
#if !defined(TORRENT_READ_HANDLER_MAX_SIZE)
|
||||||
# define TORRENT_READ_HANDLER_MAX_SIZE 256
|
# define TORRENT_READ_HANDLER_MAX_SIZE 256
|
||||||
#endif
|
#endif
|
||||||
|
|
156
src/file.cpp
156
src/file.cpp
|
@ -1182,40 +1182,54 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
#if TORRENT_USE_READV
|
#if TORRENT_USE_READV
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
while (num_bufs > 0)
|
||||||
|
{
|
||||||
|
int nbufs = (std::min)(num_bufs, TORRENT_IOV_MAX);
|
||||||
|
int tmp_ret = 0;
|
||||||
#ifdef TORRENT_LINUX
|
#ifdef TORRENT_LINUX
|
||||||
bool aligned = false;
|
bool aligned = false;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
// if we're not opened in no-buffer mode, we don't need alignment
|
// if we're not opened in no-buffer mode, we don't need alignment
|
||||||
if ((m_open_mode & no_buffer) == 0) aligned = true;
|
if ((m_open_mode & no_buffer) == 0) aligned = true;
|
||||||
if (!aligned)
|
if (!aligned)
|
||||||
{
|
|
||||||
size = bufs_size(bufs, num_bufs);
|
|
||||||
if ((size & (size_alignment()-1)) == 0) aligned = true;
|
|
||||||
}
|
|
||||||
if (aligned)
|
|
||||||
#endif // TORRENT_LINUX
|
|
||||||
{
|
|
||||||
ret = ::readv(m_fd, bufs, num_bufs);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
{
|
||||||
ec.assign(errno, get_posix_category());
|
size = bufs_size(bufs, nbufs);
|
||||||
return -1;
|
if ((size & (size_alignment()-1)) == 0) aligned = true;
|
||||||
}
|
}
|
||||||
return ret;
|
if (aligned)
|
||||||
}
|
|
||||||
#ifdef TORRENT_LINUX
|
|
||||||
file::iovec_t* temp_bufs = TORRENT_ALLOCA(file::iovec_t, num_bufs);
|
|
||||||
memcpy(temp_bufs, bufs, sizeof(file::iovec_t) * num_bufs);
|
|
||||||
iovec_t& last = temp_bufs[num_bufs-1];
|
|
||||||
last.iov_len = (last.iov_len & ~(size_alignment()-1)) + m_page_size;
|
|
||||||
ret = ::readv(m_fd, temp_bufs, num_bufs);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
|
||||||
ec.assign(errno, get_posix_category());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return (std::min)(ret, size_type(size));
|
|
||||||
#endif // TORRENT_LINUX
|
#endif // TORRENT_LINUX
|
||||||
|
{
|
||||||
|
tmp_ret = ::readv(m_fd, bufs, nbufs);
|
||||||
|
if (tmp_ret < 0)
|
||||||
|
{
|
||||||
|
ec.assign(errno, get_posix_category());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ret += tmp_ret;
|
||||||
|
}
|
||||||
|
#ifdef TORRENT_LINUX
|
||||||
|
else
|
||||||
|
{
|
||||||
|
file::iovec_t* temp_bufs = TORRENT_ALLOCA(file::iovec_t, nbufs);
|
||||||
|
memcpy(temp_bufs, bufs, sizeof(file::iovec_t) * nbufs);
|
||||||
|
iovec_t& last = temp_bufs[nbufs-1];
|
||||||
|
last.iov_len = (last.iov_len & ~(size_alignment()-1)) + m_page_size;
|
||||||
|
tmp_ret = ::readv(m_fd, temp_bufs, nbufs);
|
||||||
|
if (tmp_ret < 0)
|
||||||
|
{
|
||||||
|
ec.assign(errno, get_posix_category());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ret += (std::min)(tmp_ret, size_type(size));
|
||||||
|
}
|
||||||
|
#endif // TORRENT_LINUX
|
||||||
|
|
||||||
|
num_bufs -= nbufs;
|
||||||
|
bufs += nbufs;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
#else // TORRENT_USE_READV
|
#else // TORRENT_USE_READV
|
||||||
|
|
||||||
|
@ -1412,46 +1426,60 @@ namespace libtorrent
|
||||||
|
|
||||||
#if TORRENT_USE_WRITEV
|
#if TORRENT_USE_WRITEV
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
|
while (num_bufs > 0)
|
||||||
|
{
|
||||||
|
int nbufs = (std::min)(num_bufs, TORRENT_IOV_MAX);
|
||||||
|
int tmp_ret = 0;
|
||||||
#ifdef TORRENT_LINUX
|
#ifdef TORRENT_LINUX
|
||||||
bool aligned = false;
|
bool aligned = false;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
// if we're not opened in no-buffer mode, we don't need alignment
|
// if we're not opened in no-buffer mode, we don't need alignment
|
||||||
if ((m_open_mode & no_buffer) == 0) aligned = true;
|
if ((m_open_mode & no_buffer) == 0) aligned = true;
|
||||||
if (!aligned)
|
if (!aligned)
|
||||||
{
|
|
||||||
size = bufs_size(bufs, num_bufs);
|
|
||||||
if ((size & (size_alignment()-1)) == 0) aligned = true;
|
|
||||||
}
|
|
||||||
if (aligned)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
ret = ::writev(m_fd, bufs, num_bufs);
|
|
||||||
if (ret < 0)
|
|
||||||
{
|
{
|
||||||
ec.assign(errno, get_posix_category());
|
size = bufs_size(bufs, nbufs);
|
||||||
return -1;
|
if ((size & (size_alignment()-1)) == 0) aligned = true;
|
||||||
|
}
|
||||||
|
if (aligned)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
tmp_ret = ::writev(m_fd, bufs, nbufs);
|
||||||
|
if (tmp_ret < 0)
|
||||||
|
{
|
||||||
|
ec.assign(errno, get_posix_category());
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
ret += tmp_ret;
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#ifdef TORRENT_LINUX
|
#ifdef TORRENT_LINUX
|
||||||
file::iovec_t* temp_bufs = TORRENT_ALLOCA(file::iovec_t, num_bufs);
|
else
|
||||||
memcpy(temp_bufs, bufs, sizeof(file::iovec_t) * num_bufs);
|
{
|
||||||
iovec_t& last = temp_bufs[num_bufs-1];
|
file::iovec_t* temp_bufs = TORRENT_ALLOCA(file::iovec_t, nbufs);
|
||||||
last.iov_len = (last.iov_len & ~(size_alignment()-1)) + size_alignment();
|
memcpy(temp_bufs, bufs, sizeof(file::iovec_t) * nbufs);
|
||||||
ret = ::writev(m_fd, temp_bufs, num_bufs);
|
iovec_t& last = temp_bufs[nbufs-1];
|
||||||
if (ret < 0)
|
last.iov_len = (last.iov_len & ~(size_alignment()-1)) + size_alignment();
|
||||||
{
|
tmp_ret = ::writev(m_fd, temp_bufs, nbufs);
|
||||||
ec.assign(errno, get_posix_category());
|
if (tmp_ret < 0)
|
||||||
return -1;
|
{
|
||||||
}
|
ec.assign(errno, get_posix_category());
|
||||||
if (ftruncate(m_fd, file_offset + size) < 0)
|
return -1;
|
||||||
{
|
}
|
||||||
ec.assign(errno, get_posix_category());
|
if (ftruncate(m_fd, file_offset + size) < 0)
|
||||||
return -1;
|
{
|
||||||
}
|
ec.assign(errno, get_posix_category());
|
||||||
return (std::min)(ret, size_type(size));
|
return -1;
|
||||||
|
}
|
||||||
|
ret += (std::min)(tmp_ret, size_type(size));
|
||||||
|
}
|
||||||
#endif // TORRENT_LINUX
|
#endif // TORRENT_LINUX
|
||||||
|
|
||||||
|
num_bufs -= nbufs;
|
||||||
|
bufs += nbufs;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
|
||||||
#else // TORRENT_USE_WRITEV
|
#else // TORRENT_USE_WRITEV
|
||||||
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
Loading…
Reference in New Issue