fixed problem with file pool when files were opened with 0 as info hash and attempted to close with the correct one. the info hash is no longer used as the key in the file pool. Also updated Makefile.am to include the buffer.hpp and .cpp and to include the storage unit test

This commit is contained in:
Arvid Norberg 2005-09-28 21:46:35 +00:00
parent fa1e076d34
commit 6d66566298
5 changed files with 48 additions and 30 deletions

View File

@ -3,6 +3,7 @@ libtorrent/alert_types.hpp \
libtorrent/allocate_resources.hpp \ libtorrent/allocate_resources.hpp \
libtorrent/async_gethostbyname.hpp \ libtorrent/async_gethostbyname.hpp \
libtorrent/bencode.hpp \ libtorrent/bencode.hpp \
libtorrent/buffer.hpp \
libtorrent/debug.hpp \ libtorrent/debug.hpp \
libtorrent/entry.hpp \ libtorrent/entry.hpp \
libtorrent/escape_string.hpp \ libtorrent/escape_string.hpp \

View File

@ -1,7 +1,7 @@
lib_LTLIBRARIES = libtorrent.la lib_LTLIBRARIES = libtorrent.la
libtorrent_la_SOURCES = allocate_resources.cpp async_gethostbyname.cpp \ libtorrent_la_SOURCES = allocate_resources.cpp async_gethostbyname.cpp \
entry.cpp escape_string.cpp \ buffer.cpp entry.cpp escape_string.cpp \
peer_connection.cpp piece_picker.cpp policy.cpp \ peer_connection.cpp piece_picker.cpp policy.cpp \
session.cpp sha1.cpp socket.cpp stat.cpp \ session.cpp sha1.cpp socket.cpp stat.cpp \
storage.cpp torrent.cpp torrent_handle.cpp \ storage.cpp torrent.cpp torrent_handle.cpp \
@ -15,6 +15,7 @@ $(top_srcdir)/include/libtorrent/alert_types.hpp \
$(top_srcdir)/include/libtorrent/allocate_resources.hpp \ $(top_srcdir)/include/libtorrent/allocate_resources.hpp \
$(top_srcdir)/include/libtorrent/async_gethostbyname.hpp \ $(top_srcdir)/include/libtorrent/async_gethostbyname.hpp \
$(top_srcdir)/include/libtorrent/bencode.hpp \ $(top_srcdir)/include/libtorrent/bencode.hpp \
$(top_srcdir)/include/libtorrent/buffer.hpp \
$(top_srcdir)/include/libtorrent/debug.hpp \ $(top_srcdir)/include/libtorrent/debug.hpp \
$(top_srcdir)/include/libtorrent/entry.hpp \ $(top_srcdir)/include/libtorrent/entry.hpp \
$(top_srcdir)/include/libtorrent/escape_string.hpp \ $(top_srcdir)/include/libtorrent/escape_string.hpp \

View File

