attempt to fix potential deadlock in disk_io_thread

This commit is contained in:
Arvid Norberg 2007-12-13 04:05:25 +00:00
parent 7cae5f897b
commit 9b54043478
2 changed files with 13 additions and 24 deletions

View File

@ -124,7 +124,8 @@ namespace libtorrent
private: private:
mutable boost::mutex m_mutex; typedef boost::recursive_mutex mutex_t;
mutable mutex_t m_mutex;
boost::condition m_signal; boost::condition m_signal;
bool m_abort; bool m_abort;
std::deque<disk_io_job> m_jobs; std::deque<disk_io_job> m_jobs;

View File

@ -62,7 +62,7 @@ namespace libtorrent
disk_io_thread::~disk_io_thread() disk_io_thread::~disk_io_thread()
{ {
boost::mutex::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
m_abort = true; m_abort = true;
m_signal.notify_all(); m_signal.notify_all();
l.unlock(); l.unlock();
@ -74,7 +74,7 @@ namespace libtorrent
disk_io_job disk_io_thread::find_job(boost::intrusive_ptr<piece_manager> s disk_io_job disk_io_thread::find_job(boost::intrusive_ptr<piece_manager> s
, int action, int piece) const , int action, int piece) const
{ {
boost::mutex::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
for (std::deque<disk_io_job>::const_iterator i = m_jobs.begin(); for (std::deque<disk_io_job>::const_iterator i = m_jobs.begin();
i != m_jobs.end(); ++i) i != m_jobs.end(); ++i)
{ {
@ -98,7 +98,7 @@ namespace libtorrent
// aborts read operations // aborts read operations
void disk_io_thread::stop(boost::intrusive_ptr<piece_manager> s) void disk_io_thread::stop(boost::intrusive_ptr<piece_manager> 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 // read jobs are aborted, write and move jobs are syncronized
for (std::deque<disk_io_job>::iterator i = m_jobs.begin(); for (std::deque<disk_io_job>::iterator i = m_jobs.begin();
i != m_jobs.end();) i != m_jobs.end();)
@ -151,7 +151,7 @@ namespace libtorrent
{ {
TORRENT_ASSERT(!j.callback); TORRENT_ASSERT(!j.callback);
TORRENT_ASSERT(j.storage); TORRENT_ASSERT(j.storage);
boost::mutex::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
std::deque<disk_io_job>::reverse_iterator i = m_jobs.rbegin(); std::deque<disk_io_job>::reverse_iterator i = m_jobs.rbegin();
if (j.action == disk_io_job::read) if (j.action == disk_io_job::read)
@ -206,7 +206,7 @@ namespace libtorrent
char* disk_io_thread::allocate_buffer() char* disk_io_thread::allocate_buffer()
{ {
boost::mutex::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
#ifdef TORRENT_STATS #ifdef TORRENT_STATS
++m_allocations; ++m_allocations;
#endif #endif
@ -215,7 +215,7 @@ namespace libtorrent
void disk_io_thread::free_buffer(char* buf) 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 #ifdef TORRENT_STATS
--m_allocations; --m_allocations;
#endif #endif
@ -229,7 +229,7 @@ namespace libtorrent
#ifdef TORRENT_DISK_STATS #ifdef TORRENT_DISK_STATS
m_log << log_time() << " idle" << std::endl; m_log << log_time() << " idle" << std::endl;
#endif #endif
boost::mutex::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
#ifndef NDEBUG #ifndef NDEBUG
m_current.action = (disk_io_job::action_t)-1; m_current.action = (disk_io_job::action_t)-1;
m_current.piece = -1; m_current.piece = -1;
@ -250,7 +250,7 @@ namespace libtorrent
int ret = 0; int ret = 0;
bool free_buffer = true; bool free_current_buffer = true;
try try
{ {
TORRENT_ASSERT(j.storage); TORRENT_ASSERT(j.storage);
@ -264,15 +264,10 @@ namespace libtorrent
#ifdef TORRENT_DISK_STATS #ifdef TORRENT_DISK_STATS
m_log << log_time() << " read " << j.buffer_size << std::endl; m_log << log_time() << " read " << j.buffer_size << std::endl;
#endif #endif
free_buffer = false; free_current_buffer = false;
if (j.buffer == 0) if (j.buffer == 0)
{ {
l.lock(); j.buffer = allocate_buffer();
j.buffer = (char*)m_pool.ordered_malloc();
#ifdef TORRENT_STATS
++m_allocations;
#endif
l.unlock();
TORRENT_ASSERT(j.buffer_size <= m_block_size); TORRENT_ASSERT(j.buffer_size <= m_block_size);
if (j.buffer == 0) if (j.buffer == 0)
{ {
@ -347,14 +342,7 @@ namespace libtorrent
m_current.callback.clear(); m_current.callback.clear();
#endif #endif
if (j.buffer && free_buffer) if (j.buffer && free_current_buffer) free_buffer(j.buffer);
{
l.lock();
m_pool.ordered_free(j.buffer);
#ifdef TORRENT_STATS
--m_allocations;
#endif
}
} }
} }
} }