From 14dbd1c92dfea5bb3b2d713d27170e1270a7c779 Mon Sep 17 00:00:00 2001 From: arvidn Date: Sun, 7 May 2017 11:01:42 -0400 Subject: [PATCH] fix race condition in disk I/O storage class --- ChangeLog | 1 + include/libtorrent/storage.hpp | 1 + src/storage.cpp | 9 +++++++-- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 12ac76686..ba72f7f9f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ + * fix race condition in disk I/O storage class * fix http connection timeout on multi-homed hosts * removed depdendency on boost::uintptr_t for better compatibility * fix memory leak in the disk cache diff --git a/include/libtorrent/storage.hpp b/include/libtorrent/storage.hpp index da894d7f9..844071d28 100644 --- a/include/libtorrent/storage.hpp +++ b/include/libtorrent/storage.hpp @@ -476,6 +476,7 @@ namespace libtorrent // whose bit is 0, we set the file size, to make the file allocated // on disk (in full allocation mode) and just sparsely allocated in // case of sparse allocation mode + mutable mutex m_file_created_mutex; mutable bitfield m_file_created; bool m_allocate_files; diff --git a/src/storage.cpp b/src/storage.cpp index a22c70e5f..9c0b7b1ce 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -524,7 +524,10 @@ namespace libtorrent m_allocate_files = false; #endif - m_file_created.resize(files().num_files(), false); + { + mutex::scoped_lock l(m_file_created_mutex); + m_file_created.resize(files().num_files(), false); + } // first, create all missing directories std::string last_path; @@ -1494,6 +1497,7 @@ namespace libtorrent if (m_allocate_files && (mode & file::rw_mask) != file::read_only) { + mutex::scoped_lock l(m_file_created_mutex); if (m_file_created.size() != files().num_files()) m_file_created.resize(files().num_files(), false); @@ -1504,10 +1508,11 @@ namespace libtorrent // the file right away, to allocate it on the filesystem. if (m_file_created[file] == false) { + m_file_created.set_bit(file); + l.unlock(); error_code e; boost::int64_t const size = files().file_size(file); h->set_size(size, e); - m_file_created.set_bit(file); if (e) { ec.ec = e;