mirror of
https://github.com/qbittorrent/qBittorrent.git
synced 2024-10-22 10:46:04 +03:00
Allow to use POSIX-compliant disk IO type
This patch allows user to switch disk IO type between memory mapped files based type (default in libtorrent 2, and seems causing memory issues) and POSIX-compliant type which is more conservative on memory usage. Co-authored-by: Chocobo1 <Chocobo1@users.noreply.github.com> Co-authored-by: Vladimir Golovnev (Glassez) <glassez@yandex.ru> PR #16895.
This commit is contained in:
parent
a048ea668f
commit
e698c09298
8 changed files with 90 additions and 1 deletions
|
@ -34,6 +34,8 @@
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
#ifdef QBT_USES_LIBTORRENT2
|
#ifdef QBT_USES_LIBTORRENT2
|
||||||
|
#include <libtorrent/mmap_disk_io.hpp>
|
||||||
|
#include <libtorrent/posix_disk_io.hpp>
|
||||||
#include <libtorrent/session.hpp>
|
#include <libtorrent/session.hpp>
|
||||||
|
|
||||||
std::unique_ptr<lt::disk_interface> customDiskIOConstructor(
|
std::unique_ptr<lt::disk_interface> customDiskIOConstructor(
|
||||||
|
@ -42,6 +44,18 @@ std::unique_ptr<lt::disk_interface> customDiskIOConstructor(
|
||||||
return std::make_unique<CustomDiskIOThread>(lt::default_disk_io_constructor(ioContext, settings, counters));
|
return std::make_unique<CustomDiskIOThread>(lt::default_disk_io_constructor(ioContext, settings, counters));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<lt::disk_interface> customPosixDiskIOConstructor(
|
||||||
|
lt::io_context &ioContext, const lt::settings_interface &settings, lt::counters &counters)
|
||||||
|
{
|
||||||
|
return std::make_unique<CustomDiskIOThread>(lt::posix_disk_io_constructor(ioContext, settings, counters));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<lt::disk_interface> customMMapDiskIOConstructor(
|
||||||
|
lt::io_context &ioContext, const lt::settings_interface &settings, lt::counters &counters)
|
||||||
|
{
|
||||||
|
return std::make_unique<CustomDiskIOThread>(lt::mmap_disk_io_constructor(ioContext, settings, counters));
|
||||||
|
}
|
||||||
|
|
||||||
CustomDiskIOThread::CustomDiskIOThread(std::unique_ptr<libtorrent::disk_interface> nativeDiskIOThread)
|
CustomDiskIOThread::CustomDiskIOThread(std::unique_ptr<libtorrent::disk_interface> nativeDiskIOThread)
|
||||||
: m_nativeDiskIO {std::move(nativeDiskIOThread)}
|
: m_nativeDiskIO {std::move(nativeDiskIOThread)}
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,6 +50,10 @@
|
||||||
#ifdef QBT_USES_LIBTORRENT2
|
#ifdef QBT_USES_LIBTORRENT2
|
||||||
std::unique_ptr<lt::disk_interface> customDiskIOConstructor(
|
std::unique_ptr<lt::disk_interface> customDiskIOConstructor(
|
||||||
lt::io_context &ioContext, lt::settings_interface const &settings, lt::counters &counters);
|
lt::io_context &ioContext, lt::settings_interface const &settings, lt::counters &counters);
|
||||||
|
std::unique_ptr<lt::disk_interface> customPosixDiskIOConstructor(
|
||||||
|
lt::io_context &ioContext, lt::settings_interface const &settings, lt::counters &counters);
|
||||||
|
std::unique_ptr<lt::disk_interface> customMMapDiskIOConstructor(
|
||||||
|
lt::io_context &ioContext, lt::settings_interface const &settings, lt::counters &counters);
|
||||||
|
|
||||||
class CustomDiskIOThread final : public lt::disk_interface
|
class CustomDiskIOThread final : public lt::disk_interface
|
||||||
{
|
{
|
||||||
|
|
|
@ -381,6 +381,7 @@ Session::Session(QObject *parent)
|
||||||
, m_diskCacheSize(BITTORRENT_SESSION_KEY(u"DiskCacheSize"_qs), -1)
|
, m_diskCacheSize(BITTORRENT_SESSION_KEY(u"DiskCacheSize"_qs), -1)
|
||||||
, m_diskCacheTTL(BITTORRENT_SESSION_KEY(u"DiskCacheTTL"_qs), 60)
|
, m_diskCacheTTL(BITTORRENT_SESSION_KEY(u"DiskCacheTTL"_qs), 60)
|
||||||
, m_diskQueueSize(BITTORRENT_SESSION_KEY(u"DiskQueueSize"_qs), (1024 * 1024))
|
, m_diskQueueSize(BITTORRENT_SESSION_KEY(u"DiskQueueSize"_qs), (1024 * 1024))
|
||||||
|
, m_diskIOType(BITTORRENT_SESSION_KEY(u"DiskIOType"_qs), DiskIOType::Default)
|
||||||
, m_useOSCache(BITTORRENT_SESSION_KEY(u"UseOSCache"_qs), true)
|
, m_useOSCache(BITTORRENT_SESSION_KEY(u"UseOSCache"_qs), true)
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
, m_coalesceReadWriteEnabled(BITTORRENT_SESSION_KEY(u"CoalesceReadWrite"_qs), true)
|
, m_coalesceReadWriteEnabled(BITTORRENT_SESSION_KEY(u"CoalesceReadWrite"_qs), true)
|
||||||
|
@ -1149,7 +1150,18 @@ void Session::initializeNativeSession()
|
||||||
loadLTSettings(pack);
|
loadLTSettings(pack);
|
||||||
lt::session_params sessionParams {pack, {}};
|
lt::session_params sessionParams {pack, {}};
|
||||||
#ifdef QBT_USES_LIBTORRENT2
|
#ifdef QBT_USES_LIBTORRENT2
|
||||||
sessionParams.disk_io_constructor = customDiskIOConstructor;
|
switch (diskIOType())
|
||||||
|
{
|
||||||
|
case DiskIOType::Posix:
|
||||||
|
sessionParams.disk_io_constructor = customPosixDiskIOConstructor;
|
||||||
|
break;
|
||||||
|
case DiskIOType::MMap:
|
||||||
|
sessionParams.disk_io_constructor = customMMapDiskIOConstructor;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
sessionParams.disk_io_constructor = customDiskIOConstructor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
m_nativeSession = new lt::session {sessionParams};
|
m_nativeSession = new lt::session {sessionParams};
|
||||||
|
|
||||||
|
@ -3363,6 +3375,19 @@ void Session::setPeerTurnoverInterval(const int val)
|
||||||
configureDeferred();
|
configureDeferred();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DiskIOType Session::diskIOType() const
|
||||||
|
{
|
||||||
|
return m_diskIOType;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Session::setDiskIOType(const DiskIOType type)
|
||||||
|
{
|
||||||
|
if (type != m_diskIOType)
|
||||||
|
{
|
||||||
|
m_diskIOType = type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int Session::requestQueueSize() const
|
int Session::requestQueueSize() const
|
||||||
{
|
{
|
||||||
return m_requestQueueSize;
|
return m_requestQueueSize;
|
||||||
|
|
|
@ -122,6 +122,14 @@ namespace BitTorrent
|
||||||
};
|
};
|
||||||
Q_ENUM_NS(ChokingAlgorithm)
|
Q_ENUM_NS(ChokingAlgorithm)
|
||||||
|
|
||||||
|
enum class DiskIOType : int
|
||||||
|
{
|
||||||
|
Default = 0,
|
||||||
|
MMap = 1,
|
||||||
|
Posix = 2
|
||||||
|
};
|
||||||
|
Q_ENUM_NS(DiskIOType)
|
||||||
|
|
||||||
enum class MixedModeAlgorithm : int
|
enum class MixedModeAlgorithm : int
|
||||||
{
|
{
|
||||||
TCP = 0,
|
TCP = 0,
|
||||||
|
@ -368,6 +376,8 @@ namespace BitTorrent
|
||||||
void setDiskCacheTTL(int ttl);
|
void setDiskCacheTTL(int ttl);
|
||||||
qint64 diskQueueSize() const;
|
qint64 diskQueueSize() const;
|
||||||
void setDiskQueueSize(qint64 size);
|
void setDiskQueueSize(qint64 size);
|
||||||
|
DiskIOType diskIOType() const;
|
||||||
|
void setDiskIOType(DiskIOType type);
|
||||||
bool useOSCache() const;
|
bool useOSCache() const;
|
||||||
void setUseOSCache(bool use);
|
void setUseOSCache(bool use);
|
||||||
bool isCoalesceReadWriteEnabled() const;
|
bool isCoalesceReadWriteEnabled() const;
|
||||||
|
@ -689,6 +699,7 @@ namespace BitTorrent
|
||||||
CachedSettingValue<int> m_diskCacheSize;
|
CachedSettingValue<int> m_diskCacheSize;
|
||||||
CachedSettingValue<int> m_diskCacheTTL;
|
CachedSettingValue<int> m_diskCacheTTL;
|
||||||
CachedSettingValue<qint64> m_diskQueueSize;
|
CachedSettingValue<qint64> m_diskQueueSize;
|
||||||
|
CachedSettingValue<DiskIOType> m_diskIOType;
|
||||||
CachedSettingValue<bool> m_useOSCache;
|
CachedSettingValue<bool> m_useOSCache;
|
||||||
CachedSettingValue<bool> m_coalesceReadWriteEnabled;
|
CachedSettingValue<bool> m_coalesceReadWriteEnabled;
|
||||||
CachedSettingValue<bool> m_usePieceExtentAffinity;
|
CachedSettingValue<bool> m_usePieceExtentAffinity;
|
||||||
|
|
|
@ -108,6 +108,9 @@ namespace
|
||||||
DISK_CACHE_TTL,
|
DISK_CACHE_TTL,
|
||||||
#endif
|
#endif
|
||||||
DISK_QUEUE_SIZE,
|
DISK_QUEUE_SIZE,
|
||||||
|
#ifdef QBT_USES_LIBTORRENT2
|
||||||
|
DISK_IO_TYPE,
|
||||||
|
#endif
|
||||||
OS_CACHE,
|
OS_CACHE,
|
||||||
#ifndef QBT_USES_LIBTORRENT2
|
#ifndef QBT_USES_LIBTORRENT2
|
||||||
COALESCE_RW,
|
COALESCE_RW,
|
||||||
|
@ -219,6 +222,9 @@ void AdvancedSettings::saveAdvancedSettings()
|
||||||
#endif
|
#endif
|
||||||
// Disk queue size
|
// Disk queue size
|
||||||
session->setDiskQueueSize(m_spinBoxDiskQueueSize.value() * 1024);
|
session->setDiskQueueSize(m_spinBoxDiskQueueSize.value() * 1024);
|
||||||
|
#ifdef QBT_USES_LIBTORRENT2
|
||||||
|
session->setDiskIOType(m_comboBoxDiskIOType.currentData().value<BitTorrent::DiskIOType>());
|
||||||
|
#endif
|
||||||
// Enable OS cache
|
// Enable OS cache
|
||||||
session->setUseOSCache(m_checkBoxOsCache.isChecked());
|
session->setUseOSCache(m_checkBoxOsCache.isChecked());
|
||||||
#ifndef QBT_USES_LIBTORRENT2
|
#ifndef QBT_USES_LIBTORRENT2
|
||||||
|
@ -521,6 +527,15 @@ void AdvancedSettings::loadAdvancedSettings()
|
||||||
m_spinBoxDiskQueueSize.setSuffix(tr(" KiB"));
|
m_spinBoxDiskQueueSize.setSuffix(tr(" KiB"));
|
||||||
addRow(DISK_QUEUE_SIZE, (tr("Disk queue size") + u' ' + makeLink(u"https://www.libtorrent.org/reference-Settings.html#max_queued_disk_bytes", u"(?)"))
|
addRow(DISK_QUEUE_SIZE, (tr("Disk queue size") + u' ' + makeLink(u"https://www.libtorrent.org/reference-Settings.html#max_queued_disk_bytes", u"(?)"))
|
||||||
, &m_spinBoxDiskQueueSize);
|
, &m_spinBoxDiskQueueSize);
|
||||||
|
#ifdef QBT_USES_LIBTORRENT2
|
||||||
|
// Disk IO type
|
||||||
|
m_comboBoxDiskIOType.addItem(tr("Default"), QVariant::fromValue(BitTorrent::DiskIOType::Default));
|
||||||
|
m_comboBoxDiskIOType.addItem(tr("Memory mapped files"), QVariant::fromValue(BitTorrent::DiskIOType::MMap));
|
||||||
|
m_comboBoxDiskIOType.addItem(tr("POSIX-compliant"), QVariant::fromValue(BitTorrent::DiskIOType::Posix));
|
||||||
|
m_comboBoxDiskIOType.setCurrentIndex(m_comboBoxDiskIOType.findData(QVariant::fromValue(session->diskIOType())));
|
||||||
|
addRow(DISK_IO_TYPE, tr("Disk IO type (requires restart)") + u' ' + makeLink(u"https://www.libtorrent.org/single-page-ref.html#default-disk-io-constructor", u"(?)")
|
||||||
|
, &m_comboBoxDiskIOType);
|
||||||
|
#endif
|
||||||
// Enable OS cache
|
// Enable OS cache
|
||||||
m_checkBoxOsCache.setChecked(session->useOSCache());
|
m_checkBoxOsCache.setChecked(session->useOSCache());
|
||||||
addRow(OS_CACHE, (tr("Enable OS cache") + u' ' + makeLink(u"https://www.libtorrent.org/reference-Settings.html#disk_io_write_mode", u"(?)"))
|
addRow(OS_CACHE, (tr("Enable OS cache") + u' ' + makeLink(u"https://www.libtorrent.org/reference-Settings.html#disk_io_write_mode", u"(?)"))
|
||||||
|
|
|
@ -76,6 +76,7 @@ private:
|
||||||
QSpinBox m_spinBoxCache, m_spinBoxCacheTTL;
|
QSpinBox m_spinBoxCache, m_spinBoxCacheTTL;
|
||||||
QCheckBox m_checkBoxCoalesceRW;
|
QCheckBox m_checkBoxCoalesceRW;
|
||||||
#else
|
#else
|
||||||
|
QComboBox m_comboBoxDiskIOType;
|
||||||
QSpinBox m_spinBoxHashingThreads;
|
QSpinBox m_spinBoxHashingThreads;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -315,6 +315,8 @@ void AppController::preferencesAction()
|
||||||
data[u"disk_cache_ttl"_qs] = session->diskCacheTTL();
|
data[u"disk_cache_ttl"_qs] = session->diskCacheTTL();
|
||||||
// Disk queue size
|
// Disk queue size
|
||||||
data[u"disk_queue_size"_qs] = session->diskQueueSize();
|
data[u"disk_queue_size"_qs] = session->diskQueueSize();
|
||||||
|
// Disk IO Type
|
||||||
|
data[u"disk_io_type"_qs] = static_cast<int>(session->diskIOType());
|
||||||
// Enable OS cache
|
// Enable OS cache
|
||||||
data[u"enable_os_cache"_qs] = session->useOSCache();
|
data[u"enable_os_cache"_qs] = session->useOSCache();
|
||||||
// Coalesce reads & writes
|
// Coalesce reads & writes
|
||||||
|
@ -799,6 +801,9 @@ void AppController::setPreferencesAction()
|
||||||
// Disk queue size
|
// Disk queue size
|
||||||
if (hasKey(u"disk_queue_size"_qs))
|
if (hasKey(u"disk_queue_size"_qs))
|
||||||
session->setDiskQueueSize(it.value().toLongLong());
|
session->setDiskQueueSize(it.value().toLongLong());
|
||||||
|
// Disk IO Type
|
||||||
|
if (hasKey(u"disk_io_type"_qs))
|
||||||
|
session->setDiskIOType(static_cast<BitTorrent::DiskIOType>(it.value().toInt()));
|
||||||
// Enable OS cache
|
// Enable OS cache
|
||||||
if (hasKey(u"enable_os_cache"_qs))
|
if (hasKey(u"enable_os_cache"_qs))
|
||||||
session->setUseOSCache(it.value().toBool());
|
session->setUseOSCache(it.value().toBool());
|
||||||
|
|
|
@ -1038,6 +1038,18 @@
|
||||||
<input type="text" id="diskQueueSize" style="width: 15em;"> QBT_TR(KiB)QBT_TR[CONTEXT=OptionsDialog]
|
<input type="text" id="diskQueueSize" style="width: 15em;"> QBT_TR(KiB)QBT_TR[CONTEXT=OptionsDialog]
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<label for="diskIOType">QBT_TR(Disk IO type (libtorrent >= 2.0; requires restart):)QBT_TR[CONTEXT=OptionsDialog] <a href="https://www.libtorrent.org/single-page-ref.html#default-disk-io-constructor" target="_blank">(?)</a></label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<select id="diskIOType" style="width: 15em;">
|
||||||
|
<option value="0">QBT_TR(Default)QBT_TR[CONTEXT=OptionsDialog]</option>
|
||||||
|
<option value="1">QBT_TR(Memory mapped files)QBT_TR[CONTEXT=OptionsDialog]</option>
|
||||||
|
<option value="2">QBT_TR(POSIX-compliant)QBT_TR[CONTEXT=OptionsDialog]</option>
|
||||||
|
</select>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<label for="enableOSCache">QBT_TR(Enable OS cache:)QBT_TR[CONTEXT=OptionsDialog] <a href="https://www.libtorrent.org/reference-Settings.html#disk_io_write_mode" target="_blank">(?)</a></label>
|
<label for="enableOSCache">QBT_TR(Enable OS cache:)QBT_TR[CONTEXT=OptionsDialog] <a href="https://www.libtorrent.org/reference-Settings.html#disk_io_write_mode" target="_blank">(?)</a></label>
|
||||||
|
@ -1970,6 +1982,7 @@
|
||||||
$('diskCache').setProperty('value', pref.disk_cache);
|
$('diskCache').setProperty('value', pref.disk_cache);
|
||||||
$('diskCacheExpiryInterval').setProperty('value', pref.disk_cache_ttl);
|
$('diskCacheExpiryInterval').setProperty('value', pref.disk_cache_ttl);
|
||||||
$('diskQueueSize').setProperty('value', (pref.disk_queue_size / 1024));
|
$('diskQueueSize').setProperty('value', (pref.disk_queue_size / 1024));
|
||||||
|
$('diskIOType').setProperty('value', pref.disk_io_type);
|
||||||
$('enableOSCache').setProperty('checked', pref.enable_os_cache);
|
$('enableOSCache').setProperty('checked', pref.enable_os_cache);
|
||||||
$('coalesceReadsAndWrites').setProperty('checked', pref.enable_coalesce_read_write);
|
$('coalesceReadsAndWrites').setProperty('checked', pref.enable_coalesce_read_write);
|
||||||
$('pieceExtentAffinity').setProperty('checked', pref.enable_piece_extent_affinity);
|
$('pieceExtentAffinity').setProperty('checked', pref.enable_piece_extent_affinity);
|
||||||
|
@ -2371,6 +2384,7 @@
|
||||||
settings.set('disk_cache', $('diskCache').getProperty('value'));
|
settings.set('disk_cache', $('diskCache').getProperty('value'));
|
||||||
settings.set('disk_cache_ttl', $('diskCacheExpiryInterval').getProperty('value'));
|
settings.set('disk_cache_ttl', $('diskCacheExpiryInterval').getProperty('value'));
|
||||||
settings.set('disk_queue_size', ($('diskQueueSize').getProperty('value') * 1024));
|
settings.set('disk_queue_size', ($('diskQueueSize').getProperty('value') * 1024));
|
||||||
|
settings.set('disk_io_type', $('diskIOType').getProperty('value'));
|
||||||
settings.set('enable_os_cache', $('enableOSCache').getProperty('checked'));
|
settings.set('enable_os_cache', $('enableOSCache').getProperty('checked'));
|
||||||
settings.set('enable_coalesce_read_write', $('coalesceReadsAndWrites').getProperty('checked'));
|
settings.set('enable_coalesce_read_write', $('coalesceReadsAndWrites').getProperty('checked'));
|
||||||
settings.set('enable_piece_extent_affinity', $('pieceExtentAffinity').getProperty('checked'));
|
settings.set('enable_piece_extent_affinity', $('pieceExtentAffinity').getProperty('checked'));
|
||||||
|
|
Loading…
Reference in a new issue