Don't enable mmap if file allocation is disabled

Without file allocation, we cannot map file because file length could
be zero.

This could fix bug reported at GH-478
pull/481/head
Tatsuhiro Tsujikawa 2015-11-12 22:42:24 +09:00
parent af98861aff
commit 3974c1223b
3 changed files with 20 additions and 9 deletions

View File

@ -284,12 +284,10 @@ ssize_t AbstractDiskWriter::readDataInternal(unsigned char* data, size_t len,
int64_t offset)
{
if(mapaddr_) {
ssize_t readlen;
if(offset > maplen_) {
readlen = 0;
} else {
readlen = std::min(static_cast<size_t>(maplen_ - offset), len);
if (offset >= maplen_) {
return 0;
}
auto readlen = std::min(maplen_ - offset, static_cast<int64_t>(len));
memcpy(data, mapaddr_ + offset, readlen);
return readlen;
} else {
@ -355,6 +353,14 @@ void AbstractDiskWriter::ensureMmapWrite(size_t len, int64_t offset)
}
} else {
int64_t filesize = size();
if (filesize == 0) {
// mapping 0 length file is useless. Also munmap with size ==
// 0 will fail with EINVAL.
enableMmap_ = false;
return;
}
int errNum = 0;
if(static_cast<int64_t>(len + offset) <= filesize) {
#ifdef __MINGW32__

View File

@ -58,9 +58,11 @@ BtFileAllocationEntry::~BtFileAllocationEntry() {}
void BtFileAllocationEntry::prepareForNextAction
(std::vector<std::unique_ptr<Command>>& commands, DownloadEngine* e)
{
BtSetup().setup(commands, getRequestGroup(), e,
getRequestGroup()->getOption().get());
if(getRequestGroup()->getOption()->getAsBool(PREF_ENABLE_MMAP)) {
auto &option = getRequestGroup()->getOption();
BtSetup().setup(commands, getRequestGroup(), e, option.get());
if(option->getAsBool(PREF_ENABLE_MMAP) &&
option->get(PREF_FILE_ALLOCATION) != V_NONE) {
getRequestGroup()->getPieceStorage()->getDiskAdaptor()->enableMmap();
}
if(!getRequestGroup()->downloadFinished()) {

View File

@ -60,10 +60,13 @@ void StreamFileAllocationEntry::prepareForNextAction
(std::vector<std::unique_ptr<Command>>& commands,
DownloadEngine* e)
{
auto &option = getRequestGroup()->getOption();
// For DownloadContext::resetDownloadStartTime(), see also
// RequestGroup::createInitialCommand()
getRequestGroup()->getDownloadContext()->resetDownloadStartTime();
if(getRequestGroup()->getOption()->getAsBool(PREF_ENABLE_MMAP)) {
if(option->getAsBool(PREF_ENABLE_MMAP) &&
option->get(PREF_FILE_ALLOCATION) != V_NONE) {
getRequestGroup()->getPieceStorage()->getDiskAdaptor()->enableMmap();
}
if(getNextCommand()) {