forked from premiere/premiere-libtorrent
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:
parent
fa1e076d34
commit
6d66566298
|
@ -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 \
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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@
|
||||||
|
|
|
@ -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());
|
||||||
|
|
Loading…
Reference in New Issue