@ -194,7 +194,7 @@ namespace
log << s; log << s;
log.flush(); log.flush();
} }
/*
struct file_key struct file_key
{ {
file_key(sha1_hash ih, path f): info_hash(ih), file_path(f) {} file_key(sha1_hash ih, path f): info_hash(ih), file_path(f) {}
@ -208,14 +208,15 @@ namespace
return file_path < fk.file_path; return file_path < fk.file_path;
} }
}; };
*/
struct file_entry struct file_entry
{ {
file_entry(boost::shared_ptr<file> const& f) file_entry(boost::shared_ptr<file> const& f)
: file_ptr(f) : file_ptr(f)
, last_use(pt::second_clock::universal_time()) {} , last_use(pt::second_clock::universal_time()) {}
mutable boost::shared_ptr<file> file_ptr; mutable boost::shared_ptr<file> file_ptr;
file_key key; path file_path;
void* key;
pt::ptime last_use; pt::ptime last_use;
file::open_mode mode; file::open_mode mode;
}; };
@ -224,16 +225,23 @@ namespace
{ {
file_pool(int size): m_size(size) {} file_pool(int size): m_size(size) {}
boost::shared_ptr<file> open_file(sha1_hash const& info_hash, path const& p, file::open_mode m) boost::shared_ptr<file> open_file(void* st, path const& p, file::open_mode m)
{ {
assert(st != 0);
assert(p.is_complete()); assert(p.is_complete());
typedef file_set::nth_index<0>::type path_view; typedef file_set::nth_index<0>::type path_view;
path_view& pt = m_files.get<0>(); path_view& pt = m_files.get<0>();
path_view::iterator i = pt.find(file_key(info_hash, p)); path_view::iterator i = pt.find(p);
if (i != pt.end()) if (i != pt.end())
{ {
file_entry e = *i; file_entry e = *i;
e.last_use = pt::second_clock::universal_time(); e.last_use = pt::second_clock::universal_time();
// if you hit this assert, you probably have more than one
// storage/torrent using the same file at the same time!
assert(e.key == st);
e.key = st;
if ((e.mode & m) != m) if ((e.mode & m) != m)
{ {
// close the file before we open it with // close the file before we open it with
@ -265,24 +273,23 @@ namespace
} }
file_entry e(boost::shared_ptr<file>(new file(p, m))); file_entry e(boost::shared_ptr<file>(new file(p, m)));
e.mode = m; e.mode = m;
e.key.info_hash = info_hash; e.key = st;
e.key.file_path = p; e.file_path = p;
pt.insert(e); pt.insert(e);
return e.file_ptr; return e.file_ptr;
} }
void release(sha1_hash const& info_hash) void release(void* st)
{ {
using namespace boost::lambda; assert(st != 0);
using boost::lambda::_1; using boost::tie;
typedef file_set::nth_index<2>::type key_view;
key_view& kt = m_files.get<2>();
key_view::iterator start, end;
tie(start, end) = kt.equal_range(st);
typedef file_set::nth_index<0>::type path_view;
path_view& pt = m_files.get<0>();
file_key lower_key(info_hash, path());
file_key upper_key(info_hash, path());
upper_key.info_hash[19] += 1;
std::pair<path_view::iterator, path_view::iterator> r
= pt.range(!(_1 < lower_key), _1 < upper_key);
/* /*
std::cerr << "releasing files!\n"; std::cerr << "releasing files!\n";
for (path_view::iterator i = r.first; i != r.second; ++i) for (path_view::iterator i = r.first; i != r.second; ++i)
@ -290,7 +297,7 @@ namespace
std::cerr << i->key.file_path.native_file_string() << "\n"; std::cerr << i->key.file_path.native_file_string() << "\n";
} }
*/ */
pt.erase(r.first, r.second); kt.erase(start, end);
/* /*
std::cerr << "files left: " << pt.size() << "\n"; std::cerr << "files left: " << pt.size() << "\n";
for (path_view::iterator i = pt.begin(); i != pt.end(); ++i) for (path_view::iterator i = pt.begin(); i != pt.end(); ++i)
@ -305,9 +312,12 @@ namespace
typedef boost::multi_index_container< typedef boost::multi_index_container<
file_entry, indexed_by< file_entry, indexed_by<
ordered_unique<member<file_entry, file_key, &file_entry::key> > ordered_unique<member<file_entry, path
, &file_entry::file_path> >
, ordered_non_unique<member<file_entry, pt::ptime , ordered_non_unique<member<file_entry, pt::ptime
, &file_entry::last_use> > , &file_entry::last_use> >
, ordered_non_unique<member<file_entry, void*
, &file_entry::key> >
> >
> file_set; > file_set;
@ -430,7 +440,7 @@ namespace libtorrent
int slot; int slot;
}; };
class storage::impl : public thread_safe_storage class storage::impl : public thread_safe_storage, boost::noncopyable
{ {
public: public:
impl(torrent_info const& info, path const& path) impl(torrent_info const& info, path const& path)
@ -449,7 +459,7 @@ namespace libtorrent
~impl() ~impl()
{ {
files.release(info.info_hash()); files.release(this);
} }
torrent_info const& info; torrent_info const& info;
@ -467,7 +477,7 @@ namespace libtorrent
void storage::release_files() void storage::release_files()
{ {
m_pimpl->files.release(m_pimpl->info.info_hash()); m_pimpl->files.release(m_pimpl.get());
} }
void storage::swap(storage& other) void storage::swap(storage& other)
@ -500,7 +510,7 @@ namespace libtorrent
return false; return false;
#endif #endif
m_pimpl->files.release(m_pimpl->info.info_hash()); m_pimpl->files.release(m_pimpl.get());
if (m_pimpl->info.num_files() == 1) if (m_pimpl->info.num_files() == 1)
{ {
@ -601,7 +611,7 @@ namespace libtorrent
} }
boost::shared_ptr<file> in(m_pimpl->files.open_file( boost::shared_ptr<file> in(m_pimpl->files.open_file(
m_pimpl->info.info_hash() m_pimpl.get()
, m_pimpl->save_path / file_iter->path , m_pimpl->save_path / file_iter->path
, file::in)); , file::in));
@ -656,7 +666,7 @@ namespace libtorrent
file_offset = 0; file_offset = 0;
in = m_pimpl->files.open_file( in = m_pimpl->files.open_file(
m_pimpl->info.info_hash() m_pimpl.get()
, path, file::in); , path, file::in);
in->seek(0); in->seek(0);
} }
@ -698,7 +708,7 @@ namespace libtorrent
path p(m_pimpl->save_path / file_iter->path); path p(m_pimpl->save_path / file_iter->path);
boost::shared_ptr<file> out = m_pimpl->files.open_file( boost::shared_ptr<file> out = m_pimpl->files.open_file(
m_pimpl->info.info_hash() m_pimpl.get()
, p, file::out | file::in); , p, file::out | file::in);
assert(file_offset < file_iter->size); assert(file_offset < file_iter->size);
@ -757,7 +767,7 @@ namespace libtorrent
path p = m_pimpl->save_path / file_iter->path; path p = m_pimpl->save_path / file_iter->path;
file_offset = 0; file_offset = 0;
out = m_pimpl->files.open_file( out = m_pimpl->files.open_file(
m_pimpl->info.info_hash() m_pimpl.get()
, p, file::out | file::in); , p, file::out | file::in);
out->seek(0); out->seek(0);

View File

@ -13,6 +13,9 @@ test_ip_filter_LDADD = $(top_builddir)/src/libtorrent.la
test_piece_picker_SOURCES = main.cpp test_piece_picker.cpp test_piece_picker_SOURCES = main.cpp test_piece_picker.cpp
test_piece_picker_LDADD = $(top_builddir)/src/libtorrent.la test_piece_picker_LDADD = $(top_builddir)/src/libtorrent.la
test_storage_SOURCES = main.cpp test_storage.cpp
test_storage_LDADD = $(top_builddir)/src/libtorrent.la
noinst_HEADERS = test.hpp noinst_HEADERS = test.hpp
AM_CXXFLAGS=-ftemplate-depth-50 -I$(top_srcdir)/include @DEBUGFLAGS@ @PTHREAD_CFLAGS@ AM_CXXFLAGS=-ftemplate-depth-50 -I$(top_srcdir)/include @DEBUGFLAGS@ @PTHREAD_CFLAGS@

View File

@ -44,6 +44,9 @@ int test_main()
int num_pieces = (613 + 17 + piece_size - 1) / piece_size; int num_pieces = (613 + 17 + piece_size - 1) / piece_size;
TEST_CHECK(info.num_pieces() == num_pieces); TEST_CHECK(info.num_pieces() == num_pieces);
char piece[piece_size];
{ // avoid having two storages use the same files
storage s(info, initial_path()); storage s(info, initial_path());
// write piece 1 (in slot 0) // write piece 1 (in slot 0)
@ -51,7 +54,6 @@ int test_main()
s.write(piece1 + half, 0, half, half); s.write(piece1 + half, 0, half, half);
// verify piece 1 // verify piece 1
char piece[piece_size];
s.read(piece, 0, 0, piece_size); s.read(piece, 0, 0, piece_size);
TEST_CHECK(std::equal(piece, piece + piece_size, piece1)); TEST_CHECK(std::equal(piece, piece + piece_size, piece1));
@ -69,6 +71,7 @@ int test_main()
// make sure the files have the correct size // make sure the files have the correct size
TEST_CHECK(file_size(initial_path() / "temp_storage" / "test1.tmp") == 17); TEST_CHECK(file_size(initial_path() / "temp_storage" / "test1.tmp") == 17);
TEST_CHECK(file_size(initial_path() / "temp_storage" / "test2.tmp") == 31); TEST_CHECK(file_size(initial_path() / "temp_storage" / "test2.tmp") == 31);
}
// make sure the piece_manager can identify the pieces // make sure the piece_manager can identify the pieces
piece_manager pm(info, initial_path()); piece_manager pm(info, initial_path());