From 9b5404347869fbee0bc9753a4c14619575704737 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Thu, 13 Dec 2007 04:05:25 +0000 Subject: [PATCH] attempt to fix potential deadlock in disk_io_thread --- include/libtorrent/disk_io_thread.hpp | 3 ++- src/disk_io_thread.cpp | 34 +++++++++------------------ 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/include/libtorrent/disk_io_thread.hpp b/include/libtorrent/disk_io_thread.hpp index b93ea8b75..a77522356 100644 --- a/include/libtorrent/disk_io_thread.hpp +++ b/include/libtorrent/disk_io_thread.hpp @@ -124,7 +124,8 @@ namespace libtorrent private: - mutable boost::mutex m_mutex; + typedef boost::recursive_mutex mutex_t; + mutable mutex_t m_mutex; boost::condition m_signal; bool m_abort; std::deque m_jobs; diff --git a/src/disk_io_thread.cpp b/src/disk_io_thread.cpp index a9446f664..e0fa982bc 100644 --- a/src/disk_io_thread.cpp +++ b/src/disk_io_thread.cpp @@ -62,7 +62,7 @@ namespace libtorrent disk_io_thread::~disk_io_thread() { - boost::mutex::scoped_lock l(m_mutex); + mutex_t::scoped_lock l(m_mutex); m_abort = true; m_signal.notify_all(); l.unlock(); @@ -74,7 +74,7 @@ namespace libtorrent disk_io_job disk_io_thread::find_job(boost::intrusive_ptr s , int action, int piece) const { - boost::mutex::scoped_lock l(m_mutex); + mutex_t::scoped_lock l(m_mutex); for (std::deque::const_iterator i = m_jobs.begin(); i != m_jobs.end(); ++i) { @@ -98,7 +98,7 @@ namespace libtorrent // aborts read operations void disk_io_thread::stop(boost::intrusive_ptr s) { - boost::mutex::scoped_lock l(m_mutex); + mutex_t::scoped_lock l(m_mutex); // read jobs are aborted, write and move jobs are syncronized for (std::deque::iterator i = m_jobs.begin(); i != m_jobs.end();) @@ -151,7 +151,7 @@ namespace libtorrent { TORRENT_ASSERT(!j.callback); TORRENT_ASSERT(j.storage); - boost::mutex::scoped_lock l(m_mutex); + mutex_t::scoped_lock l(m_mutex); std::deque::reverse_iterator i = m_jobs.rbegin(); if (j.action == disk_io_job::read) @@ -206,7 +206,7 @@ namespace libtorrent char* disk_io_thread::allocate_buffer() { - boost::mutex::scoped_lock l(m_mutex); + mutex_t::scoped_lock l(m_mutex); #ifdef TORRENT_STATS ++m_allocations; #endif @@ -215,7 +215,7 @@ namespace libtorrent void disk_io_thread::free_buffer(char* buf) { - boost::mutex::scoped_lock l(m_mutex); + mutex_t::scoped_lock l(m_mutex); #ifdef TORRENT_STATS --m_allocations; #endif @@ -229,7 +229,7 @@ namespace libtorrent #ifdef TORRENT_DISK_STATS m_log << log_time() << " idle" << std::endl; #endif - boost::mutex::scoped_lock l(m_mutex); + mutex_t::scoped_lock l(m_mutex); #ifndef NDEBUG m_current.action = (disk_io_job::action_t)-1; m_current.piece = -1; @@ -250,7 +250,7 @@ namespace libtorrent int ret = 0; - bool free_buffer = true; + bool free_current_buffer = true; try { TORRENT_ASSERT(j.storage); @@ -264,15 +264,10 @@ namespace libtorrent #ifdef TORRENT_DISK_STATS m_log << log_time() << " read " << j.buffer_size << std::endl; #endif - free_buffer = false; + free_current_buffer = false; if (j.buffer == 0) { - l.lock(); - j.buffer = (char*)m_pool.ordered_malloc(); -#ifdef TORRENT_STATS - ++m_allocations; -#endif - l.unlock(); + j.buffer = allocate_buffer(); TORRENT_ASSERT(j.buffer_size <= m_block_size); if (j.buffer == 0) { @@ -347,14 +342,7 @@ namespace libtorrent m_current.callback.clear(); #endif - if (j.buffer && free_buffer) - { - l.lock(); - m_pool.ordered_free(j.buffer); -#ifdef TORRENT_STATS - --m_allocations; -#endif - } + if (j.buffer && free_current_buffer) free_buffer(j.buffer); } } }