*** empty log message ***

This commit is contained in:
Arvid Norberg
2004-12-21 12:30:09 +00:00
parent bc774ff491
commit b55a1a6766
14 changed files with 166 additions and 54 deletions

View File

@@ -104,8 +104,12 @@ namespace libtorrent
{ {
public: public:
file_logger(boost::filesystem::path const& filename) file_logger(boost::filesystem::path const& filename)
: m_file(boost::filesystem::complete("libtorrent_logs" / filename)) {
{} using namespace boost::filesystem;
path dir(complete("libtorrent_logs"));
if (!exists(dir)) create_directories(dir);
m_file.open(dir / filename);
}
virtual void log(const char* text) { assert(text); m_file << text; } virtual void log(const char* text) { assert(text); m_file << text; }
boost::filesystem::ofstream m_file; boost::filesystem::ofstream m_file;

View File

@@ -82,12 +82,18 @@ namespace libtorrent
open_mode operator|(open_mode m) const open_mode operator|(open_mode m) const
{ return open_mode(m.m_mask | m_mask); } { return open_mode(m.m_mask | m_mask); }
open_mode operator&(open_mode m) const
{ return open_mode(m.m_mask & m_mask); }
open_mode operator|=(open_mode m) open_mode operator|=(open_mode m)
{ {
m_mask |= m.m_mask; m_mask |= m.m_mask;
return *this; return *this;
} }
bool operator==(open_mode m) const { return m_mask == m.m_mask; }
bool operator!=(open_mode m) const { return m_mask != m.m_mask; }
private: private:
open_mode(int val): m_mask(val) {} open_mode(int val): m_mask(val) {}

View File

@@ -65,17 +65,17 @@ namespace libtorrent
return std::count(m_number,m_number+number_size,0) == number_size; return std::count(m_number,m_number+number_size,0) == number_size;
} }
bool operator==(const big_number& n) const bool operator==(big_number const& n) const
{ {
return std::equal(n.m_number, n.m_number+number_size, m_number); return std::equal(n.m_number, n.m_number+number_size, m_number);
} }
bool operator!=(const big_number& n) const bool operator!=(big_number const& n) const
{ {
return !std::equal(n.m_number, n.m_number+number_size, m_number); return !std::equal(n.m_number, n.m_number+number_size, m_number);
} }
bool operator<(const big_number& n) const bool operator<(big_number const& n) const
{ {
for(int i = 0; i < number_size; ++i) for(int i = 0; i < number_size; ++i)
{ {

View File

@@ -175,7 +175,7 @@ namespace libtorrent
// in this struct // in this struct
mutable boost::mutex m_mutex; mutable boost::mutex m_mutex;
torrent* find_torrent(const sha1_hash& info_hash); torrent* find_torrent(const sha1_hash& info_hash);
const peer_id& get_peer_id() const { return m_peer_id; } peer_id const& get_peer_id() const { return m_peer_id; }
tracker_manager m_tracker_manager; tracker_manager m_tracker_manager;
torrent_map m_torrents; torrent_map m_torrents;
@@ -314,6 +314,8 @@ namespace libtorrent
void enable_extension(peer_connection::extension_index i); void enable_extension(peer_connection::extension_index i);
void disable_extensions(); void disable_extensions();
void set_peer_id(peer_id const& id);
bool is_listening() const; bool is_listening() const;
// if the listen port failed in some way // if the listen port failed in some way

View File

@@ -46,7 +46,7 @@ namespace libtorrent
class stat class stat
{ {
friend class invariant_access; friend class invariant_access;
enum { history = 5 }; enum { history = 10 };
public: public:
stat() stat()

View File

@@ -95,6 +95,11 @@ namespace libtorrent
bool move_storage(boost::filesystem::path save_path); bool move_storage(boost::filesystem::path save_path);
// this will close all open files that are opened for
// writing. This is called when a torrent has finished
// downloading.
void release();
#ifndef NDEBUG #ifndef NDEBUG
// overwrites some slots with the // overwrites some slots with the
// contents of others // contents of others
@@ -121,6 +126,8 @@ namespace libtorrent
, detail::piece_checker_data& data , detail::piece_checker_data& data
, std::vector<bool>& pieces); , std::vector<bool>& pieces);
void release();
void allocate_slots(int num_slots); void allocate_slots(int num_slots);
void mark_failed(int index); void mark_failed(int index);

View File

@@ -73,7 +73,7 @@ namespace
mode_t map_open_mode(int m) mode_t map_open_mode(int m)
{ {
// if (m == (mode_in | mode_out)) return O_RDWR | O_BINARY; if (m == (mode_in | mode_out)) return O_RDWR | O_CREAT | O_BINARY | O_RANDOM;
if (m == mode_out) return O_WRONLY | O_CREAT | O_BINARY | O_RANDOM; if (m == mode_out) return O_WRONLY | O_CREAT | O_BINARY | O_RANDOM;
if (m == mode_in) return O_RDONLY | O_BINARY | O_RANDOM; if (m == mode_in) return O_RDONLY | O_BINARY | O_RANDOM;
assert(false); assert(false);
@@ -138,7 +138,7 @@ namespace libtorrent
size_type read(char* buf, size_type num_bytes) size_type read(char* buf, size_type num_bytes)
{ {
assert(m_open_mode == mode_in); assert(m_open_mode & mode_in);
assert(m_fd != -1); assert(m_fd != -1);
size_type ret = ::read(m_fd, buf, num_bytes); size_type ret = ::read(m_fd, buf, num_bytes);
@@ -153,7 +153,7 @@ namespace libtorrent
size_type write(const char* buf, size_type num_bytes) size_type write(const char* buf, size_type num_bytes)
{ {
assert(m_open_mode == mode_out); assert(m_open_mode & mode_out);
assert(m_fd != -1); assert(m_fd != -1);
size_type ret = ::write(m_fd, buf, num_bytes); size_type ret = ::write(m_fd, buf, num_bytes);

View File

@@ -170,6 +170,7 @@ namespace
, map_entry("TS", "TorrentStorm") , map_entry("TS", "TorrentStorm")
, map_entry("U", "UPnP") , map_entry("U", "UPnP")
, map_entry("XT", "XanTorrent") , map_entry("XT", "XanTorrent")
, map_entry("eX", "eXeem")
}; };
bool compare_first_string(map_entry const& e, char const* str) bool compare_first_string(map_entry const& e, char const* str)

View File

@@ -1476,8 +1476,8 @@ namespace libtorrent
detail::write_uint32((int)m_torrent->metadata().size(), ptr); detail::write_uint32((int)m_torrent->metadata().size(), ptr);
detail::write_uint32(offset.first, ptr); detail::write_uint32(offset.first, ptr);
std::vector<char> const& metadata = m_torrent->metadata(); std::vector<char> const& metadata = m_torrent->metadata();
std::copy(&metadata[offset.first], &metadata[offset.first std::copy(metadata.begin() + offset.first
+ offset.second], ptr); , metadata.begin() + offset.first + offset.second, ptr);
} }
else else
{ {

View File

@@ -396,6 +396,10 @@ namespace libtorrent
void piece_picker::dec_refcount(int i) void piece_picker::dec_refcount(int i)
{ {
#ifndef NDEBUG
// integrity_check();
#endif
assert(i >= 0); assert(i >= 0);
assert(i < (int)m_piece_map.size()); assert(i < (int)m_piece_map.size());

View File

@@ -91,7 +91,7 @@ namespace
// so, the queue size is 5 * down_rate / 16 kiB (16 kB is the size of each request) // so, the queue size is 5 * down_rate / 16 kiB (16 kB is the size of each request)
// the minimum request size is 2 and the maximum is 100 // the minimum request size is 2 and the maximum is 100
int desired_queue_size = static_cast<int>(5.f * c.statistics().download_rate() / (16 * 1024)); int desired_queue_size = static_cast<int>(queue_time * c.statistics().download_rate() / (16 * 1024));
if (desired_queue_size > max_request_queue) desired_queue_size = max_request_queue; if (desired_queue_size > max_request_queue) desired_queue_size = max_request_queue;
if (desired_queue_size < min_request_queue) desired_queue_size = min_request_queue; if (desired_queue_size < min_request_queue) desired_queue_size = min_request_queue;

View File

@@ -120,7 +120,10 @@ namespace libtorrent { namespace detail
{ {
assert(t != 0); assert(t != 0);
t->parse_resume_data(t->resume_data, t->torrent_ptr->torrent_file()); t->parse_resume_data(t->resume_data, t->torrent_ptr->torrent_file());
t->resume_data = entry(); // clear the resume data now that it has been used
// clear the resume data now that it has been used
// (the fast resume data is now parsed and stored in t)
t->resume_data = entry();
t->torrent_ptr->check_files(*t, m_mutex); t->torrent_ptr->check_files(*t, m_mutex);
// lock the session to add the new torrent // lock the session to add the new torrent
@@ -128,9 +131,9 @@ namespace libtorrent { namespace detail
if (!t->abort) if (!t->abort)
{ {
boost::mutex::scoped_lock l(m_ses.m_mutex); boost::mutex::scoped_lock l(m_ses.m_mutex);
m_ses.m_torrents.insert( m_ses.m_torrents.insert(
std::make_pair(t->info_hash, t->torrent_ptr)).first; std::make_pair(t->info_hash, t->torrent_ptr)).first;
m_torrents.pop_front();
if (t->torrent_ptr->is_seed() && m_ses.m_alerts.should_post(alert::info)) if (t->torrent_ptr->is_seed() && m_ses.m_alerts.should_post(alert::info))
{ {
m_ses.m_alerts.post_alert(torrent_finished_alert( m_ses.m_alerts.post_alert(torrent_finished_alert(
@@ -150,7 +153,8 @@ namespace libtorrent { namespace detail
catch(const std::exception& e) catch(const std::exception& e)
{ {
// This will happen if the storage fails to initialize // This will happen if the storage fails to initialize
boost::mutex::scoped_lock l(m_ses.m_mutex); boost::mutex::scoped_lock l(m_mutex);
boost::mutex::scoped_lock l2(m_ses.m_mutex);
if (m_ses.m_alerts.should_post(alert::fatal)) if (m_ses.m_alerts.should_post(alert::fatal))
{ {
m_ses.m_alerts.post_alert( m_ses.m_alerts.post_alert(
@@ -158,6 +162,7 @@ namespace libtorrent { namespace detail
t->torrent_ptr->get_handle() t->torrent_ptr->get_handle()
, e.what())); , e.what()));
} }
m_torrents.pop_front();
} }
catch(...) catch(...)
{ {
@@ -165,12 +170,9 @@ namespace libtorrent { namespace detail
std::cerr << "error while checking files\n"; std::cerr << "error while checking files\n";
#endif #endif
assert(false); assert(false);
boost::mutex::scoped_lock l(m_mutex);
m_torrents.pop_front();
} }
// remove ourself from the 'checking'-list
// (we're no longer in the checking state)
boost::mutex::scoped_lock l(m_mutex);
m_torrents.pop_front();
} }
} }
@@ -868,6 +870,12 @@ namespace libtorrent
+ peer_connection::num_supported_extensions, false); + peer_connection::num_supported_extensions, false);
} }
void session::set_peer_id(peer_id const& id)
{
boost::mutex::scoped_lock l(m_impl.m_mutex);
m_impl.m_peer_id = id;
}
void session::enable_extension(peer_connection::extension_index i) void session::enable_extension(peer_connection::extension_index i)
{ {
assert(i >= 0); assert(i >= 0);
@@ -878,28 +886,24 @@ namespace libtorrent
std::vector<torrent_handle> session::get_torrents() std::vector<torrent_handle> session::get_torrents()
{ {
boost::mutex::scoped_lock l(m_checker_impl.m_mutex);
boost::mutex::scoped_lock l2(m_impl.m_mutex);
std::vector<torrent_handle> ret; std::vector<torrent_handle> ret;
for (std::deque<detail::piece_checker_data>::iterator i
= m_checker_impl.m_torrents.begin()
, end(m_checker_impl.m_torrents.end()); i != end; ++i)
{ {
boost::mutex::scoped_lock l(m_checker_impl.m_mutex); ret.push_back(torrent_handle(&m_impl, &m_checker_impl
for (std::deque<detail::piece_checker_data>::iterator i , i->info_hash));
= m_checker_impl.m_torrents.begin()
, end(m_checker_impl.m_torrents.end()); i != end; ++i)
{
ret.push_back(torrent_handle(&m_impl, &m_checker_impl
, i->info_hash));
}
} }
for (detail::session_impl::torrent_map::iterator i
= m_impl.m_torrents.begin(), end(m_impl.m_torrents.end());
i != end; ++i)
{ {
boost::mutex::scoped_lock l(m_impl.m_mutex); if (i->second->is_aborted()) continue;
for (detail::session_impl::torrent_map::iterator i ret.push_back(torrent_handle(&m_impl, &m_checker_impl
= m_impl.m_torrents.begin(), end(m_impl.m_torrents.end()); , i->first));
i != end; ++i)
{
if (i->second->is_aborted()) continue;
ret.push_back(torrent_handle(&m_impl, &m_checker_impl
, i->first));
}
} }
return ret; return ret;
} }

View File

@@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <iterator> #include <iterator>
#include <algorithm> #include <algorithm>
#include <set> #include <set>
#include <functional>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(push, 1) #pragma warning(push, 1)
@@ -49,6 +50,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/filesystem/fstream.hpp> #include <boost/filesystem/fstream.hpp>
#include <boost/thread/mutex.hpp> #include <boost/thread/mutex.hpp>
#include <boost/ref.hpp> #include <boost/ref.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/bind.hpp>
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(pop) #pragma warning(pop)
@@ -72,9 +75,12 @@ namespace std
#endif #endif
using namespace boost::filesystem; using namespace boost::filesystem;
namespace pt = boost::posix_time;
using boost::bind;
namespace namespace
{ {
using namespace libtorrent;
void print_to_log(const std::string& s) void print_to_log(const std::string& s)
{ {
@@ -93,6 +99,58 @@ namespace
else else
return t.name() / p; return t.name() / p;
} }
struct file_entry
{
file_entry(boost::shared_ptr<file> const& f_)
: f(f_)
, last_use(pt::second_clock::universal_time()) {}
boost::shared_ptr<file> f;
pt::ptime last_use;
file::open_mode mode;
};
struct file_pool
{
file_pool(int size): m_size(size) {}
boost::shared_ptr<file> open_file(path const& p, file::open_mode m)
{
typedef std::map<path, file_entry>::iterator iterator;
iterator i = m_files.find(p);
if (i != m_files.end())
{
i->second.last_use = pt::second_clock::universal_time();
if ((i->second.mode & m) != m)
{
i->second.f.reset(new file(p, m));
i->second.mode = m;
}
return i->second.f;
}
// the file is not in our cache
if ((int)m_files.size() >= m_size)
{
i = m_files.begin();
for (iterator j = boost::next(m_files.begin()); j != m_files.end(); ++j)
if (j->second.last_use < i->second.last_use) i = j;
m_files.erase(i);
}
file_entry e(boost::shared_ptr<file>(new file(p, m)));
e.mode = m;
m_files.insert(std::make_pair(p, e));
return e.f;
}
void release()
{
m_files.clear();
}
private:
int m_size;
std::map<path, file_entry> m_files;
};
} }
namespace libtorrent namespace libtorrent
@@ -194,6 +252,7 @@ namespace libtorrent
impl(torrent_info const& info, path const& path) impl(torrent_info const& info, path const& path)
: thread_safe_storage(info.num_pieces()) : thread_safe_storage(info.num_pieces())
, info(info) , info(info)
, files(10)
{ {
save_path = complete(path); save_path = complete(path);
assert(save_path.is_complete()); assert(save_path.is_complete());
@@ -203,10 +262,12 @@ namespace libtorrent
: thread_safe_storage(x.info.num_pieces()) : thread_safe_storage(x.info.num_pieces())
, info(x.info) , info(x.info)
, save_path(x.save_path) , save_path(x.save_path)
, files(x.files)
{} {}
torrent_info const& info; torrent_info const& info;
path save_path; path save_path;
file_pool files;
}; };
storage::storage(const torrent_info& info, const path& path) storage::storage(const torrent_info& info, const path& path)
@@ -215,6 +276,11 @@ namespace libtorrent
assert(info.begin_files() != info.end_files()); assert(info.begin_files() != info.end_files());
} }
void storage::release()
{
m_pimpl->files.release();
}
void storage::swap(storage& other) void storage::swap(storage& other)
{ {
m_pimpl.swap(other.m_pimpl); m_pimpl.swap(other.m_pimpl);
@@ -233,6 +299,8 @@ namespace libtorrent
else if(!is_directory(save_path)) else if(!is_directory(save_path))
return false; return false;
m_pimpl->files.release();
if (m_pimpl->info.num_files() == 1) if (m_pimpl->info.num_files() == 1)
{ {
path single_file = m_pimpl->info.begin_files()->path; path single_file = m_pimpl->info.begin_files()->path;
@@ -323,21 +391,21 @@ namespace libtorrent
++file_iter; ++file_iter;
} }
file in( boost::shared_ptr<file> in(m_pimpl->files.open_file(
m_pimpl->save_path / get_filename(m_pimpl->info, file_iter->path) m_pimpl->save_path / get_filename(m_pimpl->info, file_iter->path)
, file::in); , file::in));
assert(file_offset < file_iter->size); assert(file_offset < file_iter->size);
in.seek(file_offset); in->seek(file_offset);
if (in.tell() != file_offset) if (in->tell() != file_offset)
{ {
// the file was not big enough // the file was not big enough
throw file_error("slot has no storage"); throw file_error("slot has no storage");
} }
#ifndef NDEBUG #ifndef NDEBUG
size_type in_tell = in.tell(); size_type in_tell = in->tell();
assert(in_tell == file_offset); assert(in_tell == file_offset);
#endif #endif
@@ -358,7 +426,7 @@ namespace libtorrent
if (file_offset + read_bytes > file_iter->size) if (file_offset + read_bytes > file_iter->size)
read_bytes = static_cast<int>(file_iter->size - file_offset); read_bytes = static_cast<int>(file_iter->size - file_offset);
size_type actual_read = in.read(buf + buf_pos, read_bytes); size_type actual_read = in->read(buf + buf_pos, read_bytes);
if (read_bytes != actual_read) if (read_bytes != actual_read)
{ {
@@ -377,7 +445,8 @@ namespace libtorrent
path path = m_pimpl->save_path / get_filename(m_pimpl->info, file_iter->path); path path = m_pimpl->save_path / get_filename(m_pimpl->info, file_iter->path);
file_offset = 0; file_offset = 0;
in.open(path, file::in); in = m_pimpl->files.open_file(path, file::in);
in->seek(0);
} }
} }
@@ -415,12 +484,12 @@ namespace libtorrent
} }
path p(m_pimpl->save_path / get_filename(m_pimpl->info, file_iter->path)); path p(m_pimpl->save_path / get_filename(m_pimpl->info, file_iter->path));
file out(p, file::out); boost::shared_ptr<file> out = m_pimpl->files.open_file(p, file::out | file::in);
assert(file_offset < file_iter->size); assert(file_offset < file_iter->size);
out.seek(file_offset); out->seek(file_offset);
size_type pos = out.tell(); size_type pos = out->tell();
if (pos != file_offset) if (pos != file_offset)
{ {
@@ -450,7 +519,7 @@ namespace libtorrent
assert(buf_pos >= 0); assert(buf_pos >= 0);
assert(write_bytes > 0); assert(write_bytes > 0);
size_type written = out.write(buf + buf_pos, write_bytes); size_type written = out->write(buf + buf_pos, write_bytes);
if (written != write_bytes) if (written != write_bytes)
{ {
@@ -472,7 +541,8 @@ namespace libtorrent
assert(file_iter != m_pimpl->info.end_files()); assert(file_iter != m_pimpl->info.end_files());
path p = m_pimpl->save_path / get_filename(m_pimpl->info, file_iter->path); path p = m_pimpl->save_path / get_filename(m_pimpl->info, file_iter->path);
file_offset = 0; file_offset = 0;
out.open(p, file::out); out = m_pimpl->files.open_file(p, file::out | file::in);
out->seek(0);
} }
} }
} }
@@ -497,6 +567,8 @@ namespace libtorrent
, detail::piece_checker_data& data , detail::piece_checker_data& data
, std::vector<bool>& pieces); , std::vector<bool>& pieces);
void release();
void allocate_slots(int num_slots); void allocate_slots(int num_slots);
void mark_failed(int index); void mark_failed(int index);
unsigned long piece_crc( unsigned long piece_crc(
@@ -612,6 +684,16 @@ namespace libtorrent
{ {
} }
void piece_manager::release()
{
m_pimpl->release();
}
void piece_manager::impl::release()
{
m_storage.release();
}
void piece_manager::impl::export_piece_map( void piece_manager::impl::export_piece_map(
std::vector<int>& p) const std::vector<int>& p) const
{ {

View File

@@ -280,8 +280,6 @@ namespace libtorrent
m_last_working_tracker m_last_working_tracker
= prioritize_tracker(m_currently_trying_tracker); = prioritize_tracker(m_currently_trying_tracker);
m_next_request = second_clock::universal_time()
+ boost::posix_time::seconds(m_duration);
m_currently_trying_tracker = 0; m_currently_trying_tracker = 0;
m_duration = interval; m_duration = interval;
@@ -289,7 +287,7 @@ namespace libtorrent
{ {
// if the peer list is empty, we should contact the // if the peer list is empty, we should contact the
// tracker soon again to see if there are any peers // tracker soon again to see if there are any peers
m_next_request = second_clock::universal_time() + boost::posix_time::seconds(60); m_next_request = second_clock::universal_time() + boost::posix_time::minutes(2);
} }
else else
{ {
@@ -531,7 +529,6 @@ namespace libtorrent
tracker_request torrent::generate_tracker_request() tracker_request torrent::generate_tracker_request()
{ {
m_duration = 1800;
m_next_request m_next_request
= second_clock::universal_time() = second_clock::universal_time()
+ boost::posix_time::seconds(tracker_retry_delay_max); + boost::posix_time::seconds(tracker_retry_delay_max);
@@ -673,6 +670,8 @@ namespace libtorrent
i->second->disconnect(); i->second->disconnect();
} }
m_storage->release();
// make the next tracker request // make the next tracker request
// be a completed-event // be a completed-event
m_event = tracker_request::completed; m_event = tracker_request::completed;
@@ -807,6 +806,7 @@ namespace libtorrent
void torrent::pause() void torrent::pause()
{ {
if (m_paused) return;
disconnect_all(); disconnect_all();
m_paused = true; m_paused = true;
// tell the tracker that we stopped // tell the tracker that we stopped
@@ -816,6 +816,7 @@ namespace libtorrent
void torrent::resume() void torrent::resume()
{ {
if (!m_paused) return;
m_paused = false; m_paused = false;
// tell the tracker that we're back // tell the tracker that we're back
@@ -921,6 +922,7 @@ namespace libtorrent
assert(m_storage.get()); assert(m_storage.get());
assert(piece_index >= 0); assert(piece_index >= 0);
assert(piece_index < m_torrent_file.num_pieces()); assert(piece_index < m_torrent_file.num_pieces());
assert(piece_index < m_have_pieces.size());
int size = static_cast<int>(m_torrent_file.piece_size(piece_index)); int size = static_cast<int>(m_torrent_file.piece_size(piece_index));
std::vector<char> buffer(size); std::vector<char> buffer(size);