honor IOV_MAX when using writev and readv
This commit is contained in:
parent
bc1e47a486
commit
43c9e640ab
|
@ -90,6 +90,7 @@
|
|||
incoming connection
|
||||
* 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
|
||||
* 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)
|
||||
|
@ -98,7 +99,7 @@
|
|||
* add reset_piece_deadline function
|
||||
* fix merkle tree torrent assert
|
||||
|
||||
0.15.67 release
|
||||
0.15.7 release
|
||||
|
||||
* exposed set_peer_id to python binding
|
||||
* improve support for merkle tree torrent creation
|
||||
|
|
|
@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <boost/config.hpp>
|
||||
#include <boost/version.hpp>
|
||||
#include <stdio.h> // for snprintf
|
||||
#include <limits.h> // for IOV_MAX
|
||||
|
||||
#if defined TORRENT_DEBUG_BUFFERS && !defined TORRENT_DISABLE_POOL_ALLOCATOR
|
||||
#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
|
||||
#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)
|
||||
# define TORRENT_READ_HANDLER_MAX_SIZE 256
|
||||
#endif
|
||||
|
|
156
src/file.cpp
156
src/file.cpp
|
@ -1182,40 +1182,54 @@ namespace libtorrent
|
|||
}
|
||||
#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
|
||||
bool aligned = false;
|
||||
int size = 0;
|
||||
// if we're not opened in no-buffer mode, we don't need alignment
|
||||
if ((m_open_mode & no_buffer) == 0) aligned = true;
|
||||
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)
|
||||
bool aligned = false;
|
||||
int size = 0;
|
||||
// if we're not opened in no-buffer mode, we don't need alignment
|
||||
if ((m_open_mode & no_buffer) == 0) aligned = true;
|
||||
if (!aligned)
|
||||
{
|
||||
ec.assign(errno, get_posix_category());
|
||||
return -1;
|
||||
size = bufs_size(bufs, nbufs);
|
||||
if ((size & (size_alignment()-1)) == 0) aligned = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#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));
|
||||
if (aligned)
|
||||
#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
|
||||
|
||||
|
@ -1412,46 +1426,60 @@ namespace libtorrent
|
|||
|
||||
#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
|
||||
bool aligned = false;
|
||||
int size = 0;
|
||||
// if we're not opened in no-buffer mode, we don't need alignment
|
||||
if ((m_open_mode & no_buffer) == 0) aligned = true;
|
||||
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)
|
||||
bool aligned = false;
|
||||
int size = 0;
|
||||
// if we're not opened in no-buffer mode, we don't need alignment
|
||||
if ((m_open_mode & no_buffer) == 0) aligned = true;
|
||||
if (!aligned)
|
||||
{
|
||||
ec.assign(errno, get_posix_category());
|
||||
return -1;
|
||||
size = bufs_size(bufs, nbufs);
|
||||
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
|
||||
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)) + size_alignment();
|
||||
ret = ::writev(m_fd, temp_bufs, num_bufs);
|
||||
if (ret < 0)
|
||||
{
|
||||
ec.assign(errno, get_posix_category());
|
||||
return -1;
|
||||
}
|
||||
if (ftruncate(m_fd, file_offset + size) < 0)
|
||||
{
|
||||
ec.assign(errno, get_posix_category());
|
||||
return -1;
|
||||
}
|
||||
return (std::min)(ret, size_type(size));
|
||||
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)) + size_alignment();
|
||||
tmp_ret = ::writev(m_fd, temp_bufs, nbufs);
|
||||
if (tmp_ret < 0)
|
||||
{
|
||||
ec.assign(errno, get_posix_category());
|
||||
return -1;
|
||||
}
|
||||
if (ftruncate(m_fd, file_offset + size) < 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_WRITEV
|
||||
|
||||
ret = 0;
|
||||
|
|
Loading…
Reference in New Issue