diff -r 263beb75f990 dcpp/FileReader.cpp --- a/dcpp/FileReader.cpp Sat Jan 02 15:19:42 2021 +0100 +++ b/dcpp/FileReader.cpp Sat Jan 02 18:11:47 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2019 Jacek Sieka, arnetheduck on gmail point com + * Copyright (C) 2001-2021 Jacek Sieka, arnetheduck on gmail point com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -44,13 +44,8 @@ } if(ret == READ_FAILED) { - dcdebug("Reading [mapped] %s\n", file.c_str()); - ret = readMapped(file, callback); - - if(ret == READ_FAILED) { - dcdebug("Reading [full] %s\n", file.c_str()); - ret = readCached(file, callback); - } + dcdebug("Reading [full] %s\n", file.c_str()); + ret = readCached(file, callback); } return ret; @@ -196,178 +191,11 @@ return *((uint64_t*)&over.Offset); } -size_t FileReader::readMapped(const string& file, const DataCallback& callback) { - /** @todo mapped reads can fail on Windows by throwing an exception that may only be caught by - SEH. MinGW doesn't have that, thus making this method of reading prone to unrecoverable - failures. disabling this for now should be fine as DC++ always tries overlapped reads first - (at the moment this file reader is only used in places where overlapped reads make the most - sense). - more info: - - */ -#if 1 - return READ_FAILED; #else - auto tfile = Text::toT(file); - - auto tmp = ::CreateFile(tfile.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, - FILE_FLAG_POSIX_SEMANTICS | FILE_FLAG_SEQUENTIAL_SCAN, nullptr); - - if (tmp == INVALID_HANDLE_VALUE) { - dcdebug("Failed to open unbuffered file: %s\n", Util::translateError(::GetLastError()).c_str()); - return READ_FAILED; - } - - Handle h(tmp); - - LARGE_INTEGER size = { 0 }; - if(!::GetFileSizeEx(h, &size)) { - dcdebug("Couldn't get file size: %s\n", Util::translateError(::GetLastError()).c_str()); - return READ_FAILED; - } - - if(!(tmp = ::CreateFileMapping(h, NULL, PAGE_READONLY, 0, 0, NULL))) { - dcdebug("Couldn't create file mapping: %s\n", Util::translateError(::GetLastError()).c_str()); - return READ_FAILED; - } - - Handle hmap(tmp); - - SYSTEM_INFO si = { 0 }; - ::GetSystemInfo(&si); - - auto blockSize = getBlockSize(si.dwPageSize); - - LARGE_INTEGER total = { 0 }; - bool go = true; - while(size.QuadPart > 0 && go) { - auto n = min(size.QuadPart, (int64_t)blockSize); - auto p = ::MapViewOfFile(hmap, FILE_MAP_READ, total.HighPart, total.LowPart, static_cast(n)); - if(!p) { - throw FileException(Util::translateError(::GetLastError())); - } - - go = callback(p, n); - - if(!::UnmapViewOfFile(p)) { - throw FileException(Util::translateError(::GetLastError())); - } - - size.QuadPart -= n; - total.QuadPart += n; - } - - return total.QuadPart; -#endif -} - -#else - -#include // mmap, munmap, madvise -#include // for handling read errors from previous trio -#include -#include -#include -#include - - size_t FileReader::readDirect(const string& file, const DataCallback& callback) { return READ_FAILED; } -static const int64_t BUF_SIZE = 0x1000000 - (0x1000000 % getpagesize()); -static sigjmp_buf sb_env; - -static void sigbus_handler(int signum, siginfo_t* info, void* context) { - // Jump back to the readMapped which will return error. Apparently truncating - // a file in Solaris sets si_code to BUS_OBJERR - if (signum == SIGBUS && (info->si_code == BUS_ADRERR || info->si_code == BUS_OBJERR)) - siglongjmp(sb_env, 1); -} - -size_t FileReader::readMapped(const string& filename, const DataCallback& callback) { - int fd = open(Text::fromUtf8(filename).c_str(), O_RDONLY); - if(fd == -1) { - dcdebug("Error opening file %s: %s\n", filename.c_str(), Util::translateError(errno).c_str()); - return READ_FAILED; - } - - struct stat statbuf; - if (fstat(fd, &statbuf) == -1) { - dcdebug("Error opening file %s: %s\n", filename.c_str(), Util::translateError(errno).c_str()); - close(fd); - return READ_FAILED; - } - - int64_t pos = 0; - auto size = statbuf.st_size; - - // Prepare and setup a signal handler in case of SIGBUS during mmapped file reads. - // SIGBUS can be sent when the file is truncated or in case of read errors. - struct sigaction act, oldact; - sigset_t signalset; - - sigemptyset(&signalset); - - act.sa_handler = NULL; - act.sa_sigaction = sigbus_handler; - act.sa_mask = signalset; - act.sa_flags = SA_SIGINFO | SA_RESETHAND; - - if (sigaction(SIGBUS, &act, &oldact) == -1) { - dcdebug("Failed to set signal handler for fastHash\n"); - close(fd); - return READ_FAILED; // Better luck with the slow hash. - } - - void* buf = NULL; - int64_t size_read = 0; - - uint64_t lastRead = GET_TICK(); - while (pos < size) { - size_read = std::min(size - pos, BUF_SIZE); - buf = mmap(0, size_read, PROT_READ, MAP_SHARED, fd, pos); - if (buf == MAP_FAILED) { - dcdebug("Error calling mmap for file %s: %s\n", filename.c_str(), Util::translateError(errno).c_str()); - break; - } - - if (sigsetjmp(sb_env, 1)) { - dcdebug("Caught SIGBUS for file %s\n", filename.c_str()); - break; - } - - if (posix_madvise(buf, size_read, POSIX_MADV_SEQUENTIAL | POSIX_MADV_WILLNEED) == -1) { - dcdebug("Error calling madvise for file %s: %s\n", filename.c_str(), Util::translateError(errno).c_str()); - break; - } - - if(!callback(buf, size_read)) { - break; - } - - if (munmap(buf, size_read) == -1) { - dcdebug("Error calling munmap for file %s: %s\n", filename.c_str(), Util::translateError(errno).c_str()); - break; - } - - buf = NULL; - pos += size_read; - } - - if (buf != NULL && buf != MAP_FAILED && munmap(buf, size_read) == -1) { - dcdebug("Error calling munmap for file %s: %s\n", filename.c_str(), Util::translateError(errno).c_str()); - } - - ::close(fd); - - if (sigaction(SIGBUS, &oldact, NULL) == -1) { - dcdebug("Failed to reset old signal handler for SIGBUS\n"); - } - - return pos == size ? pos : READ_FAILED; -} - #endif } diff -r 263beb75f990 dcpp/FileReader.h --- a/dcpp/FileReader.h Sat Jan 02 15:19:42 2021 +0100 +++ b/dcpp/FileReader.h Sat Jan 02 18:11:47 2021 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2001-2019 Jacek Sieka, arnetheduck on gmail point com + * Copyright (C) 2001-2021 Jacek Sieka, arnetheduck on gmail point com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -38,12 +38,6 @@ class FileReader : boost::noncopyable { public: - enum Strategy { - DIRECT, - MAPPED, - CACHED - }; - typedef function DataCallback; /** @@ -64,7 +58,6 @@ private: static const size_t DEFAULT_BLOCK_SIZE = 256*1024; - static const size_t DEFAULT_MMAP_SIZE = 64*1024*1024; string file; bool direct; @@ -77,7 +70,6 @@ void* align(void* buf, size_t alignment); size_t readDirect(const string& file, const DataCallback& callback); - size_t readMapped(const string& file, const DataCallback& callback); size_t readCached(const string& file, const DataCallback& callback); }; diff -r 263beb75f990 help/settings_expert.html --- a/help/settings_expert.html Sat Jan 02 15:19:42 2021 +0100 +++ b/help/settings_expert.html Sat Jan 02 18:11:47 2021 +0100 @@ -41,11 +41,11 @@ your settings are automatically saved; good to prevent losses in case of crashes. This is measured in minutes. (default: 10 minutes)
Socket read buffer
-
The size of the buffer DC++ use to read sockets. Measured -in bytes. (default: 8192 bytes)
+
The size of the buffer DC++ uses to read sockets. Measured +in bytes. (default: operating system default)
Socket write buffer
-
The size of the buffer DC++ use to write to sockets. - Measured in bytes. (default: 8192 bytes)
+
The size of the buffer DC++ uses to write to sockets. + Measured in bytes. (default: operating system default)
Max PM windows
The maximum amount of Private Message