attempted fix for inconsistent debug refcounters on blocks. pinning pieces with outstanding reads in an attempt at fixing inconsitencies seen around that logic as well
This commit is contained in:
parent
ad7d74f255
commit
9a2e511dda
|
@ -115,7 +115,6 @@ namespace libtorrent
|
|||
: buf(0)
|
||||
, refcount(0)
|
||||
, dirty(false)
|
||||
, hitcount(0)
|
||||
, pending(false)
|
||||
{
|
||||
#if TORRENT_USE_ASSERTS
|
||||
|
@ -127,7 +126,7 @@ namespace libtorrent
|
|||
|
||||
char* buf;
|
||||
|
||||
enum { max_refcount = (1 << 15) -1 };
|
||||
enum { max_refcount = (1 << 30) - 1 };
|
||||
|
||||
// the number of references to this buffer. These references
|
||||
// might be in outstanding asyncronous requests or in peer
|
||||
|
@ -135,7 +134,7 @@ namespace libtorrent
|
|||
// all references are gone and refcount reaches 0. The buf
|
||||
// pointer in this struct doesn't count as a reference and
|
||||
// is always the last to be cleared
|
||||
boost::uint16_t refcount:15;
|
||||
boost::uint32_t refcount:30;
|
||||
|
||||
// if this is true, this block needs to be written to
|
||||
// disk before it's freed. Typically all blocks in a piece
|
||||
|
@ -143,17 +142,13 @@ namespace libtorrent
|
|||
// (read-ahead cache). Once blocks are written to disk, the
|
||||
// dirty flag is cleared and effectively turns the block
|
||||
// into a read cache block
|
||||
boost::uint16_t dirty:1;
|
||||
|
||||
// the number of times this block has been copied out of
|
||||
// the cache, serving a request.
|
||||
boost::uint16_t hitcount:15;
|
||||
boost::uint32_t dirty:1;
|
||||
|
||||
// pending means that this buffer has not yet been filled in
|
||||
// with valid data. There's an outstanding read job for this.
|
||||
// If the dirty flag is set, it means there's an outstanding
|
||||
// write job to write this block.
|
||||
boost::uint16_t pending:1;
|
||||
boost::uint32_t pending:1;
|
||||
|
||||
#if TORRENT_USE_ASSERTS
|
||||
// this many of the references are held by hashing operations
|
||||
|
@ -179,6 +174,7 @@ namespace libtorrent
|
|||
&& num_blocks == 0
|
||||
&& !hashing
|
||||
&& read_jobs.size() == 0
|
||||
&& outstanding_read == 0
|
||||
&& (ignore_hash || !hash || hash->offset == 0);
|
||||
}
|
||||
|
||||
|
@ -209,9 +205,11 @@ namespace libtorrent
|
|||
|
||||
// the pointers to the block data. If this is a ghost
|
||||
// cache entry, there won't be any data here
|
||||
// TODO: 3 could this be a scoped_array instead? does cached_piece_entry really need to be copyable?
|
||||
// cached_piece_entry does need to be copyable since it's part of a container, but it's possible
|
||||
// it could be a raw pointer or boost::unique_ptr perhaps
|
||||
|
||||
// TODO: 3 could this be a scoped_array instead? does cached_piece_entry
|
||||
// really need to be copyable? cached_piece_entry does need to be
|
||||
// copyable since it's part of a container, but it's possible it could be
|
||||
// a raw pointer or boost::unique_ptr perhaps
|
||||
boost::shared_array<cached_block_entry> blocks;
|
||||
|
||||
// the last time a block was written to this piece
|
||||
|
|
|
@ -1281,6 +1281,8 @@ bool block_cache::inc_block_refcount(cached_piece_entry* pe, int block, int reas
|
|||
case ref_reading: ++pe->blocks[block].reading_count; break;
|
||||
case ref_flushing: ++pe->blocks[block].flushing_count; break;
|
||||
};
|
||||
TORRENT_ASSERT(pe->blocks[block].refcount >= pe->blocks[block].hashing_count
|
||||
+ pe->blocks[block].reading_count + pe->blocks[block].flushing_count);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
@ -1337,6 +1339,8 @@ void block_cache::dec_block_refcount(cached_piece_entry* pe, int block, int reas
|
|||
case ref_reading: --pe->blocks[block].reading_count; break;
|
||||
case ref_flushing: --pe->blocks[block].flushing_count; break;
|
||||
};
|
||||
TORRENT_PIECE_ASSERT(pe->blocks[block].refcount >= pe->blocks[block].hashing_count
|
||||
+ pe->blocks[block].reading_count + pe->blocks[block].flushing_count, pe);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -1603,6 +1607,12 @@ void block_cache::check_invariant() const
|
|||
}
|
||||
if (p.blocks[k].pending) ++num_pending;
|
||||
if (p.blocks[k].refcount > 0) ++num_pinned;
|
||||
|
||||
TORRENT_PIECE_ASSERT(p.blocks[k].refcount >=
|
||||
p.blocks[k].hashing_count
|
||||
+ p.blocks[k].reading_count
|
||||
+ p.blocks[k].flushing_count, &p);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1678,9 +1688,6 @@ int block_cache::copy_from_piece(cached_piece_entry* pe, disk_io_job* j, bool ex
|
|||
j->d.io.ref.block = start_block;
|
||||
j->buffer = bl.buf + (j->d.io.offset & (block_size()-1));
|
||||
++m_send_buffer_blocks;
|
||||
#if TORRENT_USE_ASSERTS
|
||||
++bl.reading_count;
|
||||
#endif
|
||||
return j->d.io.buffer_size;
|
||||
}
|
||||
|
||||
|
@ -1703,7 +1710,6 @@ int block_cache::copy_from_piece(cached_piece_entry* pe, disk_io_job* j, bool ex
|
|||
std::memcpy(j->buffer + buffer_offset
|
||||
, pe->blocks[block].buf + block_offset
|
||||
, to_copy);
|
||||
++pe->blocks[block].hitcount;
|
||||
size -= to_copy;
|
||||
block_offset = 0;
|
||||
buffer_offset += to_copy;
|
||||
|
|
Loading…
Reference in New Issue