mirror of
https://git.deluge-torrent.org/deluge
synced 2025-04-21 20:14:51 +00:00
revert lt sync for later testing
This commit is contained in:
parent
4dd7e38358
commit
0b746d2ab1
123 changed files with 2461 additions and 5456 deletions
|
@ -25,8 +25,6 @@ extern char const* peer_error_alert_doc;
|
|||
extern char const* invalid_request_alert_doc;
|
||||
extern char const* peer_request_doc;
|
||||
extern char const* torrent_finished_alert_doc;
|
||||
extern char const* torrent_paused_alert_doc;
|
||||
extern char const* storage_moved_alert_doc;
|
||||
extern char const* metadata_failed_alert_doc;
|
||||
extern char const* metadata_received_alert_doc;
|
||||
extern char const* fastresume_rejected_alert_doc;
|
||||
|
@ -142,18 +140,7 @@ void bind_alert()
|
|||
)
|
||||
.def_readonly("handle", &torrent_finished_alert::handle)
|
||||
;
|
||||
|
||||
class_<torrent_paused_alert, bases<alert>, noncopyable>(
|
||||
"torrent_paused_alert", torrent_paused_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("handle", &torrent_paused_alert::handle)
|
||||
;
|
||||
|
||||
class_<storage_moved_alert, bases<alert>, noncopyable>(
|
||||
"storage_moved_alert", storage_moved_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("handle", &storage_moved_alert::handle)
|
||||
;
|
||||
|
||||
class_<metadata_failed_alert, bases<alert>, noncopyable>(
|
||||
"metadata_failed_alert", metadata_failed_alert_doc, no_init
|
||||
)
|
||||
|
|
|
@ -164,14 +164,14 @@ char const* session_set_severity_level_doc =
|
|||
"";
|
||||
char const* session_pop_alert_doc =
|
||||
"";
|
||||
char const* session_start_upnp_doc =
|
||||
char const* session_start_upnp_doc =
|
||||
"";
|
||||
char const* session_stop_upnp_doc =
|
||||
char const* session_stop_upnp_doc =
|
||||
"";
|
||||
char const* session_start_natpmp_doc =
|
||||
"";
|
||||
char const* session_stop_natpmp_doc =
|
||||
char const* session_start_natpmp_doc =
|
||||
"";
|
||||
char const* session_stop_natpmp_doc =
|
||||
"";
|
||||
// -- alert -----------------------------------------------------------------
|
||||
|
||||
char const* alert_doc =
|
||||
|
@ -257,17 +257,6 @@ char const* torrent_finished_alert_doc =
|
|||
"It contains a `torrent_handle` to the torrent in question. This alert\n"
|
||||
"is generated as severity level `alert.severity_levels.info`.";
|
||||
|
||||
char const* torrent_paused_alert_doc =
|
||||
"This alert is generated when a torrent switches from being a\n"
|
||||
"active to paused.\n"
|
||||
"It contains a `torrent_handle` to the torrent in question. This alert\n"
|
||||
"is generated as severity level `alert.severity_levels.warning`.";
|
||||
|
||||
char const* storage_moved_alert_doc =
|
||||
"This alert is generated when a torrent moves storage.\n"
|
||||
"It contains a `torrent_handle` to the torrent in question. This alert\n"
|
||||
"is generated as severity level `alert.severity_levels.warning`.";
|
||||
|
||||
char const* metadata_failed_alert_doc =
|
||||
"This alert is generated when the metadata has been completely\n"
|
||||
"received and the info-hash failed to match it. i.e. the\n"
|
||||
|
|
|
@ -142,6 +142,7 @@ void bind_extensions()
|
|||
// TODO move to it's own file
|
||||
class_<peer_connection, boost::noncopyable>("peer_connection", no_init);
|
||||
|
||||
class_<torrent_plugin, boost::shared_ptr<torrent_plugin> >("torrent_plugin", no_init);
|
||||
def("create_ut_pex_plugin", create_ut_pex_plugin);
|
||||
def("create_metadata_plugin", create_metadata_plugin);
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ extern char const* session_set_max_connections_doc;
|
|||
extern char const* session_set_max_half_open_connections_doc;
|
||||
extern char const* session_set_settings_doc;
|
||||
extern char const* session_set_pe_settings_doc;
|
||||
extern char const* session_get_pe_settings_doc;
|
||||
extern char const* session_get_pe_settings_doc;
|
||||
extern char const* session_set_severity_level_doc;
|
||||
extern char const* session_pop_alert_doc;
|
||||
extern char const* session_start_upnp_doc;
|
||||
|
@ -86,10 +86,11 @@ namespace
|
|||
|
||||
torrent_handle add_torrent(session& s, torrent_info const& ti
|
||||
, boost::filesystem::path const& save, entry const& resume
|
||||
, bool compact, bool paused)
|
||||
, bool compact, int block_size)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return s.add_torrent(ti, save, resume, compact, paused, default_storage_constructor);
|
||||
return s.add_torrent(ti, save, resume, compact, block_size
|
||||
, default_storage_constructor);
|
||||
}
|
||||
|
||||
} // namespace unnamed
|
||||
|
@ -174,7 +175,7 @@ void bind_session()
|
|||
"add_torrent", &add_torrent
|
||||
, (
|
||||
arg("torrent_info"), "save_path", arg("resume_data") = entry()
|
||||
, arg("compact_mode") = true, arg("paused") = false
|
||||
, arg("compact_mode") = true, arg("block_size") = 16 * 1024
|
||||
)
|
||||
, session_add_torrent_doc
|
||||
)
|
||||
|
|
|
@ -47,7 +47,7 @@ void bind_session_settings()
|
|||
.value("http", proxy_settings::http)
|
||||
.value("http_pw", proxy_settings::http_pw)
|
||||
;
|
||||
class_<proxy_settings>("proxy_settings")
|
||||
class_<proxy_settings>("proxy_settings")
|
||||
.def_readwrite("hostname", &proxy_settings::hostname)
|
||||
.def_readwrite("port", &proxy_settings::port)
|
||||
.def_readwrite("password", &proxy_settings::password)
|
||||
|
@ -64,7 +64,7 @@ void bind_session_settings()
|
|||
enum_<pe_settings::enc_level>("enc_level")
|
||||
.value("rc4", pe_settings::rc4)
|
||||
.value("plaintext", pe_settings::plaintext)
|
||||
.value("both", pe_settings::both)
|
||||
.value("both", pe_settings::both)
|
||||
;
|
||||
|
||||
class_<pe_settings>("pe_settings")
|
||||
|
|
|
@ -16,6 +16,7 @@ namespace
|
|||
return i.trackers().begin();
|
||||
}
|
||||
|
||||
|
||||
std::vector<announce_entry>::const_iterator end_trackers(torrent_info& i)
|
||||
{
|
||||
return i.trackers().end();
|
||||
|
@ -40,29 +41,6 @@ namespace
|
|||
return result;
|
||||
}
|
||||
|
||||
std::vector<file_entry>::const_iterator begin_files(torrent_info& i, bool storage)
|
||||
{
|
||||
return i.begin_files(storage);
|
||||
}
|
||||
|
||||
std::vector<file_entry>::const_iterator end_files(torrent_info& i, bool storage)
|
||||
{
|
||||
return i.end_files(storage);
|
||||
}
|
||||
|
||||
//list files(torrent_info const& ti, bool storage) {
|
||||
list files(torrent_info const& ti, bool storage) {
|
||||
list result;
|
||||
|
||||
typedef std::vector<file_entry> list_type;
|
||||
|
||||
for (list_type::const_iterator i = ti.begin_files(storage); i != ti.end_files(storage); ++i)
|
||||
result.append(*i);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
} // namespace unnamed
|
||||
|
||||
void bind_torrent_info()
|
||||
|
@ -93,9 +71,9 @@ void bind_torrent_info()
|
|||
.def("hash_for_piece", &torrent_info::hash_for_piece, copy)
|
||||
.def("piece_size", &torrent_info::piece_size)
|
||||
|
||||
.def("num_files", &torrent_info::num_files, (arg("storage")=false))
|
||||
.def("num_files", &torrent_info::num_files)
|
||||
.def("file_at", &torrent_info::file_at, return_internal_reference<>())
|
||||
.def("files", &files, (arg("storage")=false))
|
||||
.def("files", range(&torrent_info::begin_files, &torrent_info::end_files))
|
||||
|
||||
.def("priv", &torrent_info::priv)
|
||||
.def("set_priv", &torrent_info::set_priv)
|
||||
|
@ -106,8 +84,9 @@ void bind_torrent_info()
|
|||
.def("add_node", &add_node)
|
||||
.def("nodes", &nodes)
|
||||
;
|
||||
|
||||
class_<file_entry>("file_entry")
|
||||
.add_property(
|
||||
.add_property(
|
||||
"path"
|
||||
, make_getter(
|
||||
&file_entry::path, return_value_policy<copy_non_const_reference>()
|
||||
|
|
|
@ -238,9 +238,6 @@ public:
|
|||
* with the asio::error::operation_aborted error.
|
||||
*
|
||||
* @throws asio::system_error Thrown on failure.
|
||||
*
|
||||
* @note For portable behaviour with respect to graceful closure of a
|
||||
* connected socket, call shutdown() before closing the socket.
|
||||
*/
|
||||
void close()
|
||||
{
|
||||
|
@ -268,9 +265,6 @@ public:
|
|||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @note For portable behaviour with respect to graceful closure of a
|
||||
* connected socket, call shutdown() before closing the socket.
|
||||
*/
|
||||
asio::error_code close(asio::error_code& ec)
|
||||
{
|
||||
|
|
|
@ -542,10 +542,9 @@ inline const_buffers_1 buffer(const PodType (&data)[N],
|
|||
? N * sizeof(PodType) : max_size_in_bytes));
|
||||
}
|
||||
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \
|
||||
|| BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||
|
||||
// Borland C++ and Sun Studio think the overloads:
|
||||
// Borland C++ thinks the overloads:
|
||||
//
|
||||
// unspecified buffer(boost::array<PodType, N>& array ...);
|
||||
//
|
||||
|
@ -611,7 +610,6 @@ buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes)
|
|||
}
|
||||
|
||||
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||
// || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||
|
||||
/// Create a new modifiable buffer that represents the given POD array.
|
||||
template <typename PodType, std::size_t N>
|
||||
|
@ -652,7 +650,6 @@ inline const_buffers_1 buffer(boost::array<const PodType, N>& data,
|
|||
}
|
||||
|
||||
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||
// || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||
|
||||
/// Create a new non-modifiable buffer that represents the given POD array.
|
||||
template <typename PodType, std::size_t N>
|
||||
|
|
|
@ -71,28 +71,6 @@ private:
|
|||
/// Return a completion condition function object that indicates that a read or
|
||||
/// write operation should continue until all of the data has been transferred,
|
||||
/// or until an error occurs.
|
||||
/**
|
||||
* This function is used to create an object, of unspecified type, that meets
|
||||
* CompletionCondition requirements.
|
||||
*
|
||||
* @par Example
|
||||
* Reading until a buffer is full:
|
||||
* @code
|
||||
* boost::array<char, 128> buf;
|
||||
* asio::error_code ec;
|
||||
* std::size_t n = asio::read(
|
||||
* sock, asio::buffer(buf),
|
||||
* asio::transfer_all(), ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // n == 128
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
unspecified transfer_all();
|
||||
#else
|
||||
|
@ -105,28 +83,6 @@ inline detail::transfer_all_t transfer_all()
|
|||
/// Return a completion condition function object that indicates that a read or
|
||||
/// write operation should continue until a minimum number of bytes has been
|
||||
/// transferred, or until an error occurs.
|
||||
/**
|
||||
* This function is used to create an object, of unspecified type, that meets
|
||||
* CompletionCondition requirements.
|
||||
*
|
||||
* @par Example
|
||||
* Reading until a buffer is full or contains at least 64 bytes:
|
||||
* @code
|
||||
* boost::array<char, 128> buf;
|
||||
* asio::error_code ec;
|
||||
* std::size_t n = asio::read(
|
||||
* sock, asio::buffer(buf),
|
||||
* asio::transfer_at_least(64), ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // n >= 64 && n <= 128
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
unspecified transfer_at_least(std::size_t minimum);
|
||||
#else
|
||||
|
|
|
@ -157,8 +157,7 @@ public:
|
|||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
if (result != 0)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(errno, asio::native_ecat);
|
||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
|
@ -191,8 +190,7 @@ public:
|
|||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
if (result != 0)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(errno, asio::native_ecat);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
|
@ -221,8 +219,7 @@ public:
|
|||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
if (result != 0)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(errno, asio::native_ecat);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
|
@ -253,8 +250,7 @@ public:
|
|||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
if (result != 0)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(errno, asio::native_ecat);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
|
@ -335,10 +331,7 @@ public:
|
|||
std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
std::size_t n = timer_queue.cancel_timer(token);
|
||||
if (n > 0)
|
||||
interrupter_.interrupt();
|
||||
return n;
|
||||
return timer_queue.cancel_timer(token);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -354,13 +347,16 @@ private:
|
|||
read_op_queue_.dispatch_cancellations();
|
||||
write_op_queue_.dispatch_cancellations();
|
||||
except_op_queue_.dispatch_cancellations();
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
timer_queues_[i]->dispatch_cancellations();
|
||||
|
||||
// Check if the thread is supposed to stop.
|
||||
if (stop_thread_)
|
||||
{
|
||||
cleanup_operations_and_timers(lock);
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -369,7 +365,12 @@ private:
|
|||
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
|
||||
&& except_op_queue_.empty() && all_timer_queues_are_empty())
|
||||
{
|
||||
cleanup_operations_and_timers(lock);
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -397,45 +398,59 @@ private:
|
|||
}
|
||||
else
|
||||
{
|
||||
bool more_reads = false;
|
||||
bool more_writes = false;
|
||||
bool more_except = false;
|
||||
asio::error_code ec;
|
||||
|
||||
// Exception operations must be processed first to ensure that any
|
||||
// out-of-band data is read before normal data.
|
||||
if (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP))
|
||||
more_except = except_op_queue_.dispatch_operation(descriptor, ec);
|
||||
else
|
||||
more_except = except_op_queue_.has_operation(descriptor);
|
||||
|
||||
if (events[i].events & (EPOLLIN | EPOLLERR | EPOLLHUP))
|
||||
more_reads = read_op_queue_.dispatch_operation(descriptor, ec);
|
||||
else
|
||||
more_reads = read_op_queue_.has_operation(descriptor);
|
||||
|
||||
if (events[i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP))
|
||||
more_writes = write_op_queue_.dispatch_operation(descriptor, ec);
|
||||
else
|
||||
more_writes = write_op_queue_.has_operation(descriptor);
|
||||
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
ev.events = EPOLLERR | EPOLLHUP;
|
||||
if (more_reads)
|
||||
ev.events |= EPOLLIN;
|
||||
if (more_writes)
|
||||
ev.events |= EPOLLOUT;
|
||||
if (more_except)
|
||||
ev.events |= EPOLLPRI;
|
||||
ev.data.fd = descriptor;
|
||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
if (result != 0)
|
||||
if (events[i].events & (EPOLLERR | EPOLLHUP))
|
||||
{
|
||||
ec = asio::error_code(errno,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec;
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
ev.events = 0;
|
||||
ev.data.fd = descriptor;
|
||||
epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool more_reads = false;
|
||||
bool more_writes = false;
|
||||
bool more_except = false;
|
||||
asio::error_code ec;
|
||||
|
||||
// Exception operations must be processed first to ensure that any
|
||||
// out-of-band data is read before normal data.
|
||||
if (events[i].events & EPOLLPRI)
|
||||
more_except = except_op_queue_.dispatch_operation(descriptor, ec);
|
||||
else
|
||||
more_except = except_op_queue_.has_operation(descriptor);
|
||||
|
||||
if (events[i].events & EPOLLIN)
|
||||
more_reads = read_op_queue_.dispatch_operation(descriptor, ec);
|
||||
else
|
||||
more_reads = read_op_queue_.has_operation(descriptor);
|
||||
|
||||
if (events[i].events & EPOLLOUT)
|
||||
more_writes = write_op_queue_.dispatch_operation(descriptor, ec);
|
||||
else
|
||||
more_writes = write_op_queue_.has_operation(descriptor);
|
||||
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
ev.events = EPOLLERR | EPOLLHUP;
|
||||
if (more_reads)
|
||||
ev.events |= EPOLLIN;
|
||||
if (more_writes)
|
||||
ev.events |= EPOLLOUT;
|
||||
if (more_except)
|
||||
ev.events |= EPOLLPRI;
|
||||
ev.data.fd = descriptor;
|
||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
if (result != 0)
|
||||
{
|
||||
ec = asio::error_code(errno, asio::native_ecat);
|
||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -443,17 +458,19 @@ private:
|
|||
write_op_queue_.dispatch_cancellations();
|
||||
except_op_queue_.dispatch_cancellations();
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
{
|
||||
timer_queues_[i]->dispatch_timers();
|
||||
timer_queues_[i]->dispatch_cancellations();
|
||||
}
|
||||
|
||||
// Issue any pending cancellations.
|
||||
for (size_t i = 0; i < pending_cancellations_.size(); ++i)
|
||||
cancel_ops_unlocked(pending_cancellations_[i]);
|
||||
pending_cancellations_.clear();
|
||||
|
||||
cleanup_operations_and_timers(lock);
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
}
|
||||
|
||||
// Run the select loop in the thread.
|
||||
|
@ -490,10 +507,8 @@ private:
|
|||
int fd = epoll_create(epoll_size);
|
||||
if (fd == -1)
|
||||
{
|
||||
boost::throw_exception(
|
||||
asio::system_error(
|
||||
asio::error_code(errno,
|
||||
asio::error::system_category),
|
||||
boost::throw_exception(asio::system_error(
|
||||
asio::error_code(errno, asio::native_ecat),
|
||||
"epoll"));
|
||||
}
|
||||
return fd;
|
||||
|
@ -551,22 +566,6 @@ private:
|
|||
interrupter_.interrupt();
|
||||
}
|
||||
|
||||
// Clean up operations and timers. We must not hold the lock since the
|
||||
// destructors may make calls back into this reactor. We make a copy of the
|
||||
// vector of timer queues since the original may be modified while the lock
|
||||
// is not held.
|
||||
void cleanup_operations_and_timers(
|
||||
asio::detail::mutex::scoped_lock& lock)
|
||||
{
|
||||
timer_queues_for_cleanup_ = timer_queues_;
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i)
|
||||
timer_queues_for_cleanup_[i]->cleanup_timers();
|
||||
}
|
||||
|
||||
// Mutex to protect access to internal data.
|
||||
asio::detail::mutex mutex_;
|
||||
|
||||
|
@ -591,10 +590,6 @@ private:
|
|||
// The timer queues.
|
||||
std::vector<timer_queue_base*> timer_queues_;
|
||||
|
||||
// A copy of the timer queues, used when cleaning up timers. The copy is
|
||||
// stored as a class data member to avoid unnecessary memory allocation.
|
||||
std::vector<timer_queue_base*> timer_queues_for_cleanup_;
|
||||
|
||||
// The descriptors that are pending cancellation.
|
||||
std::vector<socket_type> pending_cancellations_;
|
||||
|
||||
|
|
|
@ -150,8 +150,7 @@ public:
|
|||
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0);
|
||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(errno, asio::native_ecat);
|
||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
|
@ -177,8 +176,7 @@ public:
|
|||
EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
|
||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(errno, asio::native_ecat);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
|
@ -203,8 +201,7 @@ public:
|
|||
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0);
|
||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(errno, asio::native_ecat);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
|
@ -227,8 +224,7 @@ public:
|
|||
EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
|
||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(errno, asio::native_ecat);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
|
@ -242,8 +238,7 @@ public:
|
|||
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0);
|
||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(errno, asio::native_ecat);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
|
@ -326,10 +321,7 @@ public:
|
|||
std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
std::size_t n = timer_queue.cancel_timer(token);
|
||||
if (n > 0)
|
||||
interrupter_.interrupt();
|
||||
return n;
|
||||
return timer_queue.cancel_timer(token);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -345,13 +337,16 @@ private:
|
|||
read_op_queue_.dispatch_cancellations();
|
||||
write_op_queue_.dispatch_cancellations();
|
||||
except_op_queue_.dispatch_cancellations();
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
timer_queues_[i]->dispatch_cancellations();
|
||||
|
||||
// Check if the thread is supposed to stop.
|
||||
if (stop_thread_)
|
||||
{
|
||||
cleanup_operations_and_timers(lock);
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -360,7 +355,12 @@ private:
|
|||
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
|
||||
&& except_op_queue_.empty() && all_timer_queues_are_empty())
|
||||
{
|
||||
cleanup_operations_and_timers(lock);
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -397,7 +397,7 @@ private:
|
|||
if (events[i].flags & EV_ERROR)
|
||||
{
|
||||
asio::error_code error(
|
||||
events[i].data, asio::error::system_category);
|
||||
events[i].data, asio::native_ecat);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, error);
|
||||
read_op_queue_.dispatch_all_operations(descriptor, error);
|
||||
}
|
||||
|
@ -427,8 +427,7 @@ private:
|
|||
EV_SET(&event, descriptor, EVFILT_READ, EV_DELETE, 0, 0, 0);
|
||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code error(errno,
|
||||
asio::error::system_category);
|
||||
asio::error_code error(errno, asio::native_ecat);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, error);
|
||||
read_op_queue_.dispatch_all_operations(descriptor, error);
|
||||
}
|
||||
|
@ -440,7 +439,7 @@ private:
|
|||
if (events[i].flags & EV_ERROR)
|
||||
{
|
||||
asio::error_code error(
|
||||
events[i].data, asio::error::system_category);
|
||||
events[i].data, asio::native_ecat);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, error);
|
||||
}
|
||||
else
|
||||
|
@ -457,8 +456,7 @@ private:
|
|||
EV_SET(&event, descriptor, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
|
||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code error(errno,
|
||||
asio::error::system_category);
|
||||
asio::error_code error(errno, asio::native_ecat);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, error);
|
||||
}
|
||||
}
|
||||
|
@ -468,17 +466,19 @@ private:
|
|||
write_op_queue_.dispatch_cancellations();
|
||||
except_op_queue_.dispatch_cancellations();
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
{
|
||||
timer_queues_[i]->dispatch_timers();
|
||||
timer_queues_[i]->dispatch_cancellations();
|
||||
}
|
||||
|
||||
// Issue any pending cancellations.
|
||||
for (std::size_t i = 0; i < pending_cancellations_.size(); ++i)
|
||||
cancel_ops_unlocked(pending_cancellations_[i]);
|
||||
pending_cancellations_.clear();
|
||||
|
||||
cleanup_operations_and_timers(lock);
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
}
|
||||
|
||||
// Run the select loop in the thread.
|
||||
|
@ -512,10 +512,8 @@ private:
|
|||
int fd = kqueue();
|
||||
if (fd == -1)
|
||||
{
|
||||
boost::throw_exception(
|
||||
asio::system_error(
|
||||
asio::error_code(errno,
|
||||
asio::error::system_category),
|
||||
boost::throw_exception(asio::system_error(
|
||||
asio::error_code(errno, asio::native_ecat),
|
||||
"kqueue"));
|
||||
}
|
||||
return fd;
|
||||
|
@ -575,22 +573,6 @@ private:
|
|||
interrupter_.interrupt();
|
||||
}
|
||||
|
||||
// Clean up operations and timers. We must not hold the lock since the
|
||||
// destructors may make calls back into this reactor. We make a copy of the
|
||||
// vector of timer queues since the original may be modified while the lock
|
||||
// is not held.
|
||||
void cleanup_operations_and_timers(
|
||||
asio::detail::mutex::scoped_lock& lock)
|
||||
{
|
||||
timer_queues_for_cleanup_ = timer_queues_;
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i)
|
||||
timer_queues_for_cleanup_[i]->cleanup_timers();
|
||||
}
|
||||
|
||||
// Mutex to protect access to internal data.
|
||||
asio::detail::mutex mutex_;
|
||||
|
||||
|
@ -615,10 +597,6 @@ private:
|
|||
// The timer queues.
|
||||
std::vector<timer_queue_base*> timer_queues_;
|
||||
|
||||
// A copy of the timer queues, used when cleaning up timers. The copy is
|
||||
// stored as a class data member to avoid unnecessary memory allocation.
|
||||
std::vector<timer_queue_base*> timer_queues_for_cleanup_;
|
||||
|
||||
// The descriptors that are pending cancellation.
|
||||
std::vector<socket_type> pending_cancellations_;
|
||||
|
||||
|
|
|
@ -43,20 +43,17 @@ public:
|
|||
}
|
||||
|
||||
// Signal the event.
|
||||
template <typename Lock>
|
||||
void signal(Lock&)
|
||||
void signal()
|
||||
{
|
||||
}
|
||||
|
||||
// Reset the event.
|
||||
template <typename Lock>
|
||||
void clear(Lock&)
|
||||
void clear()
|
||||
{
|
||||
}
|
||||
|
||||
// Wait for the event to become signalled.
|
||||
template <typename Lock>
|
||||
void wait(Lock&)
|
||||
void wait()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
|
@ -24,12 +24,10 @@
|
|||
#if defined(BOOST_HAS_PTHREADS)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <pthread.h>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
|
||||
|
@ -44,11 +42,21 @@ public:
|
|||
posix_event()
|
||||
: signalled_(false)
|
||||
{
|
||||
int error = ::pthread_cond_init(&cond_, 0);
|
||||
int error = ::pthread_mutex_init(&mutex_, 0);
|
||||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
"event");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
||||
error = ::pthread_cond_init(&cond_, 0);
|
||||
if (error != 0)
|
||||
{
|
||||
::pthread_mutex_destroy(&mutex_);
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
"event");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -58,37 +66,37 @@ public:
|
|||
~posix_event()
|
||||
{
|
||||
::pthread_cond_destroy(&cond_);
|
||||
::pthread_mutex_destroy(&mutex_);
|
||||
}
|
||||
|
||||
// Signal the event.
|
||||
template <typename Lock>
|
||||
void signal(Lock& lock)
|
||||
void signal()
|
||||
{
|
||||
BOOST_ASSERT(lock.locked());
|
||||
(void)lock;
|
||||
::pthread_mutex_lock(&mutex_); // Ignore EINVAL and EDEADLK.
|
||||
signalled_ = true;
|
||||
::pthread_cond_signal(&cond_); // Ignore EINVAL.
|
||||
::pthread_mutex_unlock(&mutex_); // Ignore EINVAL and EPERM.
|
||||
}
|
||||
|
||||
// Reset the event.
|
||||
template <typename Lock>
|
||||
void clear(Lock& lock)
|
||||
void clear()
|
||||
{
|
||||
BOOST_ASSERT(lock.locked());
|
||||
(void)lock;
|
||||
::pthread_mutex_lock(&mutex_); // Ignore EINVAL and EDEADLK.
|
||||
signalled_ = false;
|
||||
::pthread_mutex_unlock(&mutex_); // Ignore EINVAL and EPERM.
|
||||
}
|
||||
|
||||
// Wait for the event to become signalled.
|
||||
template <typename Lock>
|
||||
void wait(Lock& lock)
|
||||
void wait()
|
||||
{
|
||||
BOOST_ASSERT(lock.locked());
|
||||
::pthread_mutex_lock(&mutex_); // Ignore EINVAL and EDEADLK.
|
||||
while (!signalled_)
|
||||
::pthread_cond_wait(&cond_, &lock.mutex().mutex_); // Ignore EINVAL.
|
||||
::pthread_cond_wait(&cond_, &mutex_); // Ignore EINVAL.
|
||||
::pthread_mutex_unlock(&mutex_); // Ignore EINVAL and EPERM.
|
||||
}
|
||||
|
||||
private:
|
||||
::pthread_mutex_t mutex_;
|
||||
::pthread_cond_t cond_;
|
||||
bool signalled_;
|
||||
};
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <pthread.h>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
#include "asio/detail/scoped_lock.hpp"
|
||||
|
@ -36,8 +35,6 @@
|
|||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
class posix_event;
|
||||
|
||||
class posix_mutex
|
||||
: private noncopyable
|
||||
{
|
||||
|
@ -51,7 +48,7 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
"mutex");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -70,7 +67,7 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
"mutex");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -83,14 +80,13 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
"mutex");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
friend class posix_event;
|
||||
::pthread_mutex_t mutex_;
|
||||
};
|
||||
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include <pthread.h>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
|
||||
|
@ -53,7 +52,7 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
"thread");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include <pthread.h>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
|
||||
|
@ -47,7 +46,7 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
"tss");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ public:
|
|||
};
|
||||
|
||||
// The maximum number of buffers to support in a single operation.
|
||||
enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
|
||||
enum { max_buffers = 16 };
|
||||
|
||||
// Constructor.
|
||||
reactive_socket_service(asio::io_service& io_service)
|
||||
|
@ -157,7 +157,7 @@ public:
|
|||
|
||||
if (int err = reactor_.register_descriptor(sock.get()))
|
||||
{
|
||||
ec = asio::error_code(err, asio::error::system_category);
|
||||
ec = asio::error_code(err, asio::native_ecat);
|
||||
return ec;
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ public:
|
|||
|
||||
if (int err = reactor_.register_descriptor(native_socket))
|
||||
{
|
||||
ec = asio::error_code(err, asio::error::system_category);
|
||||
ec = asio::error_code(err, asio::native_ecat);
|
||||
return ec;
|
||||
}
|
||||
|
||||
|
@ -1124,7 +1124,7 @@ public:
|
|||
bool operator()(const asio::error_code& result)
|
||||
{
|
||||
// Check whether the operation was successful.
|
||||
if (result)
|
||||
if (result != 0)
|
||||
{
|
||||
io_service_.post(bind_handler(handler_, result, 0));
|
||||
return true;
|
||||
|
@ -1489,7 +1489,7 @@ public:
|
|||
if (connect_error)
|
||||
{
|
||||
ec = asio::error_code(connect_error,
|
||||
asio::error::system_category);
|
||||
asio::native_ecat);
|
||||
io_service_.post(bind_handler(handler_, ec));
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -63,18 +63,6 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
// Test whether the lock is held.
|
||||
bool locked() const
|
||||
{
|
||||
return locked_;
|
||||
}
|
||||
|
||||
// Get the underlying mutex.
|
||||
Mutex& mutex()
|
||||
{
|
||||
return mutex_;
|
||||
}
|
||||
|
||||
private:
|
||||
// The underlying mutex.
|
||||
Mutex& mutex_;
|
||||
|
|
|
@ -229,10 +229,7 @@ public:
|
|||
std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
std::size_t n = timer_queue.cancel_timer(token);
|
||||
if (n > 0)
|
||||
interrupter_.interrupt();
|
||||
return n;
|
||||
return timer_queue.cancel_timer(token);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -248,13 +245,16 @@ private:
|
|||
read_op_queue_.dispatch_cancellations();
|
||||
write_op_queue_.dispatch_cancellations();
|
||||
except_op_queue_.dispatch_cancellations();
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
timer_queues_[i]->dispatch_cancellations();
|
||||
|
||||
// Check if the thread is supposed to stop.
|
||||
if (stop_thread_)
|
||||
{
|
||||
cleanup_operations_and_timers(lock);
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,12 @@ private:
|
|||
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
|
||||
&& except_op_queue_.empty() && all_timer_queues_are_empty())
|
||||
{
|
||||
cleanup_operations_and_timers(lock);
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -316,17 +321,19 @@ private:
|
|||
write_op_queue_.dispatch_cancellations();
|
||||
}
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
{
|
||||
timer_queues_[i]->dispatch_timers();
|
||||
timer_queues_[i]->dispatch_cancellations();
|
||||
}
|
||||
|
||||
// Issue any pending cancellations.
|
||||
for (size_t i = 0; i < pending_cancellations_.size(); ++i)
|
||||
cancel_ops_unlocked(pending_cancellations_[i]);
|
||||
pending_cancellations_.clear();
|
||||
|
||||
cleanup_operations_and_timers(lock);
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
}
|
||||
|
||||
// Run the select loop in the thread.
|
||||
|
@ -407,22 +414,6 @@ private:
|
|||
interrupter_.interrupt();
|
||||
}
|
||||
|
||||
// Clean up operations and timers. We must not hold the lock since the
|
||||
// destructors may make calls back into this reactor. We make a copy of the
|
||||
// vector of timer queues since the original may be modified while the lock
|
||||
// is not held.
|
||||
void cleanup_operations_and_timers(
|
||||
asio::detail::mutex::scoped_lock& lock)
|
||||
{
|
||||
timer_queues_for_cleanup_ = timer_queues_;
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i)
|
||||
timer_queues_for_cleanup_[i]->cleanup_timers();
|
||||
}
|
||||
|
||||
// Mutex to protect access to internal data.
|
||||
asio::detail::mutex mutex_;
|
||||
|
||||
|
@ -444,10 +435,6 @@ private:
|
|||
// The timer queues.
|
||||
std::vector<timer_queue_base*> timer_queues_;
|
||||
|
||||
// A copy of the timer queues, used when cleaning up timers. The copy is
|
||||
// stored as a class data member to avoid unnecessary memory allocation.
|
||||
std::vector<timer_queue_base*> timer_queues_for_cleanup_;
|
||||
|
||||
// The descriptors that are pending cancellation.
|
||||
std::vector<socket_type> pending_cancellations_;
|
||||
|
||||
|
|
|
@ -166,8 +166,7 @@ private:
|
|||
}
|
||||
|
||||
// Check if a service matches the given id.
|
||||
static bool service_id_matches(
|
||||
const asio::io_service::service& service,
|
||||
bool service_id_matches(const asio::io_service::service& service,
|
||||
const asio::io_service::id& id)
|
||||
{
|
||||
return service.id_ == &id;
|
||||
|
@ -175,8 +174,7 @@ private:
|
|||
|
||||
// Check if a service matches the given id.
|
||||
template <typename Service>
|
||||
static bool service_id_matches(
|
||||
const asio::io_service::service& service,
|
||||
bool service_id_matches(const asio::io_service::service& service,
|
||||
const asio::detail::service_id<Service>& /*id*/)
|
||||
{
|
||||
return service.type_info_ != 0 && *service.type_info_ == typeid(Service);
|
||||
|
|
|
@ -52,10 +52,9 @@ inline ReturnType error_wrapper(ReturnType return_value,
|
|||
asio::error_code& ec)
|
||||
{
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
ec = asio::error_code(WSAGetLastError(),
|
||||
asio::error::system_category);
|
||||
ec = asio::error_code(WSAGetLastError(), asio::native_ecat);
|
||||
#else
|
||||
ec = asio::error_code(errno, asio::error::system_category);
|
||||
ec = asio::error_code(errno, asio::native_ecat);
|
||||
#endif
|
||||
return return_value;
|
||||
}
|
||||
|
@ -924,13 +923,6 @@ inline void gai_free(void* p)
|
|||
::operator delete(p);
|
||||
}
|
||||
|
||||
inline void gai_strcpy(char* target, const char* source, std::size_t max_size)
|
||||
{
|
||||
using namespace std;
|
||||
*target = 0;
|
||||
strncat(target, source, max_size);
|
||||
}
|
||||
|
||||
enum { gai_clone_flag = 1 << 30 };
|
||||
|
||||
inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints,
|
||||
|
@ -1300,15 +1292,14 @@ inline int getaddrinfo_emulation(const char* host, const char* service,
|
|||
if (host != 0 && host[0] != '\0' && hptr->h_name && hptr->h_name[0]
|
||||
&& (hints.ai_flags & AI_CANONNAME) && canon == 0)
|
||||
{
|
||||
std::size_t canon_len = strlen(hptr->h_name) + 1;
|
||||
canon = gai_alloc<char>(canon_len);
|
||||
canon = gai_alloc<char>(strlen(hptr->h_name) + 1);
|
||||
if (canon == 0)
|
||||
{
|
||||
freeaddrinfo_emulation(aihead);
|
||||
socket_ops::freehostent(hptr);
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
gai_strcpy(canon, hptr->h_name, canon_len);
|
||||
strcpy(canon, hptr->h_name);
|
||||
}
|
||||
|
||||
// Create an addrinfo structure for each returned address.
|
||||
|
@ -1344,14 +1335,13 @@ inline int getaddrinfo_emulation(const char* host, const char* service,
|
|||
}
|
||||
else
|
||||
{
|
||||
std::size_t canonname_len = strlen(search[0].host) + 1;
|
||||
aihead->ai_canonname = gai_alloc<char>(canonname_len);
|
||||
aihead->ai_canonname = gai_alloc<char>(strlen(search[0].host) + 1);
|
||||
if (aihead->ai_canonname == 0)
|
||||
{
|
||||
freeaddrinfo_emulation(aihead);
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
gai_strcpy(aihead->ai_canonname, search[0].host, canonname_len);
|
||||
strcpy(aihead->ai_canonname, search[0].host);
|
||||
}
|
||||
}
|
||||
gai_free(canon);
|
||||
|
@ -1434,7 +1424,8 @@ inline asio::error_code getnameinfo_emulation(
|
|||
*dot = 0;
|
||||
}
|
||||
}
|
||||
gai_strcpy(host, hptr->h_name, hostlen);
|
||||
*host = '\0';
|
||||
strncat(host, hptr->h_name, hostlen);
|
||||
socket_ops::freehostent(hptr);
|
||||
}
|
||||
else
|
||||
|
@ -1472,7 +1463,8 @@ inline asio::error_code getnameinfo_emulation(
|
|||
servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0);
|
||||
if (sptr && sptr->s_name && sptr->s_name[0] != '\0')
|
||||
{
|
||||
gai_strcpy(serv, sptr->s_name, servlen);
|
||||
*serv = '\0';
|
||||
strncat(serv, sptr->s_name, servlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1512,12 +1504,6 @@ inline asio::error_code translate_addrinfo_error(int error)
|
|||
case EAI_MEMORY:
|
||||
return asio::error::no_memory;
|
||||
case EAI_NONAME:
|
||||
#if defined(EAI_ADDRFAMILY)
|
||||
case EAI_ADDRFAMILY:
|
||||
#endif
|
||||
#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
|
||||
case EAI_NODATA:
|
||||
#endif
|
||||
return asio::error::host_not_found;
|
||||
case EAI_SERVICE:
|
||||
return asio::error::service_not_found;
|
||||
|
@ -1526,10 +1512,10 @@ inline asio::error_code translate_addrinfo_error(int error)
|
|||
default: // Possibly the non-portable EAI_SYSTEM.
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
return asio::error_code(
|
||||
WSAGetLastError(), asio::error::system_category);
|
||||
WSAGetLastError(), asio::native_ecat);
|
||||
#else
|
||||
return asio::error_code(
|
||||
errno, asio::error::system_category);
|
||||
errno, asio::native_ecat);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,19 +110,8 @@ public:
|
|||
template <typename Protocol>
|
||||
void resize(const Protocol&, std::size_t s)
|
||||
{
|
||||
// On some platforms (e.g. Windows Vista), the getsockopt function will
|
||||
// return the size of a boolean socket option as one byte, even though a
|
||||
// four byte integer was passed in.
|
||||
switch (s)
|
||||
{
|
||||
case sizeof(char):
|
||||
value_ = *reinterpret_cast<char*>(&value_) ? 1 : 0;
|
||||
break;
|
||||
case sizeof(value_):
|
||||
break;
|
||||
default:
|
||||
if (s != sizeof(value_))
|
||||
throw std::length_error("boolean socket option resize");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -98,7 +98,6 @@
|
|||
# include <arpa/inet.h>
|
||||
# include <netdb.h>
|
||||
# include <net/if.h>
|
||||
# include <limits.h>
|
||||
# if defined(__sun)
|
||||
# include <sys/filio.h>
|
||||
# include <sys/sockio.h>
|
||||
|
@ -142,11 +141,6 @@ const int shutdown_both = SD_BOTH;
|
|||
const int message_peek = MSG_PEEK;
|
||||
const int message_out_of_band = MSG_OOB;
|
||||
const int message_do_not_route = MSG_DONTROUTE;
|
||||
# if defined (_WIN32_WINNT)
|
||||
const int max_iov_len = 64;
|
||||
# else
|
||||
const int max_iov_len = 16;
|
||||
# endif
|
||||
#else
|
||||
typedef int socket_type;
|
||||
const int invalid_socket = -1;
|
||||
|
@ -172,7 +166,6 @@ const int shutdown_both = SHUT_RDWR;
|
|||
const int message_peek = MSG_PEEK;
|
||||
const int message_out_of_band = MSG_OOB;
|
||||
const int message_do_not_route = MSG_DONTROUTE;
|
||||
const int max_iov_len = IOV_MAX;
|
||||
#endif
|
||||
const int custom_socket_option_level = 0xA5100000;
|
||||
const int enable_connection_aborted_option = 1;
|
||||
|
|
|
@ -239,7 +239,6 @@ public:
|
|||
#else
|
||||
BOOST_ASSERT(size <= strand_impl::handler_storage_type::size);
|
||||
#endif
|
||||
(void)size;
|
||||
return impl_->handler_storage_.address();
|
||||
}
|
||||
|
||||
|
@ -416,14 +415,14 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(impl->mutex_);
|
||||
|
||||
// Allocate and construct an object to wrap the handler.
|
||||
typedef handler_wrapper<Handler> value_type;
|
||||
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
|
||||
raw_handler_ptr<alloc_traits> raw_ptr(handler);
|
||||
handler_ptr<alloc_traits> ptr(raw_ptr, handler);
|
||||
|
||||
asio::detail::mutex::scoped_lock lock(impl->mutex_);
|
||||
|
||||
if (impl->current_handler_ == 0)
|
||||
{
|
||||
// This handler now has the lock, so can be dispatched immediately.
|
||||
|
@ -456,14 +455,14 @@ public:
|
|||
template <typename Handler>
|
||||
void post(implementation_type& impl, Handler handler)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(impl->mutex_);
|
||||
|
||||
// Allocate and construct an object to wrap the handler.
|
||||
typedef handler_wrapper<Handler> value_type;
|
||||
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
|
||||
raw_handler_ptr<alloc_traits> raw_ptr(handler);
|
||||
handler_ptr<alloc_traits> ptr(raw_ptr, handler);
|
||||
|
||||
asio::detail::mutex::scoped_lock lock(impl->mutex_);
|
||||
|
||||
if (impl->current_handler_ == 0)
|
||||
{
|
||||
// This handler now has the lock, so can be dispatched immediately.
|
||||
|
|
|
@ -40,7 +40,6 @@ public:
|
|||
: asio::detail::service_base<task_io_service<Task> >(io_service),
|
||||
mutex_(),
|
||||
task_(use_service<Task>(io_service)),
|
||||
task_interrupted_(true),
|
||||
outstanding_work_(0),
|
||||
handler_queue_(&task_handler_),
|
||||
handler_queue_end_(&task_handler_),
|
||||
|
@ -81,7 +80,8 @@ public:
|
|||
typename call_stack<task_io_service>::context ctx(this);
|
||||
|
||||
idle_thread_info this_idle_thread;
|
||||
this_idle_thread.next = 0;
|
||||
this_idle_thread.prev = &this_idle_thread;
|
||||
this_idle_thread.next = &this_idle_thread;
|
||||
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
|
@ -98,7 +98,8 @@ public:
|
|||
typename call_stack<task_io_service>::context ctx(this);
|
||||
|
||||
idle_thread_info this_idle_thread;
|
||||
this_idle_thread.next = 0;
|
||||
this_idle_thread.prev = &this_idle_thread;
|
||||
this_idle_thread.next = &this_idle_thread;
|
||||
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
|
@ -133,7 +134,7 @@ public:
|
|||
void stop()
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
stop_all_threads(lock);
|
||||
stop_all_threads();
|
||||
}
|
||||
|
||||
// Reset in preparation for a subsequent run invocation.
|
||||
|
@ -155,7 +156,7 @@ public:
|
|||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
if (--outstanding_work_ == 0)
|
||||
stop_all_threads(lock);
|
||||
stop_all_threads();
|
||||
}
|
||||
|
||||
// Request invocation of the given handler.
|
||||
|
@ -200,14 +201,9 @@ public:
|
|||
++outstanding_work_;
|
||||
|
||||
// Wake up a thread to execute the handler.
|
||||
if (!interrupt_one_idle_thread(lock))
|
||||
{
|
||||
if (!task_interrupted_)
|
||||
{
|
||||
task_interrupted_ = true;
|
||||
if (!interrupt_one_idle_thread())
|
||||
if (task_handler_.next_ == 0 && handler_queue_end_ != &task_handler_)
|
||||
task_.interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -218,7 +214,7 @@ private:
|
|||
{
|
||||
if (outstanding_work_ == 0 && !stopped_)
|
||||
{
|
||||
stop_all_threads(lock);
|
||||
stop_all_threads();
|
||||
ec = asio::error_code();
|
||||
return 0;
|
||||
}
|
||||
|
@ -234,14 +230,11 @@ private:
|
|||
handler_queue_ = h->next_;
|
||||
if (handler_queue_ == 0)
|
||||
handler_queue_end_ = 0;
|
||||
h->next_ = 0;
|
||||
bool more_handlers = (handler_queue_ != 0);
|
||||
lock.unlock();
|
||||
|
||||
if (h == &task_handler_)
|
||||
{
|
||||
bool more_handlers = (handler_queue_ != 0);
|
||||
task_interrupted_ = more_handlers || polling;
|
||||
lock.unlock();
|
||||
|
||||
// If the task has already run and we're polling then we're done.
|
||||
if (task_has_run && polling)
|
||||
{
|
||||
|
@ -259,7 +252,6 @@ private:
|
|||
}
|
||||
else
|
||||
{
|
||||
lock.unlock();
|
||||
handler_cleanup c(lock, *this);
|
||||
|
||||
// Invoke the handler. May throw an exception.
|
||||
|
@ -272,10 +264,31 @@ private:
|
|||
else if (this_idle_thread)
|
||||
{
|
||||
// Nothing to run right now, so just wait for work to do.
|
||||
this_idle_thread->next = first_idle_thread_;
|
||||
if (first_idle_thread_)
|
||||
{
|
||||
this_idle_thread->next = first_idle_thread_;
|
||||
this_idle_thread->prev = first_idle_thread_->prev;
|
||||
first_idle_thread_->prev->next = this_idle_thread;
|
||||
first_idle_thread_->prev = this_idle_thread;
|
||||
}
|
||||
first_idle_thread_ = this_idle_thread;
|
||||
this_idle_thread->wakeup_event.clear(lock);
|
||||
this_idle_thread->wakeup_event.wait(lock);
|
||||
this_idle_thread->wakeup_event.clear();
|
||||
lock.unlock();
|
||||
this_idle_thread->wakeup_event.wait();
|
||||
lock.lock();
|
||||
if (this_idle_thread->next == this_idle_thread)
|
||||
{
|
||||
first_idle_thread_ = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (first_idle_thread_ == this_idle_thread)
|
||||
first_idle_thread_ = this_idle_thread->next;
|
||||
this_idle_thread->next->prev = this_idle_thread->prev;
|
||||
this_idle_thread->prev->next = this_idle_thread->next;
|
||||
this_idle_thread->next = this_idle_thread;
|
||||
this_idle_thread->prev = this_idle_thread;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -289,44 +302,39 @@ private:
|
|||
}
|
||||
|
||||
// Stop the task and all idle threads.
|
||||
void stop_all_threads(
|
||||
asio::detail::mutex::scoped_lock& lock)
|
||||
void stop_all_threads()
|
||||
{
|
||||
stopped_ = true;
|
||||
interrupt_all_idle_threads(lock);
|
||||
if (!task_interrupted_)
|
||||
{
|
||||
task_interrupted_ = true;
|
||||
interrupt_all_idle_threads();
|
||||
if (task_handler_.next_ == 0 && handler_queue_end_ != &task_handler_)
|
||||
task_.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
// Interrupt a single idle thread. Returns true if a thread was interrupted,
|
||||
// false if no running thread could be found to interrupt.
|
||||
bool interrupt_one_idle_thread(
|
||||
asio::detail::mutex::scoped_lock& lock)
|
||||
bool interrupt_one_idle_thread()
|
||||
{
|
||||
if (first_idle_thread_)
|
||||
{
|
||||
idle_thread_info* idle_thread = first_idle_thread_;
|
||||
first_idle_thread_ = idle_thread->next;
|
||||
idle_thread->next = 0;
|
||||
idle_thread->wakeup_event.signal(lock);
|
||||
first_idle_thread_->wakeup_event.signal();
|
||||
first_idle_thread_ = first_idle_thread_->next;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Interrupt all idle threads.
|
||||
void interrupt_all_idle_threads(
|
||||
asio::detail::mutex::scoped_lock& lock)
|
||||
void interrupt_all_idle_threads()
|
||||
{
|
||||
while (first_idle_thread_)
|
||||
if (first_idle_thread_)
|
||||
{
|
||||
idle_thread_info* idle_thread = first_idle_thread_;
|
||||
first_idle_thread_ = idle_thread->next;
|
||||
idle_thread->next = 0;
|
||||
idle_thread->wakeup_event.signal(lock);
|
||||
first_idle_thread_->wakeup_event.signal();
|
||||
idle_thread_info* current_idle_thread = first_idle_thread_->next;
|
||||
while (current_idle_thread != first_idle_thread_)
|
||||
{
|
||||
current_idle_thread->wakeup_event.signal();
|
||||
current_idle_thread = current_idle_thread->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -432,7 +440,6 @@ private:
|
|||
{
|
||||
// Reinsert the task at the end of the handler queue.
|
||||
lock_.lock();
|
||||
task_io_service_.task_interrupted_ = true;
|
||||
task_io_service_.task_handler_.next_ = 0;
|
||||
if (task_io_service_.handler_queue_end_)
|
||||
{
|
||||
|
@ -471,7 +478,7 @@ private:
|
|||
{
|
||||
lock_.lock();
|
||||
if (--task_io_service_.outstanding_work_ == 0)
|
||||
task_io_service_.stop_all_threads(lock_);
|
||||
task_io_service_.stop_all_threads();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -496,9 +503,6 @@ private:
|
|||
}
|
||||
} task_handler_;
|
||||
|
||||
// Whether the task has been interrupted.
|
||||
bool task_interrupted_;
|
||||
|
||||
// The count of unfinished work.
|
||||
int outstanding_work_;
|
||||
|
||||
|
@ -518,6 +522,7 @@ private:
|
|||
struct idle_thread_info
|
||||
{
|
||||
event wakeup_event;
|
||||
idle_thread_info* prev;
|
||||
idle_thread_info* next;
|
||||
};
|
||||
|
||||
|
|
|
@ -48,9 +48,7 @@ public:
|
|||
// Constructor.
|
||||
timer_queue()
|
||||
: timers_(),
|
||||
heap_(),
|
||||
cancelled_timers_(0),
|
||||
cleanup_timers_(0)
|
||||
heap_()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -113,17 +111,12 @@ public:
|
|||
{
|
||||
timer_base* t = heap_[0];
|
||||
remove_timer(t);
|
||||
t->prev_ = 0;
|
||||
t->next_ = cleanup_timers_;
|
||||
cleanup_timers_ = t;
|
||||
t->invoke(asio::error_code());
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel the timers with the given token. Any timers pending for the token
|
||||
// will be notified that they have been cancelled next time
|
||||
// dispatch_cancellations is called. Returns the number of timers that were
|
||||
// cancelled.
|
||||
// Cancel the timer with the given token. The handler will be invoked
|
||||
// immediately with the result operation_aborted.
|
||||
std::size_t cancel_timer(void* timer_token)
|
||||
{
|
||||
std::size_t num_cancelled = 0;
|
||||
|
@ -136,9 +129,7 @@ public:
|
|||
{
|
||||
timer_base* next = t->next_;
|
||||
remove_timer(t);
|
||||
t->prev_ = 0;
|
||||
t->next_ = cancelled_timers_;
|
||||
cancelled_timers_ = t;
|
||||
t->invoke(asio::error::operation_aborted);
|
||||
t = next;
|
||||
++num_cancelled;
|
||||
}
|
||||
|
@ -146,31 +137,6 @@ public:
|
|||
return num_cancelled;
|
||||
}
|
||||
|
||||
// Dispatch any pending cancels for timers.
|
||||
virtual void dispatch_cancellations()
|
||||
{
|
||||
while (cancelled_timers_)
|
||||
{
|
||||
timer_base* this_timer = cancelled_timers_;
|
||||
cancelled_timers_ = this_timer->next_;
|
||||
this_timer->next_ = cleanup_timers_;
|
||||
cleanup_timers_ = this_timer;
|
||||
this_timer->invoke(asio::error::operation_aborted);
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy timers that are waiting to be cleaned up.
|
||||
virtual void cleanup_timers()
|
||||
{
|
||||
while (cleanup_timers_)
|
||||
{
|
||||
timer_base* next_timer = cleanup_timers_->next_;
|
||||
cleanup_timers_->next_ = 0;
|
||||
cleanup_timers_->destroy();
|
||||
cleanup_timers_ = next_timer;
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy all timers.
|
||||
virtual void destroy_timers()
|
||||
{
|
||||
|
@ -185,7 +151,6 @@ public:
|
|||
}
|
||||
heap_.clear();
|
||||
timers_.clear();
|
||||
cleanup_timers();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -273,7 +238,8 @@ private:
|
|||
static void invoke_handler(timer_base* base,
|
||||
const asio::error_code& result)
|
||||
{
|
||||
static_cast<timer<Handler>*>(base)->handler_(result);
|
||||
std::auto_ptr<timer<Handler> > t(static_cast<timer<Handler>*>(base));
|
||||
t->handler_(result);
|
||||
}
|
||||
|
||||
// Destroy the handler.
|
||||
|
@ -372,12 +338,6 @@ private:
|
|||
|
||||
// The heap of timers, with the earliest timer at the front.
|
||||
std::vector<timer_base*> heap_;
|
||||
|
||||
// The list of timers to be cancelled.
|
||||
timer_base* cancelled_timers_;
|
||||
|
||||
// The list of timers to be destroyed.
|
||||
timer_base* cleanup_timers_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
|
|
@ -44,12 +44,6 @@ public:
|
|||
// Dispatch all ready timers.
|
||||
virtual void dispatch_timers() = 0;
|
||||
|
||||
// Dispatch any pending cancels for timers.
|
||||
virtual void dispatch_cancellations() = 0;
|
||||
|
||||
// Destroy timers that are waiting to be cleaned up.
|
||||
virtual void cleanup_timers() = 0;
|
||||
|
||||
// Destroy all timers.
|
||||
virtual void destroy_timers() = 0;
|
||||
};
|
||||
|
|
|
@ -23,13 +23,11 @@
|
|||
|
||||
#if defined(BOOST_WINDOWS)
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
|
@ -48,8 +46,7 @@ public:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
asio::error_code(last_error, asio::native_ecat),
|
||||
"event");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -62,31 +59,21 @@ public:
|
|||
}
|
||||
|
||||
// Signal the event.
|
||||
template <typename Lock>
|
||||
void signal(Lock& lock)
|
||||
void signal()
|
||||
{
|
||||
BOOST_ASSERT(lock.locked());
|
||||
(void)lock;
|
||||
::SetEvent(event_);
|
||||
}
|
||||
|
||||
// Reset the event.
|
||||
template <typename Lock>
|
||||
void clear(Lock& lock)
|
||||
void clear()
|
||||
{
|
||||
BOOST_ASSERT(lock.locked());
|
||||
(void)lock;
|
||||
::ResetEvent(event_);
|
||||
}
|
||||
|
||||
// Wait for the event to become signalled.
|
||||
template <typename Lock>
|
||||
void wait(Lock& lock)
|
||||
void wait()
|
||||
{
|
||||
BOOST_ASSERT(lock.locked());
|
||||
lock.unlock();
|
||||
::WaitForSingleObject(event_, INFINITE);
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -63,8 +63,7 @@ public:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
asio::error_code(last_error, asio::native_ecat),
|
||||
"iocp");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -174,8 +173,7 @@ public:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
asio::error_code(last_error, asio::native_ecat),
|
||||
"pqcs");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -230,8 +228,7 @@ public:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
asio::error_code(last_error, asio::native_ecat),
|
||||
"pqcs");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -250,8 +247,7 @@ public:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
asio::error_code(last_error, asio::native_ecat),
|
||||
"pqcs");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -316,7 +312,7 @@ private:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
asio::native_ecat);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
#include <boost/config.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
|
||||
// This service is only supported on Win32 (NT4 and later).
|
||||
#if !defined(ASIO_DISABLE_IOCP)
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
|
|
|
@ -137,7 +137,7 @@ public:
|
|||
enum
|
||||
{
|
||||
enable_connection_aborted = 1, // User wants connection_aborted errors.
|
||||
close_might_block = 2, // User set linger option for blocking close.
|
||||
user_set_linger = 2, // The user set the linger option.
|
||||
user_set_non_blocking = 4 // The user wants a non-blocking socket.
|
||||
};
|
||||
|
||||
|
@ -170,7 +170,7 @@ public:
|
|||
typedef detail::select_reactor<true> reactor_type;
|
||||
|
||||
// The maximum number of buffers to support in a single operation.
|
||||
enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
|
||||
enum { max_buffers = 16 };
|
||||
|
||||
// Constructor.
|
||||
win_iocp_socket_service(asio::io_service& io_service)
|
||||
|
@ -192,7 +192,7 @@ public:
|
|||
while (impl)
|
||||
{
|
||||
asio::error_code ignored_ec;
|
||||
close_for_destruction(*impl);
|
||||
close(*impl, ignored_ec);
|
||||
impl = impl->next_;
|
||||
}
|
||||
}
|
||||
|
@ -217,7 +217,34 @@ public:
|
|||
// Destroy a socket implementation.
|
||||
void destroy(implementation_type& impl)
|
||||
{
|
||||
close_for_destruction(impl);
|
||||
if (impl.socket_ != invalid_socket)
|
||||
{
|
||||
// Check if the reactor was created, in which case we need to close the
|
||||
// socket on the reactor as well to cancel any operations that might be
|
||||
// running there.
|
||||
reactor_type* reactor = static_cast<reactor_type*>(
|
||||
interlocked_compare_exchange_pointer(
|
||||
reinterpret_cast<void**>(&reactor_), 0, 0));
|
||||
if (reactor)
|
||||
reactor->close_descriptor(impl.socket_);
|
||||
|
||||
if (impl.flags_ & implementation_type::user_set_linger)
|
||||
{
|
||||
::linger opt;
|
||||
opt.l_onoff = 0;
|
||||
opt.l_linger = 0;
|
||||
asio::error_code ignored_ec;
|
||||
socket_ops::setsockopt(impl.socket_,
|
||||
SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec);
|
||||
}
|
||||
|
||||
asio::error_code ignored_ec;
|
||||
socket_ops::close(impl.socket_, ignored_ec);
|
||||
impl.socket_ = invalid_socket;
|
||||
impl.flags_ = 0;
|
||||
impl.cancel_token_.reset();
|
||||
impl.safe_cancellation_thread_id_ = 0;
|
||||
}
|
||||
|
||||
// Remove implementation from linked list of all implementations.
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
|
@ -326,25 +353,6 @@ public:
|
|||
{
|
||||
ec = asio::error::bad_descriptor;
|
||||
}
|
||||
else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress(
|
||||
::GetModuleHandle("KERNEL32"), "CancelIoEx"))
|
||||
{
|
||||
// The version of Windows supports cancellation from any thread.
|
||||
typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED);
|
||||
cancel_io_ex_t cancel_io_ex = (cancel_io_ex_t)cancel_io_ex_ptr;
|
||||
socket_type sock = impl.socket_;
|
||||
HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock);
|
||||
if (!cancel_io_ex(sock_as_handle, 0))
|
||||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
}
|
||||
else
|
||||
{
|
||||
ec = asio::error_code();
|
||||
}
|
||||
}
|
||||
else if (impl.safe_cancellation_thread_id_ == 0)
|
||||
{
|
||||
// No operations have been started, so there's nothing to cancel.
|
||||
|
@ -359,8 +367,7 @@ public:
|
|||
if (!::CancelIo(sock_as_handle))
|
||||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
ec = asio::error_code(last_error, asio::native_ecat);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -468,12 +475,7 @@ public:
|
|||
if (option.level(impl.protocol_) == SOL_SOCKET
|
||||
&& option.name(impl.protocol_) == SO_LINGER)
|
||||
{
|
||||
const ::linger* linger_option =
|
||||
reinterpret_cast<const ::linger*>(option.data(impl.protocol_));
|
||||
if (linger_option->l_onoff != 0 && linger_option->l_linger != 0)
|
||||
impl.flags_ |= implementation_type::close_might_block;
|
||||
else
|
||||
impl.flags_ &= ~implementation_type::close_might_block;
|
||||
impl.flags_ |= implementation_type::user_set_linger;
|
||||
}
|
||||
|
||||
socket_ops::setsockopt(impl.socket_,
|
||||
|
@ -666,8 +668,7 @@ public:
|
|||
last_error = WSAECONNRESET;
|
||||
else if (last_error == ERROR_PORT_UNREACHABLE)
|
||||
last_error = WSAECONNREFUSED;
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
ec = asio::error_code(last_error, asio::native_ecat);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -718,8 +719,7 @@ public:
|
|||
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
|
||||
// Map non-portable errors to their portable counterparts.
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(last_error, asio::native_ecat);
|
||||
if (ec.value() == ERROR_NETNAME_DELETED)
|
||||
{
|
||||
if (handler_op->cancel_token_.expired())
|
||||
|
@ -821,8 +821,7 @@ public:
|
|||
{
|
||||
asio::io_service::work work(this->io_service());
|
||||
ptr.reset();
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(last_error, asio::native_ecat);
|
||||
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
||||
}
|
||||
else
|
||||
|
@ -866,8 +865,7 @@ public:
|
|||
DWORD last_error = ::WSAGetLastError();
|
||||
if (last_error == ERROR_PORT_UNREACHABLE)
|
||||
last_error = WSAECONNREFUSED;
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
ec = asio::error_code(last_error, asio::native_ecat);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -916,8 +914,7 @@ public:
|
|||
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
|
||||
// Map non-portable errors to their portable counterparts.
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(last_error, asio::native_ecat);
|
||||
if (ec.value() == ERROR_PORT_UNREACHABLE)
|
||||
{
|
||||
ec = asio::error::connection_refused;
|
||||
|
@ -1000,8 +997,7 @@ public:
|
|||
{
|
||||
asio::io_service::work work(this->io_service());
|
||||
ptr.reset();
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(last_error, asio::native_ecat);
|
||||
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
||||
}
|
||||
else
|
||||
|
@ -1055,8 +1051,7 @@ public:
|
|||
last_error = WSAECONNRESET;
|
||||
else if (last_error == ERROR_PORT_UNREACHABLE)
|
||||
last_error = WSAECONNREFUSED;
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
ec = asio::error_code(last_error, asio::native_ecat);
|
||||
return 0;
|
||||
}
|
||||
if (bytes_transferred == 0)
|
||||
|
@ -1114,8 +1109,7 @@ public:
|
|||
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
|
||||
// Map non-portable errors to their portable counterparts.
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(last_error, asio::native_ecat);
|
||||
if (ec.value() == ERROR_NETNAME_DELETED)
|
||||
{
|
||||
if (handler_op->cancel_token_.expired())
|
||||
|
@ -1222,8 +1216,7 @@ public:
|
|||
{
|
||||
asio::io_service::work work(this->io_service());
|
||||
ptr.reset();
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(last_error, asio::native_ecat);
|
||||
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
||||
}
|
||||
else
|
||||
|
@ -1269,8 +1262,7 @@ public:
|
|||
DWORD last_error = ::WSAGetLastError();
|
||||
if (last_error == ERROR_PORT_UNREACHABLE)
|
||||
last_error = WSAECONNREFUSED;
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
ec = asio::error_code(last_error, asio::native_ecat);
|
||||
return 0;
|
||||
}
|
||||
if (bytes_transferred == 0)
|
||||
|
@ -1336,8 +1328,7 @@ public:
|
|||
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
|
||||
// Map non-portable errors to their portable counterparts.
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(last_error, asio::native_ecat);
|
||||
if (ec.value() == ERROR_PORT_UNREACHABLE)
|
||||
{
|
||||
ec = asio::error::connection_refused;
|
||||
|
@ -1431,8 +1422,7 @@ public:
|
|||
{
|
||||
asio::io_service::work work(this->io_service());
|
||||
ptr.reset();
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(last_error, asio::native_ecat);
|
||||
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
||||
}
|
||||
else
|
||||
|
@ -1669,8 +1659,7 @@ public:
|
|||
ptr.reset();
|
||||
|
||||
// Call the handler.
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(last_error, asio::native_ecat);
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
detail::bind_handler(handler, ec), &handler);
|
||||
}
|
||||
|
@ -1770,8 +1759,7 @@ public:
|
|||
{
|
||||
asio::io_service::work work(this->io_service());
|
||||
ptr.reset();
|
||||
asio::error_code ec(last_error,
|
||||
asio::error::system_category);
|
||||
asio::error_code ec(last_error, asio::native_ecat);
|
||||
iocp_service_.post(bind_handler(handler, ec));
|
||||
}
|
||||
}
|
||||
|
@ -1847,8 +1835,8 @@ public:
|
|||
// If connection failed then post the handler with the error code.
|
||||
if (connect_error)
|
||||
{
|
||||
ec = asio::error_code(connect_error,
|
||||
asio::error::system_category);
|
||||
ec = asio::error_code(
|
||||
connect_error, asio::native_ecat);
|
||||
io_service_.post(bind_handler(handler_, ec));
|
||||
return true;
|
||||
}
|
||||
|
@ -1962,66 +1950,26 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
// Helper function to close a socket when the associated object is being
|
||||
// destroyed.
|
||||
void close_for_destruction(implementation_type& impl)
|
||||
{
|
||||
if (is_open(impl))
|
||||
{
|
||||
// Check if the reactor was created, in which case we need to close the
|
||||
// socket on the reactor as well to cancel any operations that might be
|
||||
// running there.
|
||||
reactor_type* reactor = static_cast<reactor_type*>(
|
||||
interlocked_compare_exchange_pointer(
|
||||
reinterpret_cast<void**>(&reactor_), 0, 0));
|
||||
if (reactor)
|
||||
reactor->close_descriptor(impl.socket_);
|
||||
|
||||
// The socket destructor must not block. If the user has changed the
|
||||
// linger option to block in the foreground, we will change it back to the
|
||||
// default so that the closure is performed in the background.
|
||||
if (impl.flags_ & implementation_type::close_might_block)
|
||||
{
|
||||
::linger opt;
|
||||
opt.l_onoff = 0;
|
||||
opt.l_linger = 0;
|
||||
asio::error_code ignored_ec;
|
||||
socket_ops::setsockopt(impl.socket_,
|
||||
SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec);
|
||||
}
|
||||
|
||||
asio::error_code ignored_ec;
|
||||
socket_ops::close(impl.socket_, ignored_ec);
|
||||
impl.socket_ = invalid_socket;
|
||||
impl.flags_ = 0;
|
||||
impl.cancel_token_.reset();
|
||||
impl.safe_cancellation_thread_id_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to emulate InterlockedCompareExchangePointer functionality
|
||||
// for:
|
||||
// - very old Platform SDKs; and
|
||||
// - platform SDKs where MSVC's /Wp64 option causes spurious warnings.
|
||||
// Helper function to provide InterlockedCompareExchangePointer functionality
|
||||
// on very old Platform SDKs.
|
||||
void* interlocked_compare_exchange_pointer(void** dest, void* exch, void* cmp)
|
||||
{
|
||||
#if defined(_M_IX86)
|
||||
#if defined(_WIN32_WINNT) && (_WIN32_WINNT <= 0x400) && (_M_IX86)
|
||||
return reinterpret_cast<void*>(InterlockedCompareExchange(
|
||||
reinterpret_cast<PLONG>(dest), reinterpret_cast<LONG>(exch),
|
||||
reinterpret_cast<LONG*>(dest), reinterpret_cast<LONG>(exch),
|
||||
reinterpret_cast<LONG>(cmp)));
|
||||
#else
|
||||
return InterlockedCompareExchangePointer(dest, exch, cmp);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Helper function to emulate InterlockedExchangePointer functionality for:
|
||||
// - very old Platform SDKs; and
|
||||
// - platform SDKs where MSVC's /Wp64 option causes spurious warnings.
|
||||
// Helper function to provide InterlockedExchangePointer functionality on very
|
||||
// old Platform SDKs.
|
||||
void* interlocked_exchange_pointer(void** dest, void* val)
|
||||
{
|
||||
#if defined(_M_IX86)
|
||||
#if defined(_WIN32_WINNT) && (_WIN32_WINNT <= 0x400) && (_M_IX86)
|
||||
return reinterpret_cast<void*>(InterlockedExchange(
|
||||
reinterpret_cast<PLONG>(dest), reinterpret_cast<LONG>(val)));
|
||||
reinterpret_cast<LONG*>(dest), reinterpret_cast<LONG>(val)));
|
||||
#else
|
||||
return InterlockedExchangePointer(dest, val);
|
||||
#endif
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
#if defined(BOOST_WINDOWS)
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
|
@ -49,7 +48,7 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
"mutex");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -68,7 +67,7 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
"mutex");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
#if defined(BOOST_WINDOWS)
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
|
@ -55,8 +54,7 @@ public:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
asio::error_code(last_error, asio::native_ecat),
|
||||
"thread");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
#if defined(BOOST_WINDOWS)
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
|
@ -48,8 +47,7 @@ public:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
asio::error_code(last_error, asio::native_ecat),
|
||||
"tss");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -85,8 +85,7 @@ public:
|
|||
if (this != &instance_ && ref_->result() != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(ref_->result(),
|
||||
asio::error::system_category),
|
||||
asio::error_code(ref_->result(), asio::native_ecat),
|
||||
"winsock");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -17,10 +17,6 @@
|
|||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <boost/type_traits.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/detail/bind_handler.hpp"
|
||||
#include "asio/detail/handler_alloc_helpers.hpp"
|
||||
#include "asio/detail/handler_invoke_helpers.hpp"
|
||||
|
@ -34,9 +30,7 @@ class wrapped_handler
|
|||
public:
|
||||
typedef void result_type;
|
||||
|
||||
wrapped_handler(
|
||||
typename boost::add_reference<Dispatcher>::type dispatcher,
|
||||
Handler handler)
|
||||
wrapped_handler(Dispatcher& dispatcher, Handler handler)
|
||||
: dispatcher_(dispatcher),
|
||||
handler_(handler)
|
||||
{
|
||||
|
@ -123,7 +117,7 @@ public:
|
|||
}
|
||||
|
||||
//private:
|
||||
Dispatcher dispatcher_;
|
||||
Dispatcher& dispatcher_;
|
||||
Handler handler_;
|
||||
};
|
||||
|
||||
|
@ -177,9 +171,9 @@ inline void asio_handler_invoke(const Function& function,
|
|||
function, this_handler->handler_));
|
||||
}
|
||||
|
||||
template <typename Function, typename Handler, typename Context>
|
||||
template <typename Function, typename Dispatcher, typename Handler>
|
||||
inline void asio_handler_invoke(const Function& function,
|
||||
rewrapped_handler<Handler, Context>* this_handler)
|
||||
rewrapped_handler<Dispatcher, Handler>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, &this_handler->context_);
|
||||
|
|
|
@ -37,195 +37,327 @@
|
|||
/// INTERNAL ONLY.
|
||||
# define ASIO_WIN_OR_POSIX(e_win, e_posix) implementation_defined
|
||||
#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
# define ASIO_NATIVE_ERROR(e) e
|
||||
# define ASIO_SOCKET_ERROR(e) WSA ## e
|
||||
# define ASIO_NETDB_ERROR(e) WSA ## e
|
||||
# define ASIO_GETADDRINFO_ERROR(e) WSA ## e
|
||||
# define ASIO_NATIVE_ERROR(e) \
|
||||
asio::error_code(e, \
|
||||
asio::native_ecat)
|
||||
# define ASIO_SOCKET_ERROR(e) \
|
||||
asio::error_code(WSA ## e, \
|
||||
asio::native_ecat)
|
||||
# define ASIO_NETDB_ERROR(e) \
|
||||
asio::error_code(WSA ## e, \
|
||||
asio::native_ecat)
|
||||
# define ASIO_GETADDRINFO_ERROR(e) \
|
||||
asio::error_code(WSA ## e, \
|
||||
asio::native_ecat)
|
||||
# define ASIO_MISC_ERROR(e) \
|
||||
asio::error_code(e, \
|
||||
asio::misc_ecat)
|
||||
# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_win
|
||||
#else
|
||||
# define ASIO_NATIVE_ERROR(e) e
|
||||
# define ASIO_SOCKET_ERROR(e) e
|
||||
# define ASIO_NETDB_ERROR(e) e
|
||||
# define ASIO_GETADDRINFO_ERROR(e) e
|
||||
# define ASIO_NATIVE_ERROR(e) \
|
||||
asio::error_code(e, \
|
||||
asio::native_ecat)
|
||||
# define ASIO_SOCKET_ERROR(e) \
|
||||
asio::error_code(e, \
|
||||
asio::native_ecat)
|
||||
# define ASIO_NETDB_ERROR(e) \
|
||||
asio::error_code(e, \
|
||||
asio::netdb_ecat)
|
||||
# define ASIO_GETADDRINFO_ERROR(e) \
|
||||
asio::error_code(e, \
|
||||
asio::addrinfo_ecat)
|
||||
# define ASIO_MISC_ERROR(e) \
|
||||
asio::error_code(e, \
|
||||
asio::misc_ecat)
|
||||
# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_posix
|
||||
#endif
|
||||
|
||||
namespace asio {
|
||||
namespace error {
|
||||
|
||||
enum basic_errors
|
||||
namespace detail {
|
||||
|
||||
/// Hack to keep asio library header-file-only.
|
||||
template <typename T>
|
||||
class error_base
|
||||
{
|
||||
public:
|
||||
// boostify: error category declarations go here.
|
||||
|
||||
/// Permission denied.
|
||||
access_denied = ASIO_SOCKET_ERROR(EACCES),
|
||||
static const asio::error_code access_denied;
|
||||
|
||||
/// Address family not supported by protocol.
|
||||
address_family_not_supported = ASIO_SOCKET_ERROR(EAFNOSUPPORT),
|
||||
static const asio::error_code address_family_not_supported;
|
||||
|
||||
/// Address already in use.
|
||||
address_in_use = ASIO_SOCKET_ERROR(EADDRINUSE),
|
||||
static const asio::error_code address_in_use;
|
||||
|
||||
/// Transport endpoint is already connected.
|
||||
already_connected = ASIO_SOCKET_ERROR(EISCONN),
|
||||
static const asio::error_code already_connected;
|
||||
|
||||
/// Already open.
|
||||
static const asio::error_code already_open;
|
||||
|
||||
/// Operation already in progress.
|
||||
already_started = ASIO_SOCKET_ERROR(EALREADY),
|
||||
static const asio::error_code already_started;
|
||||
|
||||
/// A connection has been aborted.
|
||||
connection_aborted = ASIO_SOCKET_ERROR(ECONNABORTED),
|
||||
static const asio::error_code connection_aborted;
|
||||
|
||||
/// Connection refused.
|
||||
connection_refused = ASIO_SOCKET_ERROR(ECONNREFUSED),
|
||||
static const asio::error_code connection_refused;
|
||||
|
||||
/// Connection reset by peer.
|
||||
connection_reset = ASIO_SOCKET_ERROR(ECONNRESET),
|
||||
static const asio::error_code connection_reset;
|
||||
|
||||
/// Bad file descriptor.
|
||||
bad_descriptor = ASIO_SOCKET_ERROR(EBADF),
|
||||
|
||||
/// Bad address.
|
||||
fault = ASIO_SOCKET_ERROR(EFAULT),
|
||||
|
||||
/// No route to host.
|
||||
host_unreachable = ASIO_SOCKET_ERROR(EHOSTUNREACH),
|
||||
|
||||
/// Operation now in progress.
|
||||
in_progress = ASIO_SOCKET_ERROR(EINPROGRESS),
|
||||
|
||||
/// Interrupted system call.
|
||||
interrupted = ASIO_SOCKET_ERROR(EINTR),
|
||||
|
||||
/// Invalid argument.
|
||||
invalid_argument = ASIO_SOCKET_ERROR(EINVAL),
|
||||
|
||||
/// Message too long.
|
||||
message_size = ASIO_SOCKET_ERROR(EMSGSIZE),
|
||||
|
||||
/// Network is down.
|
||||
network_down = ASIO_SOCKET_ERROR(ENETDOWN),
|
||||
|
||||
/// Network dropped connection on reset.
|
||||
network_reset = ASIO_SOCKET_ERROR(ENETRESET),
|
||||
|
||||
/// Network is unreachable.
|
||||
network_unreachable = ASIO_SOCKET_ERROR(ENETUNREACH),
|
||||
|
||||
/// Too many open files.
|
||||
no_descriptors = ASIO_SOCKET_ERROR(EMFILE),
|
||||
|
||||
/// No buffer space available.
|
||||
no_buffer_space = ASIO_SOCKET_ERROR(ENOBUFS),
|
||||
|
||||
/// Cannot allocate memory.
|
||||
no_memory = ASIO_WIN_OR_POSIX(
|
||||
ASIO_NATIVE_ERROR(ERROR_OUTOFMEMORY),
|
||||
ASIO_NATIVE_ERROR(ENOMEM)),
|
||||
|
||||
/// Operation not permitted.
|
||||
no_permission = ASIO_WIN_OR_POSIX(
|
||||
ASIO_NATIVE_ERROR(ERROR_ACCESS_DENIED),
|
||||
ASIO_NATIVE_ERROR(EPERM)),
|
||||
|
||||
/// Protocol not available.
|
||||
no_protocol_option = ASIO_SOCKET_ERROR(ENOPROTOOPT),
|
||||
|
||||
/// Transport endpoint is not connected.
|
||||
not_connected = ASIO_SOCKET_ERROR(ENOTCONN),
|
||||
|
||||
/// Socket operation on non-socket.
|
||||
not_socket = ASIO_SOCKET_ERROR(ENOTSOCK),
|
||||
|
||||
/// Operation cancelled.
|
||||
operation_aborted = ASIO_WIN_OR_POSIX(
|
||||
ASIO_NATIVE_ERROR(ERROR_OPERATION_ABORTED),
|
||||
ASIO_NATIVE_ERROR(ECANCELED)),
|
||||
|
||||
/// Operation not supported.
|
||||
operation_not_supported = ASIO_SOCKET_ERROR(EOPNOTSUPP),
|
||||
|
||||
/// Cannot send after transport endpoint shutdown.
|
||||
shut_down = ASIO_SOCKET_ERROR(ESHUTDOWN),
|
||||
|
||||
/// Connection timed out.
|
||||
timed_out = ASIO_SOCKET_ERROR(ETIMEDOUT),
|
||||
|
||||
/// Resource temporarily unavailable.
|
||||
try_again = ASIO_WIN_OR_POSIX(
|
||||
ASIO_NATIVE_ERROR(ERROR_RETRY),
|
||||
ASIO_NATIVE_ERROR(EAGAIN)),
|
||||
|
||||
/// The socket is marked non-blocking and the requested operation would block.
|
||||
would_block = ASIO_SOCKET_ERROR(EWOULDBLOCK)
|
||||
};
|
||||
|
||||
enum netdb_errors
|
||||
{
|
||||
/// Host not found (authoritative).
|
||||
host_not_found = ASIO_NETDB_ERROR(HOST_NOT_FOUND),
|
||||
|
||||
/// Host not found (non-authoritative).
|
||||
host_not_found_try_again = ASIO_NETDB_ERROR(TRY_AGAIN),
|
||||
|
||||
/// The query is valid but does not have associated address data.
|
||||
no_data = ASIO_NETDB_ERROR(NO_DATA),
|
||||
|
||||
/// A non-recoverable error occurred.
|
||||
no_recovery = ASIO_NETDB_ERROR(NO_RECOVERY)
|
||||
};
|
||||
|
||||
enum addrinfo_errors
|
||||
{
|
||||
/// The service is not supported for the given socket type.
|
||||
service_not_found = ASIO_WIN_OR_POSIX(
|
||||
ASIO_NATIVE_ERROR(WSATYPE_NOT_FOUND),
|
||||
ASIO_GETADDRINFO_ERROR(EAI_SERVICE)),
|
||||
|
||||
/// The socket type is not supported.
|
||||
socket_type_not_supported = ASIO_WIN_OR_POSIX(
|
||||
ASIO_NATIVE_ERROR(WSAESOCKTNOSUPPORT),
|
||||
ASIO_GETADDRINFO_ERROR(EAI_SOCKTYPE))
|
||||
};
|
||||
|
||||
enum misc_errors
|
||||
{
|
||||
/// Already open.
|
||||
already_open = 1,
|
||||
static const asio::error_code bad_descriptor;
|
||||
|
||||
/// End of file or stream.
|
||||
eof,
|
||||
static const asio::error_code eof;
|
||||
|
||||
/// Bad address.
|
||||
static const asio::error_code fault;
|
||||
|
||||
/// Host not found (authoritative).
|
||||
static const asio::error_code host_not_found;
|
||||
|
||||
/// Host not found (non-authoritative).
|
||||
static const asio::error_code host_not_found_try_again;
|
||||
|
||||
/// No route to host.
|
||||
static const asio::error_code host_unreachable;
|
||||
|
||||
/// Operation now in progress.
|
||||
static const asio::error_code in_progress;
|
||||
|
||||
/// Interrupted system call.
|
||||
static const asio::error_code interrupted;
|
||||
|
||||
/// Invalid argument.
|
||||
static const asio::error_code invalid_argument;
|
||||
|
||||
/// Message too long.
|
||||
static const asio::error_code message_size;
|
||||
|
||||
/// Network is down.
|
||||
static const asio::error_code network_down;
|
||||
|
||||
/// Network dropped connection on reset.
|
||||
static const asio::error_code network_reset;
|
||||
|
||||
/// Network is unreachable.
|
||||
static const asio::error_code network_unreachable;
|
||||
|
||||
/// Too many open files.
|
||||
static const asio::error_code no_descriptors;
|
||||
|
||||
/// No buffer space available.
|
||||
static const asio::error_code no_buffer_space;
|
||||
|
||||
/// The query is valid but does not have associated address data.
|
||||
static const asio::error_code no_data;
|
||||
|
||||
/// Cannot allocate memory.
|
||||
static const asio::error_code no_memory;
|
||||
|
||||
/// Operation not permitted.
|
||||
static const asio::error_code no_permission;
|
||||
|
||||
/// Protocol not available.
|
||||
static const asio::error_code no_protocol_option;
|
||||
|
||||
/// A non-recoverable error occurred.
|
||||
static const asio::error_code no_recovery;
|
||||
|
||||
/// Transport endpoint is not connected.
|
||||
static const asio::error_code not_connected;
|
||||
|
||||
/// Element not found.
|
||||
not_found
|
||||
static const asio::error_code not_found;
|
||||
|
||||
/// Socket operation on non-socket.
|
||||
static const asio::error_code not_socket;
|
||||
|
||||
/// Operation cancelled.
|
||||
static const asio::error_code operation_aborted;
|
||||
|
||||
/// Operation not supported.
|
||||
static const asio::error_code operation_not_supported;
|
||||
|
||||
/// The service is not supported for the given socket type.
|
||||
static const asio::error_code service_not_found;
|
||||
|
||||
/// The socket type is not supported.
|
||||
static const asio::error_code socket_type_not_supported;
|
||||
|
||||
/// Cannot send after transport endpoint shutdown.
|
||||
static const asio::error_code shut_down;
|
||||
|
||||
/// Connection timed out.
|
||||
static const asio::error_code timed_out;
|
||||
|
||||
/// Resource temporarily unavailable.
|
||||
static const asio::error_code try_again;
|
||||
|
||||
/// The socket is marked non-blocking and the requested operation would block.
|
||||
static const asio::error_code would_block;
|
||||
|
||||
private:
|
||||
error_base();
|
||||
};
|
||||
|
||||
// boostify: error category definitions go here.
|
||||
|
||||
inline asio::error_code make_error_code(basic_errors e)
|
||||
{
|
||||
return asio::error_code(static_cast<int>(e), system_category);
|
||||
}
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::access_denied = ASIO_SOCKET_ERROR(EACCES);
|
||||
|
||||
inline asio::error_code make_error_code(netdb_errors e)
|
||||
{
|
||||
return asio::error_code(static_cast<int>(e), netdb_category);
|
||||
}
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::address_family_not_supported = ASIO_SOCKET_ERROR(
|
||||
EAFNOSUPPORT);
|
||||
|
||||
inline asio::error_code make_error_code(addrinfo_errors e)
|
||||
{
|
||||
return asio::error_code(static_cast<int>(e), addrinfo_category);
|
||||
}
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::address_in_use = ASIO_SOCKET_ERROR(EADDRINUSE);
|
||||
|
||||
inline asio::error_code make_error_code(misc_errors e)
|
||||
{
|
||||
return asio::error_code(static_cast<int>(e), misc_category);
|
||||
}
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::already_connected = ASIO_SOCKET_ERROR(EISCONN);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::already_open = ASIO_MISC_ERROR(1);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::already_started = ASIO_SOCKET_ERROR(EALREADY);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::connection_aborted = ASIO_SOCKET_ERROR(ECONNABORTED);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::connection_refused = ASIO_SOCKET_ERROR(ECONNREFUSED);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::connection_reset = ASIO_SOCKET_ERROR(ECONNRESET);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::bad_descriptor = ASIO_SOCKET_ERROR(EBADF);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::eof = ASIO_MISC_ERROR(2);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::fault = ASIO_SOCKET_ERROR(EFAULT);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::host_not_found = ASIO_NETDB_ERROR(HOST_NOT_FOUND);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::host_not_found_try_again = ASIO_NETDB_ERROR(TRY_AGAIN);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::host_unreachable = ASIO_SOCKET_ERROR(EHOSTUNREACH);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::in_progress = ASIO_SOCKET_ERROR(EINPROGRESS);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::interrupted = ASIO_SOCKET_ERROR(EINTR);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::invalid_argument = ASIO_SOCKET_ERROR(EINVAL);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::message_size = ASIO_SOCKET_ERROR(EMSGSIZE);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::network_down = ASIO_SOCKET_ERROR(ENETDOWN);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::network_reset = ASIO_SOCKET_ERROR(ENETRESET);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::network_unreachable = ASIO_SOCKET_ERROR(ENETUNREACH);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::no_descriptors = ASIO_SOCKET_ERROR(EMFILE);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::no_buffer_space = ASIO_SOCKET_ERROR(ENOBUFS);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::no_data = ASIO_NETDB_ERROR(NO_DATA);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::no_memory = ASIO_WIN_OR_POSIX(
|
||||
ASIO_NATIVE_ERROR(ERROR_OUTOFMEMORY),
|
||||
ASIO_NATIVE_ERROR(ENOMEM));
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::no_permission = ASIO_WIN_OR_POSIX(
|
||||
ASIO_NATIVE_ERROR(ERROR_ACCESS_DENIED),
|
||||
ASIO_NATIVE_ERROR(EPERM));
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::no_protocol_option = ASIO_SOCKET_ERROR(ENOPROTOOPT);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::no_recovery = ASIO_NETDB_ERROR(NO_RECOVERY);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::not_connected = ASIO_SOCKET_ERROR(ENOTCONN);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::not_found = ASIO_MISC_ERROR(3);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::not_socket = ASIO_SOCKET_ERROR(ENOTSOCK);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::operation_aborted = ASIO_WIN_OR_POSIX(
|
||||
ASIO_NATIVE_ERROR(ERROR_OPERATION_ABORTED),
|
||||
ASIO_NATIVE_ERROR(ECANCELED));
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::operation_not_supported = ASIO_SOCKET_ERROR(EOPNOTSUPP);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::service_not_found = ASIO_WIN_OR_POSIX(
|
||||
ASIO_NATIVE_ERROR(WSATYPE_NOT_FOUND),
|
||||
ASIO_GETADDRINFO_ERROR(EAI_SERVICE));
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::socket_type_not_supported = ASIO_WIN_OR_POSIX(
|
||||
ASIO_NATIVE_ERROR(WSAESOCKTNOSUPPORT),
|
||||
ASIO_GETADDRINFO_ERROR(EAI_SOCKTYPE));
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::shut_down = ASIO_SOCKET_ERROR(ESHUTDOWN);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::timed_out = ASIO_SOCKET_ERROR(ETIMEDOUT);
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::try_again = ASIO_WIN_OR_POSIX(
|
||||
ASIO_NATIVE_ERROR(ERROR_RETRY),
|
||||
ASIO_NATIVE_ERROR(EAGAIN));
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
error_base<T>::would_block = ASIO_SOCKET_ERROR(EWOULDBLOCK);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
/// Contains error constants.
|
||||
class error : public asio::detail::error_base<error>
|
||||
{
|
||||
private:
|
||||
error();
|
||||
};
|
||||
|
||||
} // namespace error
|
||||
} // namespace asio
|
||||
|
||||
#undef ASIO_NATIVE_ERROR
|
||||
#undef ASIO_SOCKET_ERROR
|
||||
#undef ASIO_NETDB_ERROR
|
||||
#undef ASIO_GETADDRINFO_ERROR
|
||||
#undef ASIO_MISC_ERROR
|
||||
#undef ASIO_WIN_OR_POSIX
|
||||
|
||||
#include "asio/impl/error_code.ipp"
|
||||
|
|
|
@ -32,27 +32,24 @@
|
|||
|
||||
namespace asio {
|
||||
|
||||
namespace error
|
||||
/// Available error code categories.
|
||||
enum error_category
|
||||
{
|
||||
/// Available error code categories.
|
||||
enum error_category
|
||||
{
|
||||
/// System error codes.
|
||||
system_category = ASIO_WIN_OR_POSIX(0, 0),
|
||||
/// Native error codes.
|
||||
native_ecat = ASIO_WIN_OR_POSIX(0, 0),
|
||||
|
||||
/// Error codes from NetDB functions.
|
||||
netdb_category = ASIO_WIN_OR_POSIX(system_category, 1),
|
||||
/// Error codes from NetDB functions.
|
||||
netdb_ecat = ASIO_WIN_OR_POSIX(native_ecat, 1),
|
||||
|
||||
/// Error codes from getaddrinfo.
|
||||
addrinfo_category = ASIO_WIN_OR_POSIX(system_category, 2),
|
||||
/// Error codes from getaddrinfo.
|
||||
addrinfo_ecat = ASIO_WIN_OR_POSIX(native_ecat, 2),
|
||||
|
||||
/// Miscellaneous error codes.
|
||||
misc_category = ASIO_WIN_OR_POSIX(3, 3),
|
||||
/// Miscellaneous error codes.
|
||||
misc_ecat = ASIO_WIN_OR_POSIX(3, 3),
|
||||
|
||||
/// SSL error codes.
|
||||
ssl_category = ASIO_WIN_OR_POSIX(4, 4)
|
||||
};
|
||||
} // namespace error
|
||||
/// SSL error codes.
|
||||
ssl_ecat = ASIO_WIN_OR_POSIX(4, 4)
|
||||
};
|
||||
|
||||
/// Class to represent an error code value.
|
||||
class error_code
|
||||
|
@ -64,24 +61,17 @@ public:
|
|||
/// Default constructor.
|
||||
error_code()
|
||||
: value_(0),
|
||||
category_(error::system_category)
|
||||
category_(native_ecat)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct with specific error code and category.
|
||||
error_code(value_type v, error::error_category c)
|
||||
error_code(value_type v, error_category c)
|
||||
: value_(v),
|
||||
category_(c)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct from an error code enum.
|
||||
template <typename ErrorEnum>
|
||||
error_code(ErrorEnum e)
|
||||
{
|
||||
*this = make_error_code(e);
|
||||
}
|
||||
|
||||
/// Get the error value.
|
||||
value_type value() const
|
||||
{
|
||||
|
@ -89,7 +79,7 @@ public:
|
|||
}
|
||||
|
||||
/// Get the error category.
|
||||
error::error_category category() const
|
||||
error_category category() const
|
||||
{
|
||||
return category_;
|
||||
}
|
||||
|
@ -135,7 +125,7 @@ private:
|
|||
value_type value_;
|
||||
|
||||
// The category associated with the error code.
|
||||
error::error_category category_;
|
||||
error_category category_;
|
||||
};
|
||||
|
||||
} // namespace asio
|
||||
|
|
|
@ -35,12 +35,10 @@ inline std::string error_code::message() const
|
|||
return "Already open.";
|
||||
if (*this == error::not_found)
|
||||
return "Not found.";
|
||||
if (category_ == error::ssl_category)
|
||||
if (category_ == ssl_ecat)
|
||||
return "SSL error.";
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
value_type value = value_;
|
||||
if (category() != error::system_category && *this != error::eof)
|
||||
return "asio error";
|
||||
if (*this == error::eof)
|
||||
value = ERROR_HANDLE_EOF;
|
||||
char* msg = 0;
|
||||
|
@ -78,8 +76,6 @@ inline std::string error_code::message() const
|
|||
return "Service not found.";
|
||||
if (*this == error::socket_type_not_supported)
|
||||
return "Socket type not supported.";
|
||||
if (category() != error::system_category)
|
||||
return "asio error";
|
||||
#if defined(__sun) || defined(__QNX__)
|
||||
return strerror(value_);
|
||||
#elif defined(__MACH__) && defined(__APPLE__) \
|
||||
|
|
|
@ -128,11 +128,11 @@ template <typename Handler>
|
|||
#if defined(GENERATING_DOCUMENTATION)
|
||||
unspecified
|
||||
#else
|
||||
inline detail::wrapped_handler<io_service&, Handler>
|
||||
inline detail::wrapped_handler<io_service, Handler>
|
||||
#endif
|
||||
io_service::wrap(Handler handler)
|
||||
{
|
||||
return detail::wrapped_handler<io_service&, Handler>(*this, handler);
|
||||
return detail::wrapped_handler<io_service, Handler>(*this, handler);
|
||||
}
|
||||
|
||||
inline io_service::work::work(asio::io_service& io_service)
|
||||
|
|
|
@ -311,8 +311,7 @@ namespace detail
|
|||
if (streambuf_.size() == streambuf_.max_size())
|
||||
{
|
||||
std::size_t bytes = 0;
|
||||
asio::error_code ec(error::not_found);
|
||||
handler_(ec, bytes);
|
||||
handler_(error::not_found, bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -389,8 +388,7 @@ void async_read_until(AsyncReadStream& s,
|
|||
// No match. Check if buffer is full.
|
||||
if (b.size() == b.max_size())
|
||||
{
|
||||
asio::error_code ec(error::not_found);
|
||||
s.io_service().post(detail::bind_handler(handler, ec, 0));
|
||||
s.io_service().post(detail::bind_handler(handler, error::not_found, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -471,8 +469,7 @@ namespace detail
|
|||
if (streambuf_.size() == streambuf_.max_size())
|
||||
{
|
||||
std::size_t bytes = 0;
|
||||
asio::error_code ec(error::not_found);
|
||||
handler_(ec, bytes);
|
||||
handler_(error::not_found, bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -562,8 +559,7 @@ void async_read_until(AsyncReadStream& s,
|
|||
// Check if buffer is full.
|
||||
if (b.size() == b.max_size())
|
||||
{
|
||||
asio::error_code ec(error::not_found);
|
||||
s.io_service().post(detail::bind_handler(handler, ec, 0));
|
||||
s.io_service().post(detail::bind_handler(handler, error::not_found, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -645,8 +641,7 @@ namespace detail
|
|||
if (streambuf_.size() == streambuf_.max_size())
|
||||
{
|
||||
std::size_t bytes = 0;
|
||||
asio::error_code ec(error::not_found);
|
||||
handler_(ec, bytes);
|
||||
handler_(error::not_found, bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -736,8 +731,7 @@ void async_read_until(AsyncReadStream& s,
|
|||
// Check if buffer is full.
|
||||
if (b.size() == b.max_size())
|
||||
{
|
||||
asio::error_code ec(error::not_found);
|
||||
s.io_service().post(detail::bind_handler(handler, ec, 0));
|
||||
s.io_service().post(detail::bind_handler(handler, error::not_found, 0));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -320,7 +320,7 @@ public:
|
|||
#if defined(GENERATING_DOCUMENTATION)
|
||||
unspecified
|
||||
#else
|
||||
detail::wrapped_handler<io_service&, Handler>
|
||||
detail::wrapped_handler<io_service, Handler>
|
||||
#endif
|
||||
wrap(Handler handler);
|
||||
|
||||
|
|
|
@ -172,7 +172,7 @@ public:
|
|||
/// The protocol associated with the endpoint.
|
||||
protocol_type protocol() const
|
||||
{
|
||||
if (is_v4(data_))
|
||||
if (is_v4())
|
||||
return InternetProtocol::v4();
|
||||
return InternetProtocol::v6();
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ public:
|
|||
/// Get the underlying size of the endpoint in the native type.
|
||||
size_type size() const
|
||||
{
|
||||
if (is_v4(data_))
|
||||
if (is_v4())
|
||||
return sizeof(asio::detail::sockaddr_in4_type);
|
||||
else
|
||||
return sizeof(asio::detail::sockaddr_in6_type);
|
||||
|
@ -218,7 +218,7 @@ public:
|
|||
/// the host's byte order.
|
||||
unsigned short port() const
|
||||
{
|
||||
if (is_v4(data_))
|
||||
if (is_v4())
|
||||
{
|
||||
return asio::detail::socket_ops::network_to_host_short(
|
||||
reinterpret_cast<const asio::detail::sockaddr_in4_type&>(
|
||||
|
@ -236,7 +236,7 @@ public:
|
|||
/// the host's byte order.
|
||||
void port(unsigned short port_num)
|
||||
{
|
||||
if (is_v4(data_))
|
||||
if (is_v4())
|
||||
{
|
||||
reinterpret_cast<asio::detail::sockaddr_in4_type&>(data_).sin_port
|
||||
= asio::detail::socket_ops::host_to_network_short(port_num);
|
||||
|
@ -252,7 +252,7 @@ public:
|
|||
asio::ip::address address() const
|
||||
{
|
||||
using namespace std; // For memcpy.
|
||||
if (is_v4(data_))
|
||||
if (is_v4())
|
||||
{
|
||||
const asio::detail::sockaddr_in4_type& data
|
||||
= reinterpret_cast<const asio::detail::sockaddr_in4_type&>(
|
||||
|
@ -306,26 +306,14 @@ public:
|
|||
|
||||
private:
|
||||
// Helper function to determine whether the endpoint is IPv4.
|
||||
bool is_v4() const
|
||||
{
|
||||
#if defined(_AIX)
|
||||
template <typename T, unsigned char (T::*)> struct is_v4_helper {};
|
||||
|
||||
template <typename T>
|
||||
static bool is_v4(const T& ss, is_v4_helper<T, &T::ss_family>* = 0)
|
||||
{
|
||||
return ss.ss_family == AF_INET;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool is_v4(const T& ss, is_v4_helper<T, &T::__ss_family>* = 0)
|
||||
{
|
||||
return ss.__ss_family == AF_INET;
|
||||
}
|
||||
return data_.__ss_family == AF_INET;
|
||||
#else
|
||||
static bool is_v4(const asio::detail::sockaddr_storage_type& ss)
|
||||
{
|
||||
return ss.ss_family == AF_INET;
|
||||
}
|
||||
return data_.ss_family == AF_INET;
|
||||
#endif
|
||||
}
|
||||
|
||||
// The underlying IP socket address.
|
||||
asio::detail::sockaddr_storage_type data_;
|
||||
|
|
|
@ -174,12 +174,12 @@ public:
|
|||
if (error_code == SSL_ERROR_SYSCALL)
|
||||
{
|
||||
return handler_(asio::error_code(
|
||||
sys_error_code, asio::error::system_category), rc);
|
||||
sys_error_code, asio::native_ecat), rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
return handler_(asio::error_code(
|
||||
error_code, asio::error::ssl_category), rc);
|
||||
error_code, asio::ssl_ecat), rc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <memory>
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include <typeinfo>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -55,7 +56,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "libtorrent/time.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
#ifndef TORRENT_MAX_ALERT_TYPES
|
||||
#define TORRENT_MAX_ALERT_TYPES 15
|
||||
|
|
|
@ -38,7 +38,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/peer_connection.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -224,7 +223,7 @@ namespace libtorrent
|
|||
{
|
||||
block_downloading_alert(
|
||||
const torrent_handle& h
|
||||
, char const* speedmsg
|
||||
, std::string& speedmsg
|
||||
, int block_num
|
||||
, int piece_num
|
||||
, const std::string& msg)
|
||||
|
@ -262,17 +261,6 @@ namespace libtorrent
|
|||
{ return std::auto_ptr<alert>(new torrent_paused_alert(*this)); }
|
||||
};
|
||||
|
||||
struct TORRENT_EXPORT torrent_checked_alert: torrent_alert
|
||||
{
|
||||
torrent_checked_alert(torrent_handle const& h, std::string const& msg)
|
||||
: torrent_alert(h, alert::info, msg)
|
||||
{}
|
||||
|
||||
virtual std::auto_ptr<alert> clone() const
|
||||
{ return std::auto_ptr<alert>(new torrent_checked_alert(*this)); }
|
||||
};
|
||||
|
||||
|
||||
struct TORRENT_EXPORT url_seed_alert: torrent_alert
|
||||
{
|
||||
url_seed_alert(
|
||||
|
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2007, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#ifndef NDEBUG
|
||||
#if (defined __linux__ || defined __MACH__) && defined __GNUC__
|
||||
#ifdef assert
|
||||
#undef assert
|
||||
#endif
|
||||
|
||||
#include "libtorrent/config.hpp"
|
||||
|
||||
TORRENT_EXPORT void assert_fail(const char* expr, int line, char const* file, char const* function);
|
||||
|
||||
#define assert(x) if (x) {} else assert_fail(#x, __LINE__, __FILE__, __PRETTY_FUNCTION__)
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
#ifndef assert
|
||||
#define assert(x) (void)
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -83,7 +83,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/socket_type.hpp"
|
||||
#include "libtorrent/connection_queue.hpp"
|
||||
#include "libtorrent/disk_io_thread.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -185,7 +184,7 @@ namespace libtorrent
|
|||
~session_impl();
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> ext);
|
||||
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*)> ext);
|
||||
#endif
|
||||
void operator()();
|
||||
|
||||
|
@ -241,13 +240,12 @@ namespace libtorrent
|
|||
bool is_listening() const;
|
||||
|
||||
torrent_handle add_torrent(
|
||||
boost::intrusive_ptr<torrent_info> ti
|
||||
torrent_info const& ti
|
||||
, fs::path const& save_path
|
||||
, entry const& resume_data
|
||||
, bool compact_mode
|
||||
, storage_constructor_type sc
|
||||
, bool paused
|
||||
, void* userdata);
|
||||
, int block_size
|
||||
, storage_constructor_type sc);
|
||||
|
||||
torrent_handle add_torrent(
|
||||
char const* tracker_url
|
||||
|
@ -256,9 +254,8 @@ namespace libtorrent
|
|||
, fs::path const& save_path
|
||||
, entry const& resume_data
|
||||
, bool compact_mode
|
||||
, storage_constructor_type sc
|
||||
, bool paused
|
||||
, void* userdata);
|
||||
, int block_size
|
||||
, storage_constructor_type sc);
|
||||
|
||||
void remove_torrent(torrent_handle const& h);
|
||||
|
||||
|
@ -276,21 +273,8 @@ namespace libtorrent
|
|||
void set_max_connections(int limit);
|
||||
void set_max_uploads(int limit);
|
||||
|
||||
int max_connections() const { return m_max_connections; }
|
||||
int max_uploads() const { return m_max_uploads; }
|
||||
int max_half_open_connections() const { return m_half_open.limit(); }
|
||||
|
||||
int num_uploads() const { return m_num_unchoked; }
|
||||
int num_connections() const
|
||||
{ return m_connections.size(); }
|
||||
|
||||
void unchoke_peer(peer_connection& c)
|
||||
{
|
||||
torrent* t = c.associated_torrent().lock().get();
|
||||
assert(t);
|
||||
if (t->unchoke_peer(c))
|
||||
++m_num_unchoked;
|
||||
}
|
||||
int num_uploads() const;
|
||||
int num_connections() const;
|
||||
|
||||
session_status status() const;
|
||||
void set_peer_id(peer_id const& id);
|
||||
|
@ -433,28 +417,6 @@ namespace libtorrent
|
|||
int m_max_uploads;
|
||||
int m_max_connections;
|
||||
|
||||
// the number of unchoked peers
|
||||
int m_num_unchoked;
|
||||
|
||||
// this is initialized to the unchoke_interval
|
||||
// session_setting and decreased every second.
|
||||
// when it reaches zero, it is reset to the
|
||||
// unchoke_interval and the unchoke set is
|
||||
// recomputed.
|
||||
int m_unchoke_time_scaler;
|
||||
|
||||
// works like unchoke_time_scaler but it
|
||||
// is only decresed when the unchoke set
|
||||
// is recomputed, and when it reaches zero,
|
||||
// the optimistic unchoke is moved to another peer.
|
||||
int m_optimistic_unchoke_time_scaler;
|
||||
|
||||
// works like unchoke_time_scaler. Each time
|
||||
// it reaches 0, and all the connections are
|
||||
// used, the worst connection will be disconnected
|
||||
// from the torrent with the most peers
|
||||
int m_disconnect_time_scaler;
|
||||
|
||||
// statistics gathered from all torrents.
|
||||
stat m_stat;
|
||||
|
||||
|
@ -497,7 +459,7 @@ namespace libtorrent
|
|||
// This implements a round robin.
|
||||
int m_next_connect_torrent;
|
||||
#ifndef NDEBUG
|
||||
void check_invariant() const;
|
||||
void check_invariant(const char *place = 0);
|
||||
#endif
|
||||
|
||||
#ifdef TORRENT_STATS
|
||||
|
@ -521,7 +483,7 @@ namespace libtorrent
|
|||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
typedef std::list<boost::function<boost::shared_ptr<
|
||||
torrent_plugin>(torrent*, void*)> > extension_list_t;
|
||||
torrent_plugin>(torrent*)> > extension_list_t;
|
||||
|
||||
extension_list_t m_extensions;
|
||||
#endif
|
||||
|
|
|
@ -33,6 +33,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef TORRENT_BANDWIDTH_MANAGER_HPP_INCLUDED
|
||||
#define TORRENT_BANDWIDTH_MANAGER_HPP_INCLUDED
|
||||
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/invariant_check.hpp"
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
@ -41,17 +44,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <boost/thread/mutex.hpp>
|
||||
#include <deque>
|
||||
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/invariant_check.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
using boost::weak_ptr;
|
||||
using boost::shared_ptr;
|
||||
using boost::intrusive_ptr;
|
||||
using boost::bind;
|
||||
|
||||
//#define TORRENT_VERBOSE_BANDWIDTH_LIMIT
|
||||
|
||||
namespace libtorrent {
|
||||
|
||||
// the maximum block of bandwidth quota to
|
||||
|
@ -180,7 +177,6 @@ struct bandwidth_manager
|
|||
, m_limit(bandwidth_limit::inf)
|
||||
, m_current_quota(0)
|
||||
, m_channel(channel)
|
||||
, m_in_hand_out_bandwidth(false)
|
||||
{}
|
||||
|
||||
void throttle(int limit) throw()
|
||||
|
@ -241,10 +237,8 @@ struct bandwidth_manager
|
|||
i = j;
|
||||
}
|
||||
}
|
||||
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
|
||||
std::cerr << " req_bandwidht. m_queue.size() = " << m_queue.size() << std::endl;
|
||||
#endif
|
||||
if (!m_queue.empty()) hand_out_bandwidth();
|
||||
|
||||
if (m_queue.size() == 1) hand_out_bandwidth();
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -329,10 +323,6 @@ private:
|
|||
|
||||
void hand_out_bandwidth() throw()
|
||||
{
|
||||
// if we're already handing out bandwidth, just return back
|
||||
// to the loop further down on the callstack
|
||||
if (m_in_hand_out_bandwidth) return;
|
||||
m_in_hand_out_bandwidth = true;
|
||||
#ifndef NDEBUG
|
||||
try {
|
||||
#endif
|
||||
|
@ -347,18 +337,10 @@ private:
|
|||
// available bandwidth to hand out
|
||||
int amount = limit - m_current_quota;
|
||||
|
||||
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
|
||||
std::cerr << " hand_out_bandwidht. m_queue.size() = " << m_queue.size()
|
||||
<< " amount = " << amount
|
||||
<< " limit = " << limit
|
||||
<< " m_current_quota = " << m_current_quota << std::endl;
|
||||
#endif
|
||||
|
||||
while (!m_queue.empty() && amount > 0)
|
||||
{
|
||||
assert(amount == limit - m_current_quota);
|
||||
bw_queue_entry<PeerConnection> qe = m_queue.front();
|
||||
assert(qe.max_block_size > 0);
|
||||
m_queue.pop_front();
|
||||
|
||||
shared_ptr<Torrent> t = qe.peer->associated_torrent().lock();
|
||||
|
@ -366,7 +348,6 @@ private:
|
|||
if (qe.peer->is_disconnecting())
|
||||
{
|
||||
t->expire_bandwidth(m_channel, qe.max_block_size);
|
||||
assert(amount == limit - m_current_quota);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -380,7 +361,6 @@ private:
|
|||
if (max_assignable == 0)
|
||||
{
|
||||
t->expire_bandwidth(m_channel, qe.max_block_size);
|
||||
assert(amount == limit - m_current_quota);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -394,16 +374,17 @@ private:
|
|||
// block size must be smaller for lower rates. This is because
|
||||
// the history window is one second, and the block will be forgotten
|
||||
// after one second.
|
||||
int block_size = (std::min)(qe.peer->bandwidth_throttle(m_channel)
|
||||
, limit / 10);
|
||||
int block_size = (std::min)(qe.max_block_size
|
||||
, (std::min)(qe.peer->bandwidth_throttle(m_channel)
|
||||
, m_limit / 10));
|
||||
|
||||
if (block_size < min_bandwidth_block_size)
|
||||
{
|
||||
block_size = (std::min)(int(min_bandwidth_block_size), limit);
|
||||
block_size = min_bandwidth_block_size;
|
||||
}
|
||||
else if (block_size > max_bandwidth_block_size)
|
||||
{
|
||||
if (limit == bandwidth_limit::inf)
|
||||
if (m_limit == bandwidth_limit::inf)
|
||||
{
|
||||
block_size = max_bandwidth_block_size;
|
||||
}
|
||||
|
@ -414,15 +395,11 @@ private:
|
|||
// as possible
|
||||
// TODO: move this calculcation to where the limit
|
||||
// is changed
|
||||
block_size = limit
|
||||
/ (limit / max_bandwidth_block_size);
|
||||
block_size = m_limit
|
||||
/ (m_limit / max_bandwidth_block_size);
|
||||
}
|
||||
}
|
||||
if (block_size > qe.max_block_size) block_size = qe.max_block_size;
|
||||
|
||||
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
|
||||
std::cerr << " block_size = " << block_size << " amount = " << amount << std::endl;
|
||||
#endif
|
||||
if (amount < block_size / 2)
|
||||
{
|
||||
m_queue.push_front(qe);
|
||||
|
@ -435,21 +412,18 @@ private:
|
|||
int hand_out_amount = (std::min)((std::min)(block_size, max_assignable)
|
||||
, amount);
|
||||
assert(hand_out_amount > 0);
|
||||
assert(amount == limit - m_current_quota);
|
||||
amount -= hand_out_amount;
|
||||
assert(hand_out_amount <= qe.max_block_size);
|
||||
t->assign_bandwidth(m_channel, hand_out_amount, qe.max_block_size);
|
||||
qe.peer->assign_bandwidth(m_channel, hand_out_amount);
|
||||
add_history_entry(history_entry<PeerConnection, Torrent>(
|
||||
qe.peer, t, hand_out_amount, now + bw_window_size));
|
||||
assert(amount == limit - m_current_quota);
|
||||
}
|
||||
#ifndef NDEBUG
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{ assert(false); };
|
||||
#endif
|
||||
m_in_hand_out_bandwidth = false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -482,11 +456,6 @@ private:
|
|||
// this is the channel within the consumers
|
||||
// that bandwidth is assigned to (upload or download)
|
||||
int m_channel;
|
||||
|
||||
// this is true while we're in the hand_out_bandwidth loop
|
||||
// to prevent recursive invocations to interfere
|
||||
bool m_in_hand_out_bandwidth;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -79,8 +79,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/entry.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
namespace std
|
||||
{
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2007, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TORRENT_BROADCAST_SOCKET_HPP_INCLUDED
|
||||
#define TORRENT_BROADCAST_SOCKET_HPP_INCLUDED
|
||||
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <list>
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
||||
bool is_local(address const& a);
|
||||
bool is_loopback(address const& addr);
|
||||
bool is_multicast(address const& addr);
|
||||
|
||||
address_v4 guess_local_address(asio::io_service&);
|
||||
|
||||
typedef boost::function<void(udp::endpoint const& from
|
||||
, char* buffer, int size)> receive_handler_t;
|
||||
|
||||
class broadcast_socket
|
||||
{
|
||||
public:
|
||||
broadcast_socket(asio::io_service& ios, udp::endpoint const& multicast_endpoint
|
||||
, receive_handler_t const& handler, bool loopback = true);
|
||||
~broadcast_socket() { close(); }
|
||||
|
||||
void send(char const* buffer, int size, asio::error_code& ec);
|
||||
void close();
|
||||
|
||||
private:
|
||||
|
||||
struct socket_entry
|
||||
{
|
||||
socket_entry(boost::shared_ptr<datagram_socket> const& s): socket(s) {}
|
||||
boost::shared_ptr<datagram_socket> socket;
|
||||
char buffer[1024];
|
||||
udp::endpoint remote;
|
||||
};
|
||||
|
||||
void on_receive(socket_entry* s, asio::error_code const& ec
|
||||
, std::size_t bytes_transferred);
|
||||
|
||||
std::list<socket_entry> m_sockets;
|
||||
udp::endpoint m_multicast_endpoint;
|
||||
receive_handler_t m_on_receive;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -65,6 +65,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/alert.hpp"
|
||||
#include "libtorrent/torrent_handle.hpp"
|
||||
#include "libtorrent/torrent.hpp"
|
||||
#include "libtorrent/allocate_resources.hpp"
|
||||
#include "libtorrent/peer_request.hpp"
|
||||
#include "libtorrent/piece_block_progress.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
|
@ -121,16 +122,8 @@ namespace libtorrent
|
|||
msg_request,
|
||||
msg_piece,
|
||||
msg_cancel,
|
||||
// DHT extension
|
||||
msg_dht_port,
|
||||
// FAST extension
|
||||
msg_suggest_piece = 0xd,
|
||||
msg_have_all,
|
||||
msg_have_none,
|
||||
msg_reject_request,
|
||||
msg_allowed_fast,
|
||||
|
||||
// extension protocol message
|
||||
// extension protocol message
|
||||
msg_extended = 20,
|
||||
|
||||
num_supported_messages
|
||||
|
@ -181,17 +174,8 @@ namespace libtorrent
|
|||
void on_request(int received);
|
||||
void on_piece(int received);
|
||||
void on_cancel(int received);
|
||||
|
||||
// DHT extension
|
||||
void on_dht_port(int received);
|
||||
|
||||
// FAST extension
|
||||
void on_suggest_piece(int received);
|
||||
void on_have_all(int received);
|
||||
void on_have_none(int received);
|
||||
void on_reject_request(int received);
|
||||
void on_allowed_fast(int received);
|
||||
|
||||
void on_extended(int received);
|
||||
|
||||
void on_extended_handshake();
|
||||
|
@ -217,16 +201,7 @@ namespace libtorrent
|
|||
void write_metadata(std::pair<int, int> req);
|
||||
void write_metadata_request(std::pair<int, int> req);
|
||||
void write_keepalive();
|
||||
|
||||
// DHT extension
|
||||
void write_dht_port(int listen_port);
|
||||
|
||||
// FAST extension
|
||||
void write_have_all();
|
||||
void write_have_none();
|
||||
void write_reject_request(peer_request const&);
|
||||
void write_allow_fast(int piece);
|
||||
|
||||
void on_connected();
|
||||
void on_metadata();
|
||||
|
||||
|
@ -350,7 +325,6 @@ namespace libtorrent
|
|||
bool m_supports_extensions;
|
||||
#endif
|
||||
bool m_supports_dht_port;
|
||||
bool m_supports_fast;
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
// this is set to true after the encryption method has been
|
||||
|
|
|
@ -34,9 +34,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
//#define TORRENT_BUFFER_DEBUG
|
||||
|
||||
#include <memory>
|
||||
#include "libtorrent/invariant_check.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
#include <memory>
|
||||
|
||||
namespace libtorrent {
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <list>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/time.hpp"
|
||||
|
||||
|
@ -89,10 +88,6 @@ private:
|
|||
int m_half_open_limit;
|
||||
|
||||
deadline_timer m_timer;
|
||||
|
||||
typedef boost::recursive_mutex mutex_t;
|
||||
mutable mutex_t m_mutex;
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool m_in_timeout_function;
|
||||
#endif
|
||||
|
|
|
@ -80,4 +80,3 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#endif // TORRENT_DEBUG_HPP_INCLUDED
|
||||
|
||||
|
|
|
@ -30,10 +30,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
*/
|
||||
|
||||
#ifdef TORRENT_DISK_STATS
|
||||
#include <fstream>
|
||||
#endif
|
||||
|
||||
#include "libtorrent/storage.hpp"
|
||||
#include <boost/thread/thread.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
@ -54,7 +50,6 @@ namespace libtorrent
|
|||
, buffer_size(0)
|
||||
, piece(0)
|
||||
, offset(0)
|
||||
, priority(0)
|
||||
{}
|
||||
|
||||
enum action_t
|
||||
|
@ -77,12 +72,6 @@ namespace libtorrent
|
|||
// to the error message
|
||||
std::string str;
|
||||
|
||||
// priority decides whether or not this
|
||||
// job will skip entries in the queue or
|
||||
// not. It always skips in front of entries
|
||||
// with lower priority
|
||||
int priority;
|
||||
|
||||
// this is called when operation completes
|
||||
boost::function<void(int, disk_io_job const&)> callback;
|
||||
};
|
||||
|
@ -126,10 +115,6 @@ namespace libtorrent
|
|||
int m_block_size;
|
||||
#endif
|
||||
|
||||
#ifdef TORRENT_DISK_STATS
|
||||
std::ofstream m_log;
|
||||
#endif
|
||||
|
||||
// thread for performing blocking disk io operations
|
||||
boost::thread m_disk_io_thread;
|
||||
};
|
||||
|
|
|
@ -64,10 +64,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <list>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
|
||||
#include "libtorrent/size_type.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2007, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TORRENT_ENUM_NET_HPP_INCLUDED
|
||||
#define TORRENT_ENUM_NET_HPP_INCLUDED
|
||||
|
||||
#include "libtorrent/socket.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
std::vector<address> const& enum_net_interfaces(asio::io_service& ios, asio::error_code& ec);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -131,15 +131,6 @@ namespace libtorrent
|
|||
virtual bool on_bitfield(std::vector<bool> const& bitfield)
|
||||
{ return false; }
|
||||
|
||||
virtual bool on_have_all()
|
||||
{ return false; }
|
||||
|
||||
virtual bool on_have_none()
|
||||
{ return false; }
|
||||
|
||||
virtual bool on_allowed_fast(int index)
|
||||
{ return false; }
|
||||
|
||||
virtual bool on_request(peer_request const& req)
|
||||
{ return false; }
|
||||
|
||||
|
@ -149,12 +140,6 @@ namespace libtorrent
|
|||
virtual bool on_cancel(peer_request const& req)
|
||||
{ return false; }
|
||||
|
||||
virtual bool on_reject(peer_request const& req)
|
||||
{ return false; }
|
||||
|
||||
virtual bool on_suggest(int index)
|
||||
{ return false; }
|
||||
|
||||
// called when an extended message is received. If returning true,
|
||||
// the message is not processed by any other plugin and if false
|
||||
// is returned the next plugin in the chain will receive it to
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace libtorrent
|
|||
{
|
||||
struct torrent_plugin;
|
||||
class torrent;
|
||||
TORRENT_EXPORT boost::shared_ptr<torrent_plugin> create_metadata_plugin(torrent*, void*);
|
||||
TORRENT_EXPORT boost::shared_ptr<torrent_plugin> create_metadata_plugin(torrent*);
|
||||
}
|
||||
|
||||
#endif // TORRENT_METADATA_TRANSFER_HPP_INCLUDED
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace libtorrent
|
|||
{
|
||||
struct torrent_plugin;
|
||||
class torrent;
|
||||
TORRENT_EXPORT boost::shared_ptr<torrent_plugin> create_ut_pex_plugin(torrent*, void*);
|
||||
TORRENT_EXPORT boost::shared_ptr<torrent_plugin> create_ut_pex_plugin(torrent*);
|
||||
}
|
||||
|
||||
#endif // TORRENT_UT_PEX_EXTENSION_HPP_INCLUDED
|
||||
|
|
|
@ -37,7 +37,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <sstream>
|
||||
|
||||
#include "libtorrent/peer_id.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -92,4 +91,3 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#endif // TORRENT_FINGERPRINT_HPP_INCLUDED
|
||||
|
||||
|
|
|
@ -33,11 +33,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef TORRENT_HASHER_HPP_INCLUDED
|
||||
#define TORRENT_HASHER_HPP_INCLUDED
|
||||
|
||||
#include <cassert>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#include "libtorrent/peer_id.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
#include "zlib.h"
|
||||
|
||||
#ifdef TORRENT_USE_OPENSSL
|
||||
|
|
|
@ -44,18 +44,13 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/http_tracker_connection.hpp"
|
||||
#include "libtorrent/time.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
||||
struct http_connection;
|
||||
|
||||
typedef boost::function<void(asio::error_code const&
|
||||
, http_parser const&, char const* data, int size)> http_handler;
|
||||
|
||||
typedef boost::function<void(http_connection&)> http_connect_handler;
|
||||
|
||||
// TODO: add bind interface
|
||||
|
||||
// when bottled, the last two arguments to the handler
|
||||
|
@ -63,13 +58,11 @@ typedef boost::function<void(http_connection&)> http_connect_handler;
|
|||
struct http_connection : boost::enable_shared_from_this<http_connection>, boost::noncopyable
|
||||
{
|
||||
http_connection(asio::io_service& ios, connection_queue& cc
|
||||
, http_handler const& handler, bool bottled = true
|
||||
, http_connect_handler const& ch = http_connect_handler())
|
||||
, http_handler handler, bool bottled = true)
|
||||
: m_sock(ios)
|
||||
, m_read_pos(0)
|
||||
, m_resolver(ios)
|
||||
, m_handler(handler)
|
||||
, m_connect_handler(ch)
|
||||
, m_timer(ios)
|
||||
, m_last_receive(time_now())
|
||||
, m_bottled(bottled)
|
||||
|
@ -99,8 +92,6 @@ struct http_connection : boost::enable_shared_from_this<http_connection>, boost:
|
|||
, time_duration timeout, bool handle_redirect = true);
|
||||
void close();
|
||||
|
||||
tcp::socket const& socket() const { return m_sock; }
|
||||
|
||||
private:
|
||||
|
||||
void on_resolve(asio::error_code const& e
|
||||
|
@ -121,7 +112,6 @@ private:
|
|||
tcp::resolver m_resolver;
|
||||
http_parser m_parser;
|
||||
http_handler m_handler;
|
||||
http_connect_handler m_connect_handler;
|
||||
deadline_timer m_timer;
|
||||
time_duration m_timeout;
|
||||
ptime m_last_receive;
|
||||
|
|
|
@ -73,8 +73,6 @@ namespace libtorrent
|
|||
T header(char const* key) const;
|
||||
std::string const& protocol() const { return m_protocol; }
|
||||
int status_code() const { return m_status_code; }
|
||||
std::string const& method() const { return m_method; }
|
||||
std::string const& path() const { return m_path; }
|
||||
std::string message() const { return m_server_message; }
|
||||
buffer::const_interval get_body() const;
|
||||
bool header_finished() const { return m_state == read_body; }
|
||||
|
@ -87,8 +85,6 @@ namespace libtorrent
|
|||
private:
|
||||
int m_recv_pos;
|
||||
int m_status_code;
|
||||
std::string m_method;
|
||||
std::string m_path;
|
||||
std::string m_protocol;
|
||||
std::string m_server_message;
|
||||
|
||||
|
|
|
@ -34,17 +34,14 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define TORRENT_INTRUSIVE_PTR_BASE
|
||||
|
||||
#include <boost/detail/atomic_count.hpp>
|
||||
#include <cassert>
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
template<class T>
|
||||
struct intrusive_ptr_base
|
||||
{
|
||||
intrusive_ptr_base(intrusive_ptr_base<T> const&)
|
||||
: m_refs(0) {}
|
||||
|
||||
friend void intrusive_ptr_add_ref(intrusive_ptr_base<T> const* s)
|
||||
{
|
||||
assert(s->m_refs >= 0);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#ifndef TORRENT_INVARIANT_ACCESS_HPP_INCLUDED
|
||||
#define TORRENT_INVARIANT_ACCESS_HPP_INCLUDED
|
||||
|
||||
#include "libtorrent/assert.hpp"
|
||||
#include <cassert>
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
|
|
@ -33,9 +33,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef TORRENT_IP_FILTER_HPP
|
||||
#define TORRENT_IP_FILTER_HPP
|
||||
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push, 1)
|
||||
#endif
|
||||
|
@ -51,7 +48,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
|
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define NODE_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
|
@ -44,7 +45,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <libtorrent/io.hpp>
|
||||
#include <libtorrent/session_settings.hpp>
|
||||
#include <libtorrent/assert.hpp>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
|
|
@ -33,10 +33,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define NODE_ID_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include "libtorrent/peer_id.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent { namespace dht
|
||||
{
|
||||
|
|
|
@ -50,7 +50,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <libtorrent/kademlia/node_entry.hpp>
|
||||
#include <libtorrent/session_settings.hpp>
|
||||
#include <libtorrent/size_type.hpp>
|
||||
#include <libtorrent/assert.hpp>
|
||||
|
||||
namespace libtorrent { namespace dht
|
||||
{
|
||||
|
|
|
@ -35,7 +35,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/peer_id.hpp"
|
||||
#include "libtorrent/broadcast_socket.hpp"
|
||||
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
@ -59,26 +58,35 @@ public:
|
|||
, peer_callback_t const& cb);
|
||||
~lsd();
|
||||
|
||||
// void rebind(address const& listen_interface);
|
||||
void rebind(address const& listen_interface);
|
||||
|
||||
void announce(sha1_hash const& ih, int listen_port);
|
||||
void close();
|
||||
|
||||
private:
|
||||
|
||||
static address_v4 lsd_multicast_address;
|
||||
static udp::endpoint lsd_multicast_endpoint;
|
||||
|
||||
void resend_announce(asio::error_code const& e, std::string msg);
|
||||
void on_announce(udp::endpoint const& from, char* buffer
|
||||
void on_announce(asio::error_code const& e
|
||||
, std::size_t bytes_transferred);
|
||||
// void setup_receive();
|
||||
void setup_receive();
|
||||
|
||||
peer_callback_t m_callback;
|
||||
|
||||
// current retry count
|
||||
int m_retry_count;
|
||||
|
||||
// used to receive responses in
|
||||
char m_receive_buffer[1024];
|
||||
|
||||
// the endpoint we received the message from
|
||||
udp::endpoint m_remote;
|
||||
|
||||
// the udp socket used to send and receive
|
||||
// multicast messages on
|
||||
broadcast_socket m_socket;
|
||||
datagram_socket m_socket;
|
||||
|
||||
// used to resend udp packets in case
|
||||
// they time out
|
||||
|
|
|
@ -35,12 +35,13 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef TORRENT_PE_CRYPTO_HPP_INCLUDED
|
||||
#define TORRENT_PE_CRYPTO_HPP_INCLUDED
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/rc4.h>
|
||||
|
||||
#include "libtorrent/peer_id.hpp" // For sha1_hash
|
||||
#include "libtorrent/assert.hpp"
|
||||
#include "peer_id.hpp" // For sha1_hash
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
|
|
@ -64,6 +64,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/alert.hpp"
|
||||
#include "libtorrent/torrent_handle.hpp"
|
||||
#include "libtorrent/torrent.hpp"
|
||||
#include "libtorrent/allocate_resources.hpp"
|
||||
#include "libtorrent/peer_request.hpp"
|
||||
#include "libtorrent/piece_block_progress.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
|
@ -72,7 +73,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/policy.hpp"
|
||||
#include "libtorrent/socket_type.hpp"
|
||||
#include "libtorrent/intrusive_ptr_base.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -131,8 +131,6 @@ namespace libtorrent
|
|||
enum peer_speed_t { slow, medium, fast };
|
||||
peer_speed_t peer_speed();
|
||||
|
||||
void send_allowed_set();
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
void add_extension(boost::shared_ptr<peer_plugin>);
|
||||
#endif
|
||||
|
@ -153,17 +151,11 @@ namespace libtorrent
|
|||
int upload_limit() const { return m_upload_limit; }
|
||||
int download_limit() const { return m_download_limit; }
|
||||
|
||||
int prefer_whole_pieces() const
|
||||
{
|
||||
if (on_parole()) return 1;
|
||||
return m_prefer_whole_pieces;
|
||||
}
|
||||
bool prefer_whole_pieces() const
|
||||
{ return m_prefer_whole_pieces; }
|
||||
|
||||
bool on_parole() const
|
||||
{ return peer_info_struct() && peer_info_struct()->on_parole; }
|
||||
|
||||
void prefer_whole_pieces(int num)
|
||||
{ m_prefer_whole_pieces = num; }
|
||||
void prefer_whole_pieces(bool b)
|
||||
{ m_prefer_whole_pieces = b; }
|
||||
|
||||
bool request_large_blocks() const
|
||||
{ return m_request_large_blocks; }
|
||||
|
@ -194,9 +186,9 @@ namespace libtorrent
|
|||
void set_pid(const peer_id& pid) { m_peer_id = pid; }
|
||||
bool has_piece(int i) const;
|
||||
|
||||
std::deque<piece_block> const& download_queue() const;
|
||||
std::deque<piece_block> const& request_queue() const;
|
||||
std::deque<peer_request> const& upload_queue() const;
|
||||
const std::deque<piece_block>& download_queue() const;
|
||||
const std::deque<piece_block>& request_queue() const;
|
||||
const std::deque<peer_request>& upload_queue() const;
|
||||
|
||||
bool is_interesting() const { return m_interesting; }
|
||||
bool is_choked() const { return m_choked; }
|
||||
|
@ -219,14 +211,12 @@ namespace libtorrent
|
|||
void add_stat(size_type downloaded, size_type uploaded);
|
||||
|
||||
// is called once every second by the main loop
|
||||
void second_tick(float tick_interval) throw();
|
||||
void second_tick(float tick_interval);
|
||||
|
||||
boost::shared_ptr<socket_type> get_socket() const { return m_socket; }
|
||||
tcp::endpoint const& remote() const { return m_remote; }
|
||||
|
||||
std::vector<bool> const& get_bitfield() const;
|
||||
std::vector<int> const& allowed_fast();
|
||||
std::vector<int> const& suggested_pieces() const { return m_suggested_pieces; }
|
||||
|
||||
void timed_out();
|
||||
// this will cause this peer_connection to be disconnected.
|
||||
|
@ -304,14 +294,7 @@ namespace libtorrent
|
|||
void incoming_piece(peer_request const& p, char const* data);
|
||||
void incoming_piece_fragment();
|
||||
void incoming_cancel(peer_request const& r);
|
||||
|
||||
void incoming_dht_port(int listen_port);
|
||||
|
||||
void incoming_reject_request(peer_request const& r);
|
||||
void incoming_have_all();
|
||||
void incoming_have_none();
|
||||
void incoming_allowed_fast(int index);
|
||||
void incoming_suggest(int index);
|
||||
|
||||
// the following functions appends messages
|
||||
// to the send buffer
|
||||
|
@ -390,9 +373,6 @@ namespace libtorrent
|
|||
virtual void write_keepalive() = 0;
|
||||
virtual void write_piece(peer_request const& r, char const* buffer) = 0;
|
||||
|
||||
virtual void write_reject_request(peer_request const& r) = 0;
|
||||
virtual void write_allow_fast(int piece) = 0;
|
||||
|
||||
virtual void on_connected() = 0;
|
||||
virtual void on_tick() {}
|
||||
|
||||
|
@ -502,11 +482,6 @@ namespace libtorrent
|
|||
// the time we sent a request to
|
||||
// this peer the last time
|
||||
ptime m_last_request;
|
||||
// the time we received the last
|
||||
// piece request from the peer
|
||||
ptime m_last_incoming_request;
|
||||
// the time when we unchoked this peer
|
||||
ptime m_last_unchoke;
|
||||
|
||||
int m_packet_size;
|
||||
int m_recv_pos;
|
||||
|
@ -554,7 +529,7 @@ namespace libtorrent
|
|||
// set to the torrent it belongs to.
|
||||
boost::weak_ptr<torrent> m_torrent;
|
||||
// is true if it was we that connected to the peer
|
||||
// and false if we got an incoming connection
|
||||
// and false if we got an incomming connection
|
||||
// could be considered: true = local, false = remote
|
||||
bool m_active;
|
||||
|
||||
|
@ -588,10 +563,6 @@ namespace libtorrent
|
|||
|
||||
// the pieces the other end have
|
||||
std::vector<bool> m_have_piece;
|
||||
// this is set to true when a have_all
|
||||
// message is received. This information
|
||||
// is used to fill the bitmask in init()
|
||||
bool m_have_all;
|
||||
|
||||
// the number of pieces this peer
|
||||
// has. Must be the same as
|
||||
|
@ -604,7 +575,7 @@ namespace libtorrent
|
|||
std::deque<peer_request> m_requests;
|
||||
|
||||
// the blocks we have reserved in the piece
|
||||
// picker and will request from this peer.
|
||||
// picker and will send to this peer.
|
||||
std::deque<piece_block> m_request_queue;
|
||||
|
||||
// the queue of blocks we have requested
|
||||
|
@ -672,13 +643,12 @@ namespace libtorrent
|
|||
bool m_writing;
|
||||
bool m_reading;
|
||||
|
||||
// if set to non-zero, this peer will always prefer
|
||||
// to request entire n pieces, rather than blocks.
|
||||
// where n is the value of this variable.
|
||||
// if it is 0, the download rate limit setting
|
||||
// if set to true, this peer will always prefer
|
||||
// to request entire pieces, rather than blocks.
|
||||
// if it is false, the download rate limit setting
|
||||
// will be used to determine if whole pieces
|
||||
// are preferred.
|
||||
int m_prefer_whole_pieces;
|
||||
bool m_prefer_whole_pieces;
|
||||
|
||||
// if this is true, the blocks picked by the piece
|
||||
// picker will be merged before passed to the
|
||||
|
@ -725,18 +695,6 @@ namespace libtorrent
|
|||
// was last updated
|
||||
ptime m_remote_dl_update;
|
||||
|
||||
// the pieces we will send to the peer
|
||||
// if requested (regardless of choke state)
|
||||
std::set<int> m_accept_fast;
|
||||
|
||||
// the pieces the peer will send us if
|
||||
// requested (regardless of choke state)
|
||||
std::vector<int> m_allowed_fast;
|
||||
|
||||
// pieces that has been suggested to be
|
||||
// downloaded from this peer
|
||||
std::vector<int> m_suggested_pieces;
|
||||
|
||||
// the number of bytes send to the disk-io
|
||||
// thread that hasn't yet been completely written.
|
||||
int m_outstanding_writing_bytes;
|
||||
|
|
|
@ -35,12 +35,12 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
|
|
@ -56,11 +56,10 @@ namespace libtorrent
|
|||
connecting = 0x80,
|
||||
queued = 0x100,
|
||||
on_parole = 0x200,
|
||||
seed = 0x400,
|
||||
optimistic_unchoke = 0x800
|
||||
seed = 0x400
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
, rc4_encrypted = 0x100000,
|
||||
plaintext_encrypted = 0x200000
|
||||
, rc4_encrypted = 0x800,
|
||||
plaintext_encrypted = 0x1000
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -72,8 +71,7 @@ namespace libtorrent
|
|||
dht = 0x2,
|
||||
pex = 0x4,
|
||||
lsd = 0x8,
|
||||
resume_data = 0x10,
|
||||
incoming = 0x20
|
||||
resume_data = 0x10
|
||||
};
|
||||
|
||||
int source;
|
||||
|
@ -118,11 +116,6 @@ namespace libtorrent
|
|||
// for yet
|
||||
int download_queue_length;
|
||||
|
||||
// the number of requests that is
|
||||
// tried to be maintained (this is
|
||||
// typically a function of download speed)
|
||||
int target_dl_queue_length;
|
||||
|
||||
// this is the number of requests
|
||||
// the peer has sent to us
|
||||
// that we haven't sent yet
|
||||
|
|
|
@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <bitset>
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -51,7 +52,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/session_settings.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -191,33 +191,11 @@ namespace libtorrent
|
|||
// THIS IS DONE BY THE peer_connection::send_request() MEMBER FUNCTION!
|
||||
// The last argument is the policy::peer pointer for the peer that
|
||||
// we'll download from.
|
||||
void pick_pieces(std::vector<bool> const& pieces
|
||||
void pick_pieces(const std::vector<bool>& pieces
|
||||
, std::vector<piece_block>& interesting_blocks
|
||||
, int num_pieces, int prefer_whole_pieces
|
||||
, int num_pieces, bool prefer_whole_pieces
|
||||
, void* peer, piece_state_t speed
|
||||
, bool rarest_first, bool on_parole
|
||||
, std::vector<int> const& suggested_pieces) const;
|
||||
|
||||
// picks blocks from each of the pieces in the piece_list
|
||||
// vector that is also in the piece bitmask. The blocks
|
||||
// are added to interesting_blocks, and busy blocks are
|
||||
// added to backup_blocks. num blocks is the number of
|
||||
// blocks to be picked. Blocks are not picked from pieces
|
||||
// that are being downloaded
|
||||
int add_blocks(std::vector<int> const& piece_list
|
||||
, const std::vector<bool>& pieces
|
||||
, std::vector<piece_block>& interesting_blocks
|
||||
, int num_blocks, int prefer_whole_pieces
|
||||
, void* peer, std::vector<int> const& ignore) const;
|
||||
|
||||
// picks blocks only from downloading pieces
|
||||
int add_blocks_downloading(
|
||||
std::vector<bool> const& pieces
|
||||
, std::vector<piece_block>& interesting_blocks
|
||||
, std::vector<piece_block>& backup_blocks
|
||||
, int num_blocks, int prefer_whole_pieces
|
||||
, void* peer, piece_state_t speed
|
||||
, bool on_parole) const;
|
||||
, bool rarest_first) const;
|
||||
|
||||
// clears the peer pointer in all downloading pieces with this
|
||||
// peer pointer
|
||||
|
@ -233,7 +211,7 @@ namespace libtorrent
|
|||
bool is_finished(piece_block block) const;
|
||||
|
||||
// marks this piece-block as queued for downloading
|
||||
bool mark_as_downloading(piece_block block, void* peer
|
||||
void mark_as_downloading(piece_block block, void* peer
|
||||
, piece_state_t s);
|
||||
void mark_as_writing(piece_block block, void* peer);
|
||||
void mark_as_finished(piece_block block, void* peer);
|
||||
|
@ -275,8 +253,6 @@ namespace libtorrent
|
|||
#ifndef NDEBUG
|
||||
// used in debug mode
|
||||
void check_invariant(const torrent* t = 0) const;
|
||||
void verify_pick(std::vector<piece_block> const& picked
|
||||
, std::vector<bool> const& bitfield) const;
|
||||
#endif
|
||||
|
||||
// functor that compares indices on downloading_pieces
|
||||
|
@ -295,10 +271,6 @@ namespace libtorrent
|
|||
|
||||
private:
|
||||
|
||||
bool can_pick(int piece, std::vector<bool> const& bitmask) const;
|
||||
std::pair<int, int> expand_piece(int piece, int whole_pieces
|
||||
, std::vector<bool> const& have) const;
|
||||
|
||||
struct piece_pos
|
||||
{
|
||||
piece_pos() {}
|
||||
|
@ -348,9 +320,9 @@ namespace libtorrent
|
|||
|
||||
int priority(int limit) const
|
||||
{
|
||||
if (downloading || filtered() || have()) return 0;
|
||||
if (filtered() || have()) return 0;
|
||||
// pieces we are currently downloading have high priority
|
||||
int prio = peer_count * 2;
|
||||
int prio = downloading ? (std::min)(1, int(peer_count)) : peer_count * 2;
|
||||
// if the peer_count is 0 or 1, the priority cannot be higher
|
||||
if (prio <= 1) return prio;
|
||||
if (prio >= limit * 2) prio = limit * 2;
|
||||
|
@ -386,6 +358,14 @@ namespace libtorrent
|
|||
void move(int vec_index, int elem_index);
|
||||
void sort_piece(std::vector<downloading_piece>::iterator dp);
|
||||
|
||||
int add_interesting_blocks(const std::vector<int>& piece_list
|
||||
, const std::vector<bool>& pieces
|
||||
, std::vector<piece_block>& interesting_blocks
|
||||
, std::vector<piece_block>& backup_blocks
|
||||
, int num_blocks, bool prefer_whole_pieces
|
||||
, void* peer, piece_state_t speed
|
||||
, bool ignore_downloading_pieces) const;
|
||||
|
||||
downloading_piece& add_download_piece();
|
||||
void erase_download_piece(std::vector<downloading_piece>::iterator i);
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ namespace libtorrent
|
|||
void new_connection(peer_connection& c);
|
||||
|
||||
// the given connection was just closed
|
||||
void connection_closed(const peer_connection& c) throw();
|
||||
void connection_closed(const peer_connection& c);
|
||||
|
||||
// the peer has got at least one interesting piece
|
||||
void peer_is_interesting(peer_connection& c);
|
||||
|
@ -155,13 +155,6 @@ namespace libtorrent
|
|||
// this is true if the peer is a seed
|
||||
bool seed;
|
||||
|
||||
// true if this peer currently is unchoked
|
||||
// because of an optimistic unchoke.
|
||||
// when the optimistic unchoke is moved to
|
||||
// another peer, this peer will be choked
|
||||
// if this is true
|
||||
bool optimistically_unchoked;
|
||||
|
||||
// the time when this peer was optimistically unchoked
|
||||
// the last time.
|
||||
libtorrent::ptime last_optimistically_unchoked;
|
||||
|
@ -210,18 +203,25 @@ namespace libtorrent
|
|||
peer_connection* connection;
|
||||
};
|
||||
|
||||
int num_peers() const { return m_peers.size(); }
|
||||
int num_peers() const
|
||||
{
|
||||
return m_peers.size();
|
||||
}
|
||||
|
||||
int num_uploads() const
|
||||
{
|
||||
return m_num_unchoked;
|
||||
}
|
||||
|
||||
typedef std::list<peer>::iterator iterator;
|
||||
typedef std::list<peer>::const_iterator const_iterator;
|
||||
iterator begin_peer() { return m_peers.begin(); }
|
||||
iterator end_peer() { return m_peers.end(); }
|
||||
|
||||
bool connect_one_peer();
|
||||
bool disconnect_one_peer();
|
||||
|
||||
private:
|
||||
/*
|
||||
|
||||
bool unchoke_one_peer();
|
||||
void choke_one_peer();
|
||||
iterator find_choke_candidate();
|
||||
|
@ -233,7 +233,8 @@ namespace libtorrent
|
|||
void seed_choke_one_peer();
|
||||
iterator find_seed_choke_candidate();
|
||||
iterator find_seed_unchoke_candidate();
|
||||
*/
|
||||
|
||||
bool disconnect_one_peer();
|
||||
iterator find_disconnect_candidate();
|
||||
iterator find_connect_candidate();
|
||||
|
||||
|
@ -241,6 +242,10 @@ namespace libtorrent
|
|||
|
||||
torrent* m_torrent;
|
||||
|
||||
// the number of unchoked peers
|
||||
// at any given time
|
||||
int m_num_unchoked;
|
||||
|
||||
// free download we have got that hasn't
|
||||
// been distributed yet.
|
||||
size_type m_available_free_upload;
|
||||
|
@ -248,7 +253,7 @@ namespace libtorrent
|
|||
// if there is a connection limit,
|
||||
// we disconnect one peer every minute in hope of
|
||||
// establishing a connection with a better peer
|
||||
// ptime m_last_optimistic_disconnect;
|
||||
ptime m_last_optimistic_disconnect;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -53,7 +53,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/torrent_handle.hpp"
|
||||
#include "libtorrent/entry.hpp"
|
||||
#include "libtorrent/alert.hpp"
|
||||
|
@ -61,6 +60,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/version.hpp"
|
||||
#include "libtorrent/fingerprint.hpp"
|
||||
|
||||
#include "libtorrent/resource_request.hpp"
|
||||
#include "libtorrent/storage.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -141,17 +141,22 @@ namespace libtorrent
|
|||
, fs::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true
|
||||
, bool paused = false
|
||||
, storage_constructor_type sc = default_storage_constructor) TORRENT_DEPRECATED;
|
||||
, int block_size = 16 * 1024
|
||||
, storage_constructor_type sc = default_storage_constructor);
|
||||
|
||||
// ==== deprecated, this is for backwards compatibility only
|
||||
// instead, use one of the other add_torrent overloads
|
||||
torrent_handle add_torrent(
|
||||
boost::intrusive_ptr<torrent_info> ti
|
||||
entry const& e
|
||||
, fs::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true
|
||||
, bool paused = false
|
||||
, storage_constructor_type sc = default_storage_constructor
|
||||
, void* userdata = 0);
|
||||
, int block_size = 16 * 1024
|
||||
, storage_constructor_type sc = default_storage_constructor) TORRENT_DEPRECATED
|
||||
{
|
||||
return add_torrent(torrent_info(e), save_path, resume_data
|
||||
, compact_mode, block_size, sc);
|
||||
}
|
||||
|
||||
torrent_handle add_torrent(
|
||||
char const* tracker_url
|
||||
|
@ -160,9 +165,8 @@ namespace libtorrent
|
|||
, fs::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true
|
||||
, bool paused = false
|
||||
, storage_constructor_type sc = default_storage_constructor
|
||||
, void* userdata = 0);
|
||||
, int block_size = 16 * 1024
|
||||
, storage_constructor_type sc = default_storage_constructor);
|
||||
|
||||
session_proxy abort() { return session_proxy(m_impl); }
|
||||
|
||||
|
@ -183,7 +187,7 @@ namespace libtorrent
|
|||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*, void*)> ext);
|
||||
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*)> ext);
|
||||
#endif
|
||||
|
||||
void set_ip_filter(ip_filter const& f);
|
||||
|
@ -239,7 +243,6 @@ namespace libtorrent
|
|||
|
||||
int upload_rate_limit() const;
|
||||
int download_rate_limit() const;
|
||||
int max_half_open_connections() const;
|
||||
|
||||
void set_upload_rate_limit(int bytes_per_second);
|
||||
void set_download_rate_limit(int bytes_per_second);
|
||||
|
@ -262,6 +265,12 @@ namespace libtorrent
|
|||
void stop_natpmp();
|
||||
void stop_upnp();
|
||||
|
||||
// Resource management used for global limits.
|
||||
resource_request m_ul_bandwidth_quota;
|
||||
resource_request m_dl_bandwidth_quota;
|
||||
resource_request m_uploads_quota;
|
||||
resource_request m_connections_quota;
|
||||
|
||||
private:
|
||||
|
||||
// just a way to initialize boost.filesystem
|
||||
|
|
|
@ -1,594 +0,0 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2006, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef TORRENT_SESSION_IMPL_HPP_INCLUDED
|
||||
#define TORRENT_SESSION_IMPL_HPP_INCLUDED
|
||||
|
||||
#include <ctime>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <list>
|
||||
#include <deque>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push, 1)
|
||||
#endif
|
||||
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include "libtorrent/torrent_handle.hpp"
|
||||
#include "libtorrent/entry.hpp"
|
||||
#include "libtorrent/torrent_info.hpp"
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/peer_connection.hpp"
|
||||
#include "libtorrent/peer_id.hpp"
|
||||
#include "libtorrent/policy.hpp"
|
||||
#include "libtorrent/tracker_manager.hpp"
|
||||
#include "libtorrent/peer_info.hpp"
|
||||
#include "libtorrent/alert.hpp"
|
||||
#include "libtorrent/fingerprint.hpp"
|
||||
#include "libtorrent/debug.hpp"
|
||||
#include "libtorrent/peer_request.hpp"
|
||||
#include "libtorrent/piece_block_progress.hpp"
|
||||
#include "libtorrent/ip_filter.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/session_settings.hpp"
|
||||
#include "libtorrent/kademlia/dht_tracker.hpp"
|
||||
#include "libtorrent/session_status.hpp"
|
||||
#include "libtorrent/session.hpp"
|
||||
#include "libtorrent/stat.hpp"
|
||||
#include "libtorrent/file_pool.hpp"
|
||||
#include "libtorrent/bandwidth_manager.hpp"
|
||||
#include "libtorrent/natpmp.hpp"
|
||||
#include "libtorrent/upnp.hpp"
|
||||
#include "libtorrent/lsd.hpp"
|
||||
#include "libtorrent/socket_type.hpp"
|
||||
#include "libtorrent/connection_queue.hpp"
|
||||
#include "libtorrent/disk_io_thread.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
||||
namespace fs = boost::filesystem;
|
||||
|
||||
namespace aux
|
||||
{
|
||||
struct session_impl;
|
||||
|
||||
// this data is shared between the main thread and the
|
||||
// thread that initialize pieces
|
||||
struct piece_checker_data
|
||||
{
|
||||
piece_checker_data()
|
||||
: processing(false), progress(0.f), abort(false) {}
|
||||
|
||||
boost::shared_ptr<torrent> torrent_ptr;
|
||||
fs::path save_path;
|
||||
|
||||
sha1_hash info_hash;
|
||||
|
||||
void parse_resume_data(
|
||||
const entry& rd
|
||||
, const torrent_info& info
|
||||
, std::string& error);
|
||||
|
||||
std::vector<int> piece_map;
|
||||
std::vector<piece_picker::downloading_piece> unfinished_pieces;
|
||||
std::vector<piece_picker::block_info> block_info;
|
||||
std::vector<tcp::endpoint> peers;
|
||||
entry resume_data;
|
||||
|
||||
// this is true if this torrent is being processed (checked)
|
||||
// if it is not being processed, then it can be removed from
|
||||
// the queue without problems, otherwise the abort flag has
|
||||
// to be set.
|
||||
bool processing;
|
||||
|
||||
// is filled in by storage::initialize_pieces()
|
||||
// and represents the progress. It should be a
|
||||
// value in the range [0, 1]
|
||||
float progress;
|
||||
|
||||
// abort defaults to false and is typically
|
||||
// filled in by torrent_handle when the user
|
||||
// aborts the torrent
|
||||
bool abort;
|
||||
};
|
||||
|
||||
struct checker_impl: boost::noncopyable
|
||||
{
|
||||
checker_impl(session_impl& s): m_ses(s), m_abort(false) {}
|
||||
void operator()();
|
||||
piece_checker_data* find_torrent(const sha1_hash& info_hash);
|
||||
void remove_torrent(sha1_hash const& info_hash);
|
||||
|
||||
#ifndef NDEBUG
|
||||
void check_invariant() const;
|
||||
#endif
|
||||
|
||||
// when the files has been checked
|
||||
// the torrent is added to the session
|
||||
session_impl& m_ses;
|
||||
|
||||
mutable boost::mutex m_mutex;
|
||||
boost::condition m_cond;
|
||||
|
||||
// a list of all torrents that are currently in queue
|
||||
// or checking their files
|
||||
std::deque<boost::shared_ptr<piece_checker_data> > m_torrents;
|
||||
std::deque<boost::shared_ptr<piece_checker_data> > m_processing;
|
||||
|
||||
bool m_abort;
|
||||
};
|
||||
|
||||
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
|
||||
struct tracker_logger;
|
||||
#endif
|
||||
|
||||
// this is the link between the main thread and the
|
||||
// thread started to run the main downloader loop
|
||||
struct session_impl: boost::noncopyable
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
friend class ::libtorrent::peer_connection;
|
||||
#endif
|
||||
friend struct checker_impl;
|
||||
friend class invariant_access;
|
||||
typedef std::map<boost::shared_ptr<socket_type>
|
||||
, boost::intrusive_ptr<peer_connection> >
|
||||
connection_map;
|
||||
typedef std::map<sha1_hash, boost::shared_ptr<torrent> > torrent_map;
|
||||
|
||||
session_impl(
|
||||
std::pair<int, int> listen_port_range
|
||||
, fingerprint const& cl_fprint
|
||||
, char const* listen_interface = "0.0.0.0");
|
||||
~session_impl();
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
void add_extension(boost::function<boost::shared_ptr<torrent_plugin>(torrent*)> ext);
|
||||
#endif
|
||||
void operator()();
|
||||
|
||||
void open_listen_port();
|
||||
|
||||
void async_accept();
|
||||
void on_incoming_connection(boost::shared_ptr<socket_type> const& s
|
||||
, boost::weak_ptr<socket_acceptor> const& as, asio::error_code const& e);
|
||||
|
||||
// must be locked to access the data
|
||||
// in this struct
|
||||
typedef boost::recursive_mutex mutex_t;
|
||||
mutable mutex_t m_mutex;
|
||||
|
||||
boost::weak_ptr<torrent> find_torrent(const sha1_hash& info_hash);
|
||||
peer_id const& get_peer_id() const { return m_peer_id; }
|
||||
|
||||
void close_connection(boost::intrusive_ptr<peer_connection> const& p);
|
||||
void connection_failed(boost::shared_ptr<socket_type> const& s
|
||||
, tcp::endpoint const& a, char const* message);
|
||||
|
||||
void set_settings(session_settings const& s);
|
||||
session_settings const& settings() const { return m_settings; }
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
void add_dht_node(std::pair<std::string, int> const& node);
|
||||
void add_dht_node(udp::endpoint n);
|
||||
void add_dht_router(std::pair<std::string, int> const& node);
|
||||
void set_dht_settings(dht_settings const& s);
|
||||
dht_settings const& get_dht_settings() const { return m_dht_settings; }
|
||||
void start_dht(entry const& startup_state);
|
||||
void stop_dht();
|
||||
entry dht_state() const;
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
void set_pe_settings(pe_settings const& settings);
|
||||
pe_settings const& get_pe_settings() const { return m_pe_settings; }
|
||||
#endif
|
||||
|
||||
// called when a port mapping is successful, or a router returns
|
||||
// a failure to map a port
|
||||
void on_port_mapping(int tcp_port, int udp_port, std::string const& errmsg);
|
||||
|
||||
bool is_aborted() const { return m_abort; }
|
||||
|
||||
void set_ip_filter(ip_filter const& f);
|
||||
void set_port_filter(port_filter const& f);
|
||||
|
||||
bool listen_on(
|
||||
std::pair<int, int> const& port_range
|
||||
, const char* net_interface = 0);
|
||||
bool is_listening() const;
|
||||
|
||||
torrent_handle add_torrent(
|
||||
torrent_info const& ti
|
||||
, fs::path const& save_path
|
||||
, entry const& resume_data
|
||||
, bool compact_mode
|
||||
, int block_size
|
||||
, storage_constructor_type sc);
|
||||
|
||||
torrent_handle add_torrent(
|
||||
char const* tracker_url
|
||||
, sha1_hash const& info_hash
|
||||
, char const* name
|
||||
, fs::path const& save_path
|
||||
, entry const& resume_data
|
||||
, bool compact_mode
|
||||
, int block_size
|
||||
, storage_constructor_type sc);
|
||||
|
||||
void remove_torrent(torrent_handle const& h);
|
||||
|
||||
std::vector<torrent_handle> get_torrents();
|
||||
|
||||
void set_severity_level(alert::severity_t s);
|
||||
std::auto_ptr<alert> pop_alert();
|
||||
|
||||
int upload_rate_limit() const;
|
||||
int download_rate_limit() const;
|
||||
|
||||
void set_download_rate_limit(int bytes_per_second);
|
||||
void set_upload_rate_limit(int bytes_per_second);
|
||||
void set_max_half_open_connections(int limit);
|
||||
void set_max_connections(int limit);
|
||||
void set_max_uploads(int limit);
|
||||
|
||||
int max_connections() const { return m_max_connections; }
|
||||
int max_uploads() const { return m_max_uploads; }
|
||||
|
||||
int num_uploads() const { return m_num_unchoked; }
|
||||
int num_connections() const
|
||||
{ return m_connections.size(); }
|
||||
|
||||
void unchoke_peer(peer_connection& c)
|
||||
{
|
||||
c.send_unchoke();
|
||||
++m_num_unchoked;
|
||||
}
|
||||
|
||||
session_status status() const;
|
||||
void set_peer_id(peer_id const& id);
|
||||
void set_key(int key);
|
||||
unsigned short listen_port() const;
|
||||
|
||||
void abort();
|
||||
|
||||
torrent_handle find_torrent_handle(sha1_hash const& info_hash);
|
||||
|
||||
void announce_lsd(sha1_hash const& ih);
|
||||
|
||||
void set_peer_proxy(proxy_settings const& s)
|
||||
{ m_peer_proxy = s; }
|
||||
void set_web_seed_proxy(proxy_settings const& s)
|
||||
{ m_web_seed_proxy = s; }
|
||||
void set_tracker_proxy(proxy_settings const& s)
|
||||
{ m_tracker_proxy = s; }
|
||||
|
||||
proxy_settings const& peer_proxy() const
|
||||
{ return m_peer_proxy; }
|
||||
proxy_settings const& web_seed_proxy() const
|
||||
{ return m_web_seed_proxy; }
|
||||
proxy_settings const& tracker_proxy() const
|
||||
{ return m_tracker_proxy; }
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
void set_dht_proxy(proxy_settings const& s)
|
||||
{ m_dht_proxy = s; }
|
||||
proxy_settings const& dht_proxy() const
|
||||
{ return m_dht_proxy; }
|
||||
#endif
|
||||
|
||||
void start_lsd();
|
||||
void start_natpmp();
|
||||
void start_upnp();
|
||||
|
||||
void stop_lsd();
|
||||
void stop_natpmp();
|
||||
void stop_upnp();
|
||||
|
||||
// handles delayed alerts
|
||||
alert_manager m_alerts;
|
||||
|
||||
// private:
|
||||
|
||||
void on_lsd_peer(tcp::endpoint peer, sha1_hash const& ih);
|
||||
|
||||
// this is where all active sockets are stored.
|
||||
// the selector can sleep while there's no activity on
|
||||
// them
|
||||
io_service m_io_service;
|
||||
asio::strand m_strand;
|
||||
|
||||
// the file pool that all storages in this session's
|
||||
// torrents uses. It sets a limit on the number of
|
||||
// open files by this session.
|
||||
// file pool must be destructed after the torrents
|
||||
// since they will still have references to it
|
||||
// when they are destructed.
|
||||
file_pool m_files;
|
||||
|
||||
// handles disk io requests asynchronously
|
||||
disk_io_thread m_disk_thread;
|
||||
|
||||
// this is a list of half-open tcp connections
|
||||
// (only outgoing connections)
|
||||
// this has to be one of the last
|
||||
// members to be destructed
|
||||
connection_queue m_half_open;
|
||||
|
||||
// the bandwidth manager is responsible for
|
||||
// handing out bandwidth to connections that
|
||||
// asks for it, it can also throttle the
|
||||
// rate.
|
||||
bandwidth_manager<peer_connection, torrent> m_download_channel;
|
||||
bandwidth_manager<peer_connection, torrent> m_upload_channel;
|
||||
|
||||
bandwidth_manager<peer_connection, torrent>* m_bandwidth_manager[2];
|
||||
|
||||
tracker_manager m_tracker_manager;
|
||||
torrent_map m_torrents;
|
||||
|
||||
// this maps sockets to their peer_connection
|
||||
// object. It is the complete list of all connected
|
||||
// peers.
|
||||
connection_map m_connections;
|
||||
|
||||
// filters incoming connections
|
||||
ip_filter m_ip_filter;
|
||||
|
||||
// filters outgoing connections
|
||||
port_filter m_port_filter;
|
||||
|
||||
// the peer id that is generated at the start of the session
|
||||
peer_id m_peer_id;
|
||||
|
||||
// the key is an id that is used to identify the
|
||||
// client with the tracker only. It is randomized
|
||||
// at startup
|
||||
int m_key;
|
||||
|
||||
// the range of ports we try to listen on
|
||||
std::pair<int, int> m_listen_port_range;
|
||||
|
||||
// the ip-address of the interface
|
||||
// we are supposed to listen on.
|
||||
// if the ip is set to zero, it means
|
||||
// that we should let the os decide which
|
||||
// interface to listen on
|
||||
tcp::endpoint m_listen_interface;
|
||||
|
||||
// this is typically set to the same as the local
|
||||
// listen port. In case a NAT port forward was
|
||||
// successfully opened, this will be set to the
|
||||
// port that is open on the external (NAT) interface
|
||||
// on the NAT box itself. This is the port that has
|
||||
// to be published to peers, since this is the port
|
||||
// the client is reachable through.
|
||||
int m_external_listen_port;
|
||||
|
||||
boost::shared_ptr<socket_acceptor> m_listen_socket;
|
||||
|
||||
// the settings for the client
|
||||
session_settings m_settings;
|
||||
// the proxy settings for different
|
||||
// kinds of connections
|
||||
proxy_settings m_peer_proxy;
|
||||
proxy_settings m_web_seed_proxy;
|
||||
proxy_settings m_tracker_proxy;
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
proxy_settings m_dht_proxy;
|
||||
#endif
|
||||
|
||||
// set to true when the session object
|
||||
// is being destructed and the thread
|
||||
// should exit
|
||||
volatile bool m_abort;
|
||||
|
||||
int m_max_uploads;
|
||||
int m_max_connections;
|
||||
|
||||
// the number of unchoked peers
|
||||
int m_num_unchoked;
|
||||
|
||||
// this is initialized to the unchoke_interval
|
||||
// session_setting and decreased every second.
|
||||
// when it reaches zero, it is reset to the
|
||||
// unchoke_interval and the unchoke set is
|
||||
// recomputed.
|
||||
int m_unchoke_time_scaler;
|
||||
|
||||
// works like unchoke_time_scaler but it
|
||||
// is only decresed when the unchoke set
|
||||
// is recomputed, and when it reaches zero,
|
||||
// the optimistic unchoke is moved to another peer.
|
||||
int m_optimistic_unchoke_time_scaler;
|
||||
|
||||
// works like unchoke_time_scaler. Each time
|
||||
// it reaches 0, and all the connections are
|
||||
// used, the worst connection will be disconnected
|
||||
// from the torrent with the most peers
|
||||
int m_disconnect_time_scaler;
|
||||
|
||||
// statistics gathered from all torrents.
|
||||
stat m_stat;
|
||||
|
||||
// is false by default and set to true when
|
||||
// the first incoming connection is established
|
||||
// this is used to know if the client is behind
|
||||
// NAT or not.
|
||||
bool m_incoming_connection;
|
||||
|
||||
void second_tick(asio::error_code const& e);
|
||||
ptime m_last_tick;
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
boost::intrusive_ptr<dht::dht_tracker> m_dht;
|
||||
dht_settings m_dht_settings;
|
||||
// if this is set to true, the dht listen port
|
||||
// will be set to the same as the tcp listen port
|
||||
// and will be synchronlized with it as it changes
|
||||
// it defaults to true
|
||||
bool m_dht_same_port;
|
||||
|
||||
// see m_external_listen_port. This is the same
|
||||
// but for the udp port used by the DHT.
|
||||
int m_external_udp_port;
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
pe_settings m_pe_settings;
|
||||
#endif
|
||||
|
||||
boost::shared_ptr<natpmp> m_natpmp;
|
||||
boost::shared_ptr<upnp> m_upnp;
|
||||
boost::shared_ptr<lsd> m_lsd;
|
||||
|
||||
// the timer used to fire the second_tick
|
||||
deadline_timer m_timer;
|
||||
|
||||
// the index of the torrent that will be offered to
|
||||
// connect to a peer next time second_tick is called.
|
||||
// This implements a round robin.
|
||||
int m_next_connect_torrent;
|
||||
#ifndef NDEBUG
|
||||
void check_invariant(const char *place = 0);
|
||||
#endif
|
||||
|
||||
#ifdef TORRENT_STATS
|
||||
// logger used to write bandwidth usage statistics
|
||||
std::ofstream m_stats_logger;
|
||||
int m_second_counter;
|
||||
#endif
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
boost::shared_ptr<logger> create_log(std::string const& name
|
||||
, int instance, bool append = true);
|
||||
|
||||
// this list of tracker loggers serves as tracker_callbacks when
|
||||
// shutting down. This list is just here to keep them alive during
|
||||
// whe shutting down process
|
||||
std::list<boost::shared_ptr<tracker_logger> > m_tracker_loggers;
|
||||
|
||||
public:
|
||||
boost::shared_ptr<logger> m_logger;
|
||||
private:
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
typedef std::list<boost::function<boost::shared_ptr<
|
||||
torrent_plugin>(torrent*)> > extension_list_t;
|
||||
|
||||
extension_list_t m_extensions;
|
||||
#endif
|
||||
|
||||
// data shared between the main thread
|
||||
// and the checker thread
|
||||
checker_impl m_checker_impl;
|
||||
|
||||
// the main working thread
|
||||
boost::scoped_ptr<boost::thread> m_thread;
|
||||
|
||||
// the thread that calls initialize_pieces()
|
||||
// on all torrents before they start downloading
|
||||
boost::scoped_ptr<boost::thread> m_checker_thread;
|
||||
};
|
||||
|
||||
#if defined(TORRENT_LOGGING) || defined(TORRENT_VERBOSE_LOGGING)
|
||||
struct tracker_logger : request_callback
|
||||
{
|
||||
tracker_logger(session_impl& ses): m_ses(ses) {}
|
||||
void tracker_warning(std::string const& str)
|
||||
{
|
||||
debug_log("*** tracker warning: " + str);
|
||||
}
|
||||
|
||||
void tracker_response(tracker_request const&
|
||||
, std::vector<peer_entry>& peers
|
||||
, int interval
|
||||
, int complete
|
||||
, int incomplete)
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "TRACKER RESPONSE:\n"
|
||||
"interval: " << interval << "\n"
|
||||
"peers:\n";
|
||||
for (std::vector<peer_entry>::const_iterator i = peers.begin();
|
||||
i != peers.end(); ++i)
|
||||
{
|
||||
s << " " << std::setfill(' ') << std::setw(16) << i->ip
|
||||
<< " " << std::setw(5) << std::dec << i->port << " ";
|
||||
if (!i->pid.is_all_zeros()) s << " " << i->pid;
|
||||
s << "\n";
|
||||
}
|
||||
debug_log(s.str());
|
||||
}
|
||||
|
||||
void tracker_request_timed_out(
|
||||
tracker_request const&)
|
||||
{
|
||||
debug_log("*** tracker timed out");
|
||||
}
|
||||
|
||||
void tracker_request_error(
|
||||
tracker_request const&
|
||||
, int response_code
|
||||
, const std::string& str)
|
||||
{
|
||||
debug_log(std::string("*** tracker error: ")
|
||||
+ boost::lexical_cast<std::string>(response_code) + ": "
|
||||
+ str);
|
||||
}
|
||||
|
||||
void debug_log(const std::string& line)
|
||||
{
|
||||
(*m_ses.m_logger) << line << "\n";
|
||||
}
|
||||
session_impl& m_ses;
|
||||
};
|
||||
#endif
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -105,11 +105,9 @@ namespace libtorrent
|
|||
, send_redundant_have(false)
|
||||
, lazy_bitfields(true)
|
||||
, inactivity_timeout(600)
|
||||
, unchoke_interval(15)
|
||||
, optimistic_unchoke_multiplier(4)
|
||||
, unchoke_interval(20)
|
||||
, num_want(200)
|
||||
, initial_picker_threshold(4)
|
||||
, allowed_fast_set_size(10)
|
||||
, max_outstanding_disk_bytes_per_connection(64 * 1024)
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
, use_dht_as_fallback(true)
|
||||
|
@ -243,10 +241,6 @@ namespace libtorrent
|
|||
// the number of seconds between chokes/unchokes
|
||||
int unchoke_interval;
|
||||
|
||||
// the number of unchoke intervals between
|
||||
// optimistic unchokes
|
||||
int optimistic_unchoke_multiplier;
|
||||
|
||||
// if this is set, this IP will be reported do the
|
||||
// tracker in the ip= parameter.
|
||||
address announce_ip;
|
||||
|
@ -258,10 +252,6 @@ namespace libtorrent
|
|||
// random pieces instead of rarest first.
|
||||
int initial_picker_threshold;
|
||||
|
||||
// the number of allowed pieces to send to peers
|
||||
// that supports the fast extensions
|
||||
int allowed_fast_set_size;
|
||||
|
||||
// the maximum number of bytes a connection may have
|
||||
// pending in the disk write queue before its download
|
||||
// rate is being throttled. This prevents fast downloads
|
||||
|
|
|
@ -40,7 +40,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/size_type.hpp"
|
||||
#include "libtorrent/invariant_check.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
|
|
@ -43,7 +43,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <boost/limits.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -148,11 +147,10 @@ namespace libtorrent
|
|||
};
|
||||
|
||||
typedef storage_interface* (&storage_constructor_type)(
|
||||
boost::intrusive_ptr<torrent_info const>, fs::path const&
|
||||
torrent_info const&, fs::path const&
|
||||
, file_pool&);
|
||||
|
||||
TORRENT_EXPORT storage_interface* default_storage_constructor(
|
||||
boost::intrusive_ptr<torrent_info const> ti
|
||||
TORRENT_EXPORT storage_interface* default_storage_constructor(torrent_info const& ti
|
||||
, fs::path const& path, file_pool& fp);
|
||||
|
||||
// returns true if the filesystem the path relies on supports
|
||||
|
@ -171,7 +169,7 @@ namespace libtorrent
|
|||
|
||||
piece_manager(
|
||||
boost::shared_ptr<void> const& torrent
|
||||
, boost::intrusive_ptr<torrent_info const> ti
|
||||
, torrent_info const& ti
|
||||
, fs::path const& path
|
||||
, file_pool& fp
|
||||
, disk_io_thread& io
|
||||
|
@ -201,9 +199,7 @@ namespace libtorrent
|
|||
|
||||
void async_read(
|
||||
peer_request const& r
|
||||
, boost::function<void(int, disk_io_job const&)> const& handler
|
||||
, char* buffer = 0
|
||||
, int priority = 0);
|
||||
, boost::function<void(int, disk_io_job const&)> const& handler);
|
||||
|
||||
void async_write(
|
||||
peer_request const& r
|
||||
|
@ -231,7 +227,7 @@ namespace libtorrent
|
|||
{ return m_compact_mode; }
|
||||
|
||||
#ifndef NDEBUG
|
||||
std::string name() const { return m_info->name(); }
|
||||
std::string name() const { return m_info.name(); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
@ -287,7 +283,7 @@ namespace libtorrent
|
|||
// a bitmask representing the pieces we have
|
||||
std::vector<bool> m_have_piece;
|
||||
|
||||
boost::intrusive_ptr<torrent_info const> m_info;
|
||||
torrent_info const& m_info;
|
||||
|
||||
// slots that haven't had any file storage allocated
|
||||
std::vector<int> m_unallocated_slots;
|
||||
|
@ -317,6 +313,12 @@ namespace libtorrent
|
|||
|
||||
mutable boost::recursive_mutex m_mutex;
|
||||
|
||||
bool m_allocating;
|
||||
boost::mutex m_allocating_monitor;
|
||||
boost::condition m_allocating_condition;
|
||||
|
||||
// these states are used while checking/allocating the torrent
|
||||
|
||||
enum {
|
||||
// the default initial state
|
||||
state_none,
|
||||
|
@ -331,11 +333,6 @@ namespace libtorrent
|
|||
} m_state;
|
||||
int m_current_slot;
|
||||
|
||||
// this is saved in case we need to instantiate a new
|
||||
// storage (osed when remapping files)
|
||||
storage_constructor_type m_storage_constructor;
|
||||
|
||||
// temporary buffer used while checking
|
||||
std::vector<char> m_piece_data;
|
||||
|
||||
// this maps a piece hash to piece index. It will be
|
||||
|
@ -343,9 +340,6 @@ namespace libtorrent
|
|||
// isn't needed)
|
||||
std::multimap<sha1_hash, int> m_hash_to_piece;
|
||||
|
||||
// this map contains partial hashes for downloading
|
||||
// pieces. This is only accessed from within the
|
||||
// disk-io thread.
|
||||
std::map<int, partial_hash> m_piece_hasher;
|
||||
|
||||
disk_io_thread& m_io_thread;
|
||||
|
|
|
@ -55,7 +55,6 @@ namespace libtorrent
|
|||
|| _POSIX_MONOTONIC_CLOCK < 0)) || defined (TORRENT_USE_BOOST_DATE_TIME)
|
||||
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -86,7 +85,6 @@ namespace libtorrent
|
|||
|
||||
#include <asio/time_traits.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -172,7 +170,6 @@ namespace asio
|
|||
|
||||
#include <mach/mach_time.h>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
// high precision timer for darwin intel and ppc
|
||||
|
||||
|
@ -252,7 +249,6 @@ namespace libtorrent
|
|||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -339,7 +335,6 @@ namespace libtorrent
|
|||
#elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
|
||||
|
||||
#include <time.h>
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -390,4 +385,4 @@ namespace libtorrent
|
|||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -62,13 +62,13 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/tracker_manager.hpp"
|
||||
#include "libtorrent/stat.hpp"
|
||||
#include "libtorrent/alert.hpp"
|
||||
#include "libtorrent/resource_request.hpp"
|
||||
#include "libtorrent/piece_picker.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/escape_string.hpp"
|
||||
#include "libtorrent/bandwidth_manager.hpp"
|
||||
#include "libtorrent/storage.hpp"
|
||||
#include "libtorrent/hasher.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -98,13 +98,13 @@ namespace libtorrent
|
|||
torrent(
|
||||
aux::session_impl& ses
|
||||
, aux::checker_impl& checker
|
||||
, boost::intrusive_ptr<torrent_info> tf
|
||||
, torrent_info const& tf
|
||||
, fs::path const& save_path
|
||||
, tcp::endpoint const& net_interface
|
||||
, bool compact_mode
|
||||
, int block_size
|
||||
, storage_constructor_type sc
|
||||
, bool paused);
|
||||
, session_settings const& s
|
||||
, storage_constructor_type sc);
|
||||
|
||||
// used with metadata-less torrents
|
||||
// (the metadata is downloaded from the peers)
|
||||
|
@ -118,8 +118,8 @@ namespace libtorrent
|
|||
, tcp::endpoint const& net_interface
|
||||
, bool compact_mode
|
||||
, int block_size
|
||||
, storage_constructor_type sc
|
||||
, bool paused);
|
||||
, session_settings const& s
|
||||
, storage_constructor_type sc);
|
||||
|
||||
~torrent();
|
||||
|
||||
|
@ -154,6 +154,10 @@ namespace libtorrent
|
|||
bool verify_resume_data(entry& rd, std::string& error)
|
||||
{ assert(m_storage); return m_storage->verify_resume_data(rd, error); }
|
||||
|
||||
// is called every second by session. This will
|
||||
// caclulate the upload/download and number
|
||||
// of connections this torrent needs. And prepare
|
||||
// it for being used by allocate_resources.
|
||||
void second_tick(stat& accumulator, float tick_interval);
|
||||
|
||||
// debug purpose only
|
||||
|
@ -250,15 +254,6 @@ namespace libtorrent
|
|||
void remove_url_seed(std::string const& url)
|
||||
{ m_web_seeds.erase(url); }
|
||||
|
||||
std::set<std::string> url_seeds() const
|
||||
{ return m_web_seeds; }
|
||||
|
||||
bool free_upload_slots() const
|
||||
{ return m_num_uploads < m_max_uploads; }
|
||||
|
||||
void choke_peer(peer_connection& c);
|
||||
bool unchoke_peer(peer_connection& c);
|
||||
|
||||
// used by peer_connection to attach itself to a torrent
|
||||
// since incoming connections don't know what torrent
|
||||
// they're a part of until they have received an info_hash.
|
||||
|
@ -470,14 +465,14 @@ namespace libtorrent
|
|||
bool is_seed() const
|
||||
{
|
||||
return valid_metadata()
|
||||
&& m_num_pieces == m_torrent_file->num_pieces();
|
||||
&& m_num_pieces == m_torrent_file.num_pieces();
|
||||
}
|
||||
|
||||
// this is true if we have all the pieces that we want
|
||||
bool is_finished() const
|
||||
{
|
||||
if (is_seed()) return true;
|
||||
return valid_metadata() && m_torrent_file->num_pieces()
|
||||
return valid_metadata() && m_torrent_file.num_pieces()
|
||||
- m_num_pieces - m_picker->num_filtered() == 0;
|
||||
}
|
||||
|
||||
|
@ -499,7 +494,7 @@ namespace libtorrent
|
|||
}
|
||||
piece_manager& filesystem();
|
||||
torrent_info const& torrent_file() const
|
||||
{ return *m_torrent_file; }
|
||||
{ return m_torrent_file; }
|
||||
|
||||
std::vector<announce_entry> const& trackers() const
|
||||
{ return m_trackers; }
|
||||
|
@ -521,6 +516,11 @@ namespace libtorrent
|
|||
// --------------------------------------------
|
||||
// RESOURCE MANAGEMENT
|
||||
|
||||
void distribute_resources(float tick_interval);
|
||||
|
||||
resource_request m_uploads_quota;
|
||||
resource_request m_connections_quota;
|
||||
|
||||
void set_peer_upload_limit(tcp::endpoint ip, int limit);
|
||||
void set_peer_download_limit(tcp::endpoint ip, int limit);
|
||||
|
||||
|
@ -530,9 +530,7 @@ namespace libtorrent
|
|||
int download_limit() const;
|
||||
|
||||
void set_max_uploads(int limit);
|
||||
int max_uploads() const { return m_max_uploads; }
|
||||
void set_max_connections(int limit);
|
||||
int max_connections() const { return m_max_connections; }
|
||||
void move_storage(fs::path const& save_path);
|
||||
|
||||
// unless this returns true, new connections must wait
|
||||
|
@ -540,7 +538,7 @@ namespace libtorrent
|
|||
bool ready_for_connections() const
|
||||
{ return m_connections_initialized; }
|
||||
bool valid_metadata() const
|
||||
{ return m_torrent_file->is_valid(); }
|
||||
{ return m_torrent_file.is_valid(); }
|
||||
|
||||
// parses the info section from the given
|
||||
// bencoded tree and moves the torrent
|
||||
|
@ -564,7 +562,7 @@ namespace libtorrent
|
|||
|
||||
void update_peer_interest();
|
||||
|
||||
boost::intrusive_ptr<torrent_info> m_torrent_file;
|
||||
torrent_info m_torrent_file;
|
||||
|
||||
// is set to true when the torrent has
|
||||
// been aborted.
|
||||
|
@ -707,9 +705,9 @@ namespace libtorrent
|
|||
// determine the timeout until next try.
|
||||
int m_failed_trackers;
|
||||
|
||||
// this is a counter that is decreased every
|
||||
// second, and when it reaches 0, the policy::pulse()
|
||||
// is called and the time scaler is reset to 10.
|
||||
// this is a counter that is increased every
|
||||
// second, and when it reaches 10, the policy::pulse()
|
||||
// is called and the time scaler is reset to 0.
|
||||
int m_time_scaler;
|
||||
|
||||
// the bitmask that says which pieces we have
|
||||
|
@ -776,15 +774,6 @@ namespace libtorrent
|
|||
session_settings const& m_settings;
|
||||
|
||||
storage_constructor_type m_storage_constructor;
|
||||
|
||||
// the maximum number of uploads for this torrent
|
||||
int m_max_uploads;
|
||||
|
||||
// the number of unchoked peers in this torrent
|
||||
int m_num_uploads;
|
||||
|
||||
// the maximum number of connections for this torrent
|
||||
int m_max_connections;
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
typedef std::list<boost::shared_ptr<torrent_plugin> > extension_list_t;
|
||||
|
|
|
@ -34,7 +34,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define TORRENT_TORRENT_HANDLE_HPP_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push, 1)
|
||||
|
@ -274,9 +273,7 @@ namespace libtorrent
|
|||
std::vector<announce_entry> const& trackers() const;
|
||||
void replace_trackers(std::vector<announce_entry> const&) const;
|
||||
|
||||
void add_url_seed(std::string const& url) const;
|
||||
void remove_url_seed(std::string const& url) const;
|
||||
std::set<std::string> url_seeds() const;
|
||||
void add_url_seed(std::string const& url);
|
||||
|
||||
bool has_metadata() const;
|
||||
const torrent_info& get_torrent_info() const;
|
||||
|
@ -399,7 +396,6 @@ namespace libtorrent
|
|||
, m_info_hash(h)
|
||||
{
|
||||
assert(m_ses != 0);
|
||||
assert(m_chk != 0);
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
|
|
@ -57,8 +57,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/peer_request.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/time.hpp"
|
||||
#include "libtorrent/intrusive_ptr_base.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -73,7 +71,7 @@ namespace libtorrent
|
|||
size_type offset; // the offset of this file inside the torrent
|
||||
size_type size; // the size of this file
|
||||
// if the path was incorrectly encoded, this is
|
||||
// the original corrupt encoded string. It is
|
||||
// the origianal corrupt encoded string. It is
|
||||
// preserved in order to be able to reproduce
|
||||
// the correct info-hash
|
||||
boost::shared_ptr<const fs::path> orig_path;
|
||||
|
@ -98,7 +96,7 @@ namespace libtorrent
|
|||
virtual const char* what() const throw() { return "invalid torrent file"; }
|
||||
};
|
||||
|
||||
class TORRENT_EXPORT torrent_info : public intrusive_ptr_base<torrent_info>
|
||||
class TORRENT_EXPORT torrent_info
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -117,12 +115,8 @@ namespace libtorrent
|
|||
void add_file(fs::path file, size_type size);
|
||||
void add_url_seed(std::string const& url);
|
||||
|
||||
bool remap_files(std::vector<std::pair<std::string, libtorrent::size_type> > const& map);
|
||||
|
||||
std::vector<file_slice> map_block(int piece, size_type offset
|
||||
, int size, bool storage = false) const;
|
||||
peer_request map_file(int file, size_type offset, int size
|
||||
, bool storage = false) const;
|
||||
std::vector<file_slice> map_block(int piece, size_type offset, int size) const;
|
||||
peer_request map_file(int file, size_type offset, int size) const;
|
||||
|
||||
std::vector<std::string> const& url_seeds() const
|
||||
{
|
||||
|
@ -134,60 +128,15 @@ namespace libtorrent
|
|||
typedef std::vector<file_entry>::const_reverse_iterator reverse_file_iterator;
|
||||
|
||||
// list the files in the torrent file
|
||||
file_iterator begin_files(bool storage = false) const
|
||||
{
|
||||
if (!storage || m_remapped_files.empty())
|
||||
return m_files.begin();
|
||||
else
|
||||
return m_remapped_files.begin();
|
||||
}
|
||||
file_iterator begin_files() const { return m_files.begin(); }
|
||||
file_iterator end_files() const { return m_files.end(); }
|
||||
reverse_file_iterator rbegin_files() const { return m_files.rbegin(); }
|
||||
reverse_file_iterator rend_files() const { return m_files.rend(); }
|
||||
|
||||
file_iterator end_files(bool storage = false) const
|
||||
{
|
||||
if (!storage || m_remapped_files.empty())
|
||||
return m_files.end();
|
||||
else
|
||||
return m_remapped_files.end();
|
||||
}
|
||||
|
||||
reverse_file_iterator rbegin_files(bool storage = false) const
|
||||
{
|
||||
if (!storage || m_remapped_files.empty())
|
||||
return m_files.rbegin();
|
||||
else
|
||||
return m_remapped_files.rbegin();
|
||||
}
|
||||
|
||||
reverse_file_iterator rend_files(bool storage = false) const
|
||||
{
|
||||
if (!storage || m_remapped_files.empty())
|
||||
return m_files.rend();
|
||||
else
|
||||
return m_remapped_files.rend();
|
||||
}
|
||||
|
||||
int num_files(bool storage = false) const
|
||||
{
|
||||
assert(m_piece_length > 0);
|
||||
if (!storage || m_remapped_files.empty())
|
||||
return (int)m_files.size();
|
||||
else
|
||||
return (int)m_remapped_files.size();
|
||||
}
|
||||
|
||||
const file_entry& file_at(int index, bool storage = false) const
|
||||
{
|
||||
if (!storage || m_remapped_files.empty())
|
||||
{
|
||||
assert(index >= 0 && index < (int)m_files.size());
|
||||
return m_files[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(index >= 0 && index < (int)m_remapped_files.size());
|
||||
return m_remapped_files[index];
|
||||
}
|
||||
}
|
||||
int num_files() const
|
||||
{ assert(m_piece_length > 0); return (int)m_files.size(); }
|
||||
const file_entry& file_at(int index) const
|
||||
{ assert(index >= 0 && index < (int)m_files.size()); return m_files[index]; }
|
||||
|
||||
const std::vector<announce_entry>& trackers() const { return m_urls; }
|
||||
|
||||
|
@ -269,13 +218,6 @@ namespace libtorrent
|
|||
// the list of files that this torrent consists of
|
||||
std::vector<file_entry> m_files;
|
||||
|
||||
// this vector is typically empty. If it is not
|
||||
// empty, it means the user has re-mapped the
|
||||
// files in this torrent to diffefrent names
|
||||
// on disk. This is only used when reading and
|
||||
// writing the disk.
|
||||
std::vector<file_entry> m_remapped_files;
|
||||
|
||||
nodes_t m_nodes;
|
||||
|
||||
// the sum of all filesizes
|
||||
|
@ -322,10 +264,8 @@ namespace libtorrent
|
|||
entry m_extra_info;
|
||||
|
||||
#ifndef NDEBUG
|
||||
public:
|
||||
// this is set to true when seed_free() is called
|
||||
bool m_half_metadata;
|
||||
private:
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -194,10 +194,11 @@ namespace libtorrent
|
|||
, address bind_interface
|
||||
, boost::weak_ptr<request_callback> r);
|
||||
|
||||
boost::shared_ptr<request_callback> requester();
|
||||
request_callback& requester();
|
||||
virtual ~tracker_connection() {}
|
||||
|
||||
tracker_request const& tracker_req() const { return m_req; }
|
||||
bool has_requester() const { return !m_requester.expired(); }
|
||||
|
||||
void fail(int code, char const* msg);
|
||||
void fail_timeout();
|
||||
|
|
|
@ -34,7 +34,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define TORRENT_UPNP_HPP
|
||||
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/broadcast_socket.hpp"
|
||||
#include "libtorrent/http_connection.hpp"
|
||||
#include "libtorrent/connection_queue.hpp"
|
||||
|
||||
|
@ -57,6 +56,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace libtorrent
|
||||
{
|
||||
|
||||
bool is_local(address const& a);
|
||||
address_v4 guess_local_address(asio::io_service&);
|
||||
|
||||
// int: external tcp port
|
||||
// int: external udp port
|
||||
// std::string: error message
|
||||
|
@ -70,6 +72,8 @@ public:
|
|||
, portmap_callback_t const& cb);
|
||||
~upnp();
|
||||
|
||||
void rebind(address const& listen_interface);
|
||||
|
||||
// maps the ports, if a port is set to 0
|
||||
// it will not be mapped
|
||||
void set_mappings(int tcp, int udp);
|
||||
|
@ -86,7 +90,7 @@ private:
|
|||
|
||||
void update_mapping(int i, int port);
|
||||
void resend_request(asio::error_code const& e);
|
||||
void on_reply(udp::endpoint const& from, char* buffer
|
||||
void on_reply(asio::error_code const& e
|
||||
, std::size_t bytes_transferred);
|
||||
void discover_device();
|
||||
|
||||
|
@ -102,15 +106,12 @@ private:
|
|||
, int mapping);
|
||||
void on_expire(asio::error_code const& e);
|
||||
|
||||
void post(rootdevice& d, std::stringstream const& s
|
||||
, std::string const& soap_action);
|
||||
void map_port(rootdevice& d, int i);
|
||||
void unmap_port(rootdevice& d, int i);
|
||||
void disable();
|
||||
|
||||
void delete_port_mapping(rootdevice& d, int i);
|
||||
void create_port_mapping(http_connection& c, rootdevice& d, int i);
|
||||
void post(upnp::rootdevice const& d, std::string const& soap
|
||||
, std::string const& soap_action);
|
||||
|
||||
struct mapping_t
|
||||
{
|
||||
mapping_t()
|
||||
|
@ -197,13 +198,18 @@ private:
|
|||
// current retry count
|
||||
int m_retry_count;
|
||||
|
||||
asio::io_service& m_io_service;
|
||||
// used to receive responses in
|
||||
char m_receive_buffer[1024];
|
||||
|
||||
asio::strand m_strand;
|
||||
// the endpoint we received the message from
|
||||
udp::endpoint m_remote;
|
||||
|
||||
// the local address we're listening on
|
||||
address_v4 m_local_ip;
|
||||
|
||||
// the udp socket used to send and receive
|
||||
// multicast messages on the network
|
||||
broadcast_socket m_socket;
|
||||
datagram_socket m_socket;
|
||||
|
||||
// used to resend udp packets in case
|
||||
// they time out
|
||||
|
@ -211,6 +217,8 @@ private:
|
|||
|
||||
// timer used to refresh mappings
|
||||
deadline_timer m_refresh_timer;
|
||||
|
||||
asio::strand m_strand;
|
||||
|
||||
bool m_disabled;
|
||||
bool m_closing;
|
||||
|
|
|
@ -65,6 +65,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/alert.hpp"
|
||||
#include "libtorrent/torrent_handle.hpp"
|
||||
#include "libtorrent/torrent.hpp"
|
||||
#include "libtorrent/allocate_resources.hpp"
|
||||
#include "libtorrent/peer_request.hpp"
|
||||
#include "libtorrent/piece_block_progress.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
|
@ -125,8 +126,6 @@ namespace libtorrent
|
|||
void write_piece(peer_request const& r, char const* buffer) { assert(false); }
|
||||
void write_keepalive() {}
|
||||
void on_connected();
|
||||
void write_reject_request(peer_request const&) {}
|
||||
void write_allow_fast(int) {}
|
||||
|
||||
#ifndef NDEBUG
|
||||
void check_invariant() const;
|
||||
|
|
|
@ -1,73 +0,0 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2007, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#if defined __linux__ && defined __GNUC__
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
|
||||
void assert_fail(char const* expr, int line, char const* file, char const* function)
|
||||
{
|
||||
|
||||
fprintf(stderr, "assertion failed. Please file a bugreport at "
|
||||
"http://code.rasterbar.com/libtorrent/newticket\n"
|
||||
"Please include the following information:\n\n"
|
||||
"file: '%s'\n"
|
||||
"line: %d\n"
|
||||
"function: %s\n"
|
||||
"expression: %s\n"
|
||||
"stack:\n", file, line, function, expr);
|
||||
|
||||
#if defined __linux__ && defined __GNUC__
|
||||
void* stack[50];
|
||||
int size = backtrace(stack, 50);
|
||||
char** symbols = backtrace_symbols(stack, size);
|
||||
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
fprintf(stderr, "%d: %s\n", i, symbols[i]);
|
||||
}
|
||||
|
||||
free(symbols);
|
||||
#endif
|
||||
// send SIGINT to the current process
|
||||
// to break into the debugger
|
||||
raise(SIGINT);
|
||||
abort();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -1,186 +0,0 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2007, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#include <asio/ip/host_name.hpp>
|
||||
#include <asio/ip/multicast.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/enum_net.hpp"
|
||||
#include "libtorrent/broadcast_socket.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
bool is_local(address const& a)
|
||||
{
|
||||
if (a.is_v6()) return a.to_v6().is_link_local();
|
||||
address_v4 a4 = a.to_v4();
|
||||
unsigned long ip = a4.to_ulong();
|
||||
return ((ip & 0xff000000) == 0x0a000000
|
||||
|| (ip & 0xfff00000) == 0xac100000
|
||||
|| (ip & 0xffff0000) == 0xc0a80000);
|
||||
}
|
||||
|
||||
address_v4 guess_local_address(asio::io_service& ios)
|
||||
{
|
||||
// make a best guess of the interface we're using and its IP
|
||||
udp::resolver r(ios);
|
||||
udp::resolver::iterator i = r.resolve(udp::resolver::query(asio::ip::host_name(), "0"));
|
||||
for (;i != udp::resolver_iterator(); ++i)
|
||||
{
|
||||
address const& a = i->endpoint().address();
|
||||
// ignore non-IPv4 addresses
|
||||
if (!a.is_v4()) break;
|
||||
// ignore the loopback
|
||||
if (a.to_v4() == address_v4::loopback()) continue;
|
||||
}
|
||||
if (i == udp::resolver_iterator()) return address_v4::any();
|
||||
return i->endpoint().address().to_v4();
|
||||
}
|
||||
|
||||
bool is_loopback(address const& addr)
|
||||
{
|
||||
if (addr.is_v4())
|
||||
return addr.to_v4() == address_v4::loopback();
|
||||
else
|
||||
return addr.to_v6() == address_v6::loopback();
|
||||
}
|
||||
|
||||
bool is_multicast(address const& addr)
|
||||
{
|
||||
if (addr.is_v4())
|
||||
return addr.to_v4().is_multicast();
|
||||
else
|
||||
return addr.to_v6().is_multicast();
|
||||
}
|
||||
|
||||
broadcast_socket::broadcast_socket(asio::io_service& ios
|
||||
, udp::endpoint const& multicast_endpoint
|
||||
, receive_handler_t const& handler
|
||||
, bool loopback)
|
||||
: m_multicast_endpoint(multicast_endpoint)
|
||||
, m_on_receive(handler)
|
||||
{
|
||||
assert(is_multicast(m_multicast_endpoint.address()));
|
||||
|
||||
using namespace asio::ip::multicast;
|
||||
|
||||
asio::error_code ec;
|
||||
std::vector<address> interfaces = enum_net_interfaces(ios, ec);
|
||||
|
||||
for (std::vector<address>::const_iterator i = interfaces.begin()
|
||||
, end(interfaces.end()); i != end; ++i)
|
||||
{
|
||||
// only broadcast to IPv4 addresses that are not local
|
||||
if (!is_local(*i)) continue;
|
||||
// only multicast on compatible networks
|
||||
if (i->is_v4() != multicast_endpoint.address().is_v4()) continue;
|
||||
// ignore any loopback interface
|
||||
if (is_loopback(*i)) continue;
|
||||
|
||||
boost::shared_ptr<datagram_socket> s(new datagram_socket(ios));
|
||||
if (i->is_v4())
|
||||
{
|
||||
s->open(udp::v4(), ec);
|
||||
if (ec) continue;
|
||||
s->set_option(datagram_socket::reuse_address(true), ec);
|
||||
if (ec) continue;
|
||||
s->bind(udp::endpoint(address_v4::any(), multicast_endpoint.port()), ec);
|
||||
if (ec) continue;
|
||||
s->set_option(join_group(multicast_endpoint.address()), ec);
|
||||
if (ec) continue;
|
||||
s->set_option(outbound_interface(i->to_v4()), ec);
|
||||
if (ec) continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
s->open(udp::v6(), ec);
|
||||
if (ec) continue;
|
||||
s->set_option(datagram_socket::reuse_address(true), ec);
|
||||
if (ec) continue;
|
||||
s->bind(udp::endpoint(address_v6::any(), multicast_endpoint.port()), ec);
|
||||
if (ec) continue;
|
||||
s->set_option(join_group(multicast_endpoint.address()), ec);
|
||||
if (ec) continue;
|
||||
// s->set_option(outbound_interface(i->to_v6()), ec);
|
||||
// if (ec) continue;
|
||||
}
|
||||
s->set_option(hops(255), ec);
|
||||
if (ec) continue;
|
||||
s->set_option(enable_loopback(loopback), ec);
|
||||
if (ec) continue;
|
||||
m_sockets.push_back(socket_entry(s));
|
||||
socket_entry& se = m_sockets.back();
|
||||
s->async_receive_from(asio::buffer(se.buffer, sizeof(se.buffer))
|
||||
, se.remote, bind(&broadcast_socket::on_receive, this, &se, _1, _2));
|
||||
#ifndef NDEBUG
|
||||
// std::cerr << "broadcast socket [ if: " << i->to_v4().to_string()
|
||||
// << " group: " << multicast_endpoint.address() << " ]" << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void broadcast_socket::send(char const* buffer, int size, asio::error_code& ec)
|
||||
{
|
||||
for (std::list<socket_entry>::iterator i = m_sockets.begin()
|
||||
, end(m_sockets.end()); i != end; ++i)
|
||||
{
|
||||
asio::error_code e;
|
||||
i->socket->send_to(asio::buffer(buffer, size), m_multicast_endpoint, 0, e);
|
||||
#ifndef NDEBUG
|
||||
// std::cerr << " sending on " << i->socket->local_endpoint().address().to_string() << std::endl;
|
||||
#endif
|
||||
if (e) ec = e;
|
||||
}
|
||||
}
|
||||
|
||||
void broadcast_socket::on_receive(socket_entry* s, asio::error_code const& ec
|
||||
, std::size_t bytes_transferred)
|
||||
{
|
||||
if (ec || bytes_transferred == 0) return;
|
||||
m_on_receive(s->remote, s->buffer, bytes_transferred);
|
||||
s->socket->async_receive_from(asio::buffer(s->buffer, sizeof(s->buffer))
|
||||
, s->remote, bind(&broadcast_socket::on_receive, this, s, _1, _2));
|
||||
}
|
||||
|
||||
void broadcast_socket::close()
|
||||
{
|
||||
for (std::list<socket_entry>::iterator i = m_sockets.begin()
|
||||
, end(m_sockets.end()); i != end; ++i)
|
||||
{
|
||||
i->socket->close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -50,7 +50,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/version.hpp"
|
||||
#include "libtorrent/extensions.hpp"
|
||||
#include "libtorrent/aux_/session_impl.hpp"
|
||||
#include "libtorrent/enum_net.hpp"
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
#include "libtorrent/pe_crypto.hpp"
|
||||
|
@ -76,14 +75,7 @@ namespace libtorrent
|
|||
&bt_peer_connection::on_piece,
|
||||
&bt_peer_connection::on_cancel,
|
||||
&bt_peer_connection::on_dht_port,
|
||||
0, 0, 0,
|
||||
// FAST extension messages
|
||||
&bt_peer_connection::on_suggest_piece,
|
||||
&bt_peer_connection::on_have_all,
|
||||
&bt_peer_connection::on_have_none,
|
||||
&bt_peer_connection::on_reject_request,
|
||||
&bt_peer_connection::on_allowed_fast,
|
||||
0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
&bt_peer_connection::on_extended
|
||||
};
|
||||
|
||||
|
@ -101,7 +93,6 @@ namespace libtorrent
|
|||
, m_supports_extensions(false)
|
||||
#endif
|
||||
, m_supports_dht_port(false)
|
||||
, m_supports_fast(false)
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
, m_encrypted(false)
|
||||
, m_rc4_encrypted(false)
|
||||
|
@ -133,7 +124,6 @@ namespace libtorrent
|
|||
, m_supports_extensions(false)
|
||||
#endif
|
||||
, m_supports_dht_port(false)
|
||||
, m_supports_fast(false)
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
, m_encrypted(false)
|
||||
, m_rc4_encrypted(false)
|
||||
|
@ -236,10 +226,6 @@ namespace libtorrent
|
|||
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
||||
assert(t);
|
||||
write_bitfield(t->pieces());
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
if (m_supports_dht_port && m_ses.m_dht)
|
||||
write_dht_port(m_ses.get_dht_settings().service_port);
|
||||
#endif
|
||||
}
|
||||
|
||||
void bt_peer_connection::write_dht_port(int listen_port)
|
||||
|
@ -260,75 +246,6 @@ namespace libtorrent
|
|||
setup_send();
|
||||
}
|
||||
|
||||
void bt_peer_connection::write_have_all()
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
assert(m_sent_handshake && !m_sent_bitfield);
|
||||
#ifndef NDEBUG
|
||||
m_sent_bitfield = true;
|
||||
#endif
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
(*m_logger) << time_now_string()
|
||||
<< " ==> HAVE_ALL\n";
|
||||
#endif
|
||||
char buf[] = {0,0,0,1, msg_have_all};
|
||||
send_buffer(buf, buf + sizeof(buf));
|
||||
}
|
||||
|
||||
void bt_peer_connection::write_have_none()
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
assert(m_sent_handshake && !m_sent_bitfield);
|
||||
#ifndef NDEBUG
|
||||
m_sent_bitfield = true;
|
||||
#endif
|
||||
#ifdef TORRENT_VERBOSE_LOGGING
|
||||
(*m_logger) << time_now_string()
|
||||
<< " ==> HAVE_NONE\n";
|
||||
#endif
|
||||
char buf[] = {0,0,0,1, msg_have_none};
|
||||
send_buffer(buf, buf + sizeof(buf));
|
||||
}
|
||||
|
||||
void bt_peer_connection::write_reject_request(peer_request const& r)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
assert(m_sent_handshake && m_sent_bitfield);
|
||||
assert(associated_torrent().lock()->valid_metadata());
|
||||
|
||||
char buf[] = {0,0,0,13, msg_reject_request};
|
||||
|
||||
buffer::interval i = allocate_send_buffer(17);
|
||||
|
||||
std::copy(buf, buf + 5, i.begin);
|
||||
i.begin += 5;
|
||||
|
||||
// index
|
||||
detail::write_int32(r.piece, i.begin);
|
||||
// begin
|
||||
detail::write_int32(r.start, i.begin);
|
||||
// length
|
||||
detail::write_int32(r.length, i.begin);
|
||||
assert(i.begin == i.end);
|
||||
|
||||
setup_send();
|
||||
}
|
||||
|
||||
void bt_peer_connection::write_allow_fast(int piece)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
assert(m_sent_handshake && m_sent_bitfield);
|
||||
assert(associated_torrent().lock()->valid_metadata());
|
||||
|
||||
char buf[] = {0,0,0,5, msg_allowed_fast, 0, 0, 0, 0};
|
||||
|
||||
char* ptr = buf + 5;
|
||||
detail::write_int32(piece, ptr);
|
||||
send_buffer(buf, buf + sizeof(buf));
|
||||
}
|
||||
|
||||
void bt_peer_connection::get_specific_peer_info(peer_info& p) const
|
||||
{
|
||||
assert(!associated_torrent().expired());
|
||||
|
@ -711,17 +628,14 @@ namespace libtorrent
|
|||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
// indicate that we support the DHT messages
|
||||
*(i.begin + 7) |= 0x01;
|
||||
*(i.begin + 7) = 0x01;
|
||||
#endif
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
// we support extensions
|
||||
*(i.begin + 5) |= 0x10;
|
||||
*(i.begin + 5) = 0x10;
|
||||
#endif
|
||||
|
||||
// we support FAST extension
|
||||
*(i.begin + 7) |= 0x04;
|
||||
|
||||
i.begin += 8;
|
||||
|
||||
// info hash
|
||||
|
@ -807,20 +721,6 @@ namespace libtorrent
|
|||
if (!packet_finished()) return;
|
||||
|
||||
incoming_choke();
|
||||
if (!m_supports_fast)
|
||||
{
|
||||
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
||||
assert(t);
|
||||
while (!request_queue().empty())
|
||||
{
|
||||
piece_block const& b = request_queue().front();
|
||||
peer_request r;
|
||||
r.piece = b.piece_index;
|
||||
r.start = b.block_index * t->block_size();
|
||||
r.length = t->block_size();
|
||||
incoming_reject_request(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
|
@ -1039,9 +939,6 @@ namespace libtorrent
|
|||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (!m_supports_dht_port)
|
||||
throw protocol_error("got 'dht_port' message from peer that doesn't support it");
|
||||
|
||||
assert(received > 0);
|
||||
if (packet_size() != 3)
|
||||
throw protocol_error("'dht_port' message size != 3");
|
||||
|
@ -1056,80 +953,6 @@ namespace libtorrent
|
|||
incoming_dht_port(listen_port);
|
||||
}
|
||||
|
||||
void bt_peer_connection::on_suggest_piece(int received)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (!m_supports_fast)
|
||||
throw protocol_error("got 'suggest_piece' without FAST extension support");
|
||||
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (!packet_finished()) return;
|
||||
|
||||
buffer::const_interval recv_buffer = receive_buffer();
|
||||
|
||||
const char* ptr = recv_buffer.begin + 1;
|
||||
int piece = detail::read_uint32(ptr);
|
||||
incoming_suggest(piece);
|
||||
}
|
||||
|
||||
void bt_peer_connection::on_have_all(int received)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (!m_supports_fast)
|
||||
throw protocol_error("got 'have_all' without FAST extension support");
|
||||
m_statistics.received_bytes(0, received);
|
||||
incoming_have_all();
|
||||
}
|
||||
|
||||
void bt_peer_connection::on_have_none(int received)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (!m_supports_fast)
|
||||
throw protocol_error("got 'have_none' without FAST extension support");
|
||||
m_statistics.received_bytes(0, received);
|
||||
incoming_have_none();
|
||||
}
|
||||
|
||||
void bt_peer_connection::on_reject_request(int received)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (!m_supports_fast)
|
||||
throw protocol_error("got 'reject_request' without FAST extension support");
|
||||
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (!packet_finished()) return;
|
||||
|
||||
buffer::const_interval recv_buffer = receive_buffer();
|
||||
|
||||
peer_request r;
|
||||
const char* ptr = recv_buffer.begin + 1;
|
||||
r.piece = detail::read_int32(ptr);
|
||||
r.start = detail::read_int32(ptr);
|
||||
r.length = detail::read_int32(ptr);
|
||||
|
||||
incoming_reject_request(r);
|
||||
}
|
||||
|
||||
void bt_peer_connection::on_allowed_fast(int received)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (!m_supports_fast)
|
||||
throw protocol_error("got 'allowed_fast' without FAST extension support");
|
||||
|
||||
m_statistics.received_bytes(0, received);
|
||||
if (!packet_finished()) return;
|
||||
buffer::const_interval recv_buffer = receive_buffer();
|
||||
const char* ptr = recv_buffer.begin + 1;
|
||||
int index = detail::read_int32(ptr);
|
||||
|
||||
incoming_allowed_fast(index);
|
||||
}
|
||||
|
||||
// -----------------------------
|
||||
// --------- EXTENDED ----------
|
||||
// -----------------------------
|
||||
|
@ -1222,7 +1045,7 @@ namespace libtorrent
|
|||
{
|
||||
tcp::endpoint adr(remote().address()
|
||||
, (unsigned short)listen_port->integer());
|
||||
t->get_policy().peer_from_tracker(adr, pid(), peer_info::incoming, 0);
|
||||
t->get_policy().peer_from_tracker(adr, pid(), 0, 0);
|
||||
}
|
||||
}
|
||||
// there should be a version too
|
||||
|
@ -1352,22 +1175,6 @@ namespace libtorrent
|
|||
assert(m_sent_handshake && !m_sent_bitfield);
|
||||
assert(t->valid_metadata());
|
||||
|
||||
// in this case, have_all or have_none should be sent instead
|
||||
assert(!m_supports_fast || !t->is_seed() || t->num_pieces() != 0);
|
||||
|
||||
if (m_supports_fast && t->is_seed())
|
||||
{
|
||||
write_have_all();
|
||||
send_allowed_set();
|
||||
return;
|
||||
}
|
||||
else if (m_supports_fast && t->num_pieces() == 0)
|
||||
{
|
||||
write_have_none();
|
||||
send_allowed_set();
|
||||
return;
|
||||
}
|
||||
|
||||
int num_pieces = bitfield.size();
|
||||
int lazy_pieces[50];
|
||||
int num_lazy_pieces = 0;
|
||||
|
@ -1376,7 +1183,7 @@ namespace libtorrent
|
|||
assert(t->is_seed() == (std::count(bitfield.begin(), bitfield.end(), true) == num_pieces));
|
||||
if (t->is_seed() && m_ses.settings().lazy_bitfields)
|
||||
{
|
||||
num_lazy_pieces = (std::min)(50, num_pieces / 10);
|
||||
num_lazy_pieces = std::min(50, num_pieces / 10);
|
||||
if (num_lazy_pieces < 1) num_lazy_pieces = 1;
|
||||
for (int i = 0; i < num_pieces; ++i)
|
||||
{
|
||||
|
@ -1444,9 +1251,6 @@ namespace libtorrent
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (m_supports_fast)
|
||||
send_allowed_set();
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
|
@ -1475,19 +1279,6 @@ namespace libtorrent
|
|||
detail::write_address(remote().address(), out);
|
||||
handshake["yourip"] = remote_address;
|
||||
handshake["reqq"] = m_ses.settings().max_allowed_in_request_queue;
|
||||
asio::error_code ec;
|
||||
std::vector<address> const& interfaces = enum_net_interfaces(get_socket()->io_service(), ec);
|
||||
for (std::vector<address>::const_iterator i = interfaces.begin()
|
||||
, end(interfaces.end()); i != end; ++i)
|
||||
{
|
||||
// TODO: only use global IPv6 addresses
|
||||
if (!i->is_v6() || i->to_v6().is_link_local()) continue;
|
||||
std::string ipv6_address;
|
||||
std::back_insert_iterator<std::string> out(ipv6_address);
|
||||
detail::write_address(*i, out);
|
||||
handshake["ipv6"] = ipv6_address;
|
||||
break;
|
||||
}
|
||||
|
||||
// loop backwards, to make the first extension be the last
|
||||
// to fill in the handshake (i.e. give the first extensions priority)
|
||||
|
@ -1755,7 +1546,7 @@ namespace libtorrent
|
|||
if (m_sync_bytes_read >= 512)
|
||||
throw protocol_error("sync hash not found within 532 bytes");
|
||||
|
||||
cut_receive_buffer(bytes_processed, (std::min)(packet_size(), (512+20) - m_sync_bytes_read));
|
||||
cut_receive_buffer(bytes_processed, std::min(packet_size(), (512+20) - m_sync_bytes_read));
|
||||
|
||||
assert(!packet_finished());
|
||||
return;
|
||||
|
@ -1893,7 +1684,7 @@ namespace libtorrent
|
|||
if (m_sync_bytes_read >= 512)
|
||||
throw protocol_error("sync verification constant not found within 520 bytes");
|
||||
|
||||
cut_receive_buffer(bytes_processed, (std::min)(packet_size(), (512+8) - m_sync_bytes_read));
|
||||
cut_receive_buffer(bytes_processed, std::min(packet_size(), (512+8) - m_sync_bytes_read));
|
||||
|
||||
assert(!packet_finished());
|
||||
return;
|
||||
|
@ -2225,9 +2016,6 @@ namespace libtorrent
|
|||
if (recv_buffer[7] & 0x01)
|
||||
m_supports_dht_port = true;
|
||||
|
||||
if (recv_buffer[7] & 0x04)
|
||||
m_supports_fast = true;
|
||||
|
||||
// ok, now we have got enough of the handshake. Is this connection
|
||||
// attached to a torrent?
|
||||
if (!t)
|
||||
|
@ -2261,10 +2049,10 @@ namespace libtorrent
|
|||
assert(t);
|
||||
|
||||
// if this is a local connection, we have already
|
||||
// sent the handshake
|
||||
// send the handshake
|
||||
if (!is_local()) write_handshake();
|
||||
// if (t->valid_metadata())
|
||||
// write_bitfield(t->pieces());
|
||||
if (t->valid_metadata())
|
||||
write_bitfield(t->pieces());
|
||||
|
||||
assert(t->get_policy().has_connection(this));
|
||||
|
||||
|
@ -2337,6 +2125,11 @@ namespace libtorrent
|
|||
throw protocol_error("closing connection to ourself");
|
||||
}
|
||||
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
if (m_supports_dht_port && m_ses.m_dht)
|
||||
write_dht_port(m_ses.get_dht_settings().service_port);
|
||||
#endif
|
||||
|
||||
m_client_version = identify_client(pid);
|
||||
boost::optional<fingerprint> f = client_fingerprint(pid);
|
||||
if (f && std::equal(f->name, f->name + 2, "BC"))
|
||||
|
@ -2388,14 +2181,6 @@ namespace libtorrent
|
|||
|
||||
m_state = read_packet_size;
|
||||
reset_recv_buffer(4);
|
||||
if (t->valid_metadata())
|
||||
{
|
||||
write_bitfield(t->pieces());
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
if (m_supports_dht_port && m_ses.m_dht)
|
||||
write_dht_port(m_ses.get_dht_settings().service_port);
|
||||
#endif
|
||||
}
|
||||
|
||||
assert(!packet_finished());
|
||||
return;
|
||||
|
|
|
@ -54,8 +54,6 @@ namespace libtorrent
|
|||
, boost::function<void()> const& on_timeout
|
||||
, time_duration timeout)
|
||||
{
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
INVARIANT_CHECK;
|
||||
|
||||
m_queue.push_back(entry());
|
||||
|
@ -70,8 +68,6 @@ namespace libtorrent
|
|||
|
||||
void connection_queue::done(int ticket)
|
||||
{
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
INVARIANT_CHECK;
|
||||
|
||||
std::list<entry>::iterator i = std::find_if(m_queue.begin()
|
||||
|
@ -152,8 +148,6 @@ namespace libtorrent
|
|||
|
||||
void connection_queue::on_timeout(asio::error_code const& e)
|
||||
{
|
||||
mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
INVARIANT_CHECK;
|
||||
#ifndef NDEBUG
|
||||
function_guard guard_(m_in_timeout_function);
|
||||
|
@ -164,35 +158,21 @@ namespace libtorrent
|
|||
|
||||
ptime next_expire = max_time();
|
||||
ptime now = time_now();
|
||||
std::list<entry> timed_out;
|
||||
for (std::list<entry>::iterator i = m_queue.begin();
|
||||
!m_queue.empty() && i != m_queue.end();)
|
||||
{
|
||||
if (i->connecting && i->expires < now)
|
||||
{
|
||||
std::list<entry>::iterator j = i;
|
||||
++i;
|
||||
timed_out.splice(timed_out.end(), m_queue, j, i);
|
||||
boost::function<void()> on_timeout = i->on_timeout;
|
||||
m_queue.erase(i++);
|
||||
--m_num_connecting;
|
||||
try { on_timeout(); } catch (std::exception&) {}
|
||||
continue;
|
||||
}
|
||||
if (i->expires < next_expire)
|
||||
next_expire = i->expires;
|
||||
++i;
|
||||
}
|
||||
|
||||
// we don't want to call the timeout callback while we're locked
|
||||
// since that is a recepie for dead-locks
|
||||
l.unlock();
|
||||
|
||||
for (std::list<entry>::iterator i = timed_out.begin()
|
||||
, end(timed_out.end()); i != end; ++i)
|
||||
{
|
||||
try { i->on_timeout(); } catch (std::exception&) {}
|
||||
}
|
||||
|
||||
l.lock();
|
||||
|
||||
if (next_expire < max_time())
|
||||
{
|
||||
m_timer.expires_at(next_expire);
|
||||
|
|
|
@ -34,24 +34,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <deque>
|
||||
#include "libtorrent/disk_io_thread.hpp"
|
||||
|
||||
#ifdef TORRENT_DISK_STATS
|
||||
|
||||
#include "libtorrent/time.hpp"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string log_time()
|
||||
{
|
||||
using namespace libtorrent;
|
||||
static ptime start = time_now();
|
||||
return boost::lexical_cast<std::string>(
|
||||
total_milliseconds(time_now() - start));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
||||
|
@ -63,12 +45,7 @@ namespace libtorrent
|
|||
, m_block_size(block_size)
|
||||
#endif
|
||||
, m_disk_io_thread(boost::ref(*this))
|
||||
{
|
||||
|
||||
#ifdef TORRENT_DISK_STATS
|
||||
m_log.open("disk_io_thread.log", std::ios::trunc);
|
||||
#endif
|
||||
}
|
||||
{}
|
||||
|
||||
disk_io_thread::~disk_io_thread()
|
||||
{
|
||||
|
@ -112,15 +89,8 @@ namespace libtorrent
|
|||
|
||||
namespace
|
||||
{
|
||||
// The semantic of this operator is:
|
||||
// shouls lhs come before rhs in the job queue
|
||||
bool operator<(disk_io_job const& lhs, disk_io_job const& rhs)
|
||||
{
|
||||
// NOTE: comparison inverted to make higher priority
|
||||
// skip _in_front_of_ lower priority
|
||||
if (lhs.priority > rhs.priority) return true;
|
||||
if (lhs.priority < rhs.priority) return false;
|
||||
|
||||
if (lhs.storage.get() < rhs.storage.get()) return true;
|
||||
if (lhs.storage.get() > rhs.storage.get()) return false;
|
||||
if (lhs.piece < rhs.piece) return true;
|
||||
|
@ -195,9 +165,6 @@ namespace libtorrent
|
|||
{
|
||||
for (;;)
|
||||
{
|
||||
#ifdef TORRENT_DISK_STATS
|
||||
m_log << log_time() << " idle" << std::endl;
|
||||
#endif
|
||||
boost::mutex::scoped_lock l(m_mutex);
|
||||
while (m_jobs.empty() && !m_abort)
|
||||
m_signal.wait(l);
|
||||
|
@ -212,46 +179,31 @@ namespace libtorrent
|
|||
|
||||
int ret = 0;
|
||||
|
||||
bool free_buffer = true;
|
||||
try
|
||||
{
|
||||
#ifdef TORRENT_DISK_STATS
|
||||
ptime start = time_now();
|
||||
#endif
|
||||
// std::cerr << "DISK THREAD: executing job: " << j.action << std::endl;
|
||||
switch (j.action)
|
||||
{
|
||||
case disk_io_job::read:
|
||||
#ifdef TORRENT_DISK_STATS
|
||||
m_log << log_time() << " read " << j.buffer_size << std::endl;
|
||||
#endif
|
||||
l.lock();
|
||||
j.buffer = (char*)m_pool.ordered_malloc();
|
||||
l.unlock();
|
||||
if (j.buffer == 0)
|
||||
{
|
||||
l.lock();
|
||||
j.buffer = (char*)m_pool.ordered_malloc();
|
||||
l.unlock();
|
||||
assert(j.buffer_size <= m_block_size);
|
||||
if (j.buffer == 0)
|
||||
{
|
||||
ret = -1;
|
||||
j.str = "out of memory";
|
||||
break;
|
||||
}
|
||||
ret = -1;
|
||||
j.str = "out of memory";
|
||||
}
|
||||
else
|
||||
{
|
||||
free_buffer = false;
|
||||
}
|
||||
ret = j.storage->read_impl(j.buffer, j.piece, j.offset
|
||||
, j.buffer_size);
|
||||
assert(j.buffer_size <= m_block_size);
|
||||
ret = j.storage->read_impl(j.buffer, j.piece, j.offset
|
||||
, j.buffer_size);
|
||||
|
||||
// simulates slow drives
|
||||
// usleep(300);
|
||||
// simulates slow drives
|
||||
// usleep(300);
|
||||
}
|
||||
break;
|
||||
case disk_io_job::write:
|
||||
#ifdef TORRENT_DISK_STATS
|
||||
m_log << log_time() << " write " << j.buffer_size << std::endl;
|
||||
#endif
|
||||
assert(j.buffer);
|
||||
assert(j.buffer_size <= m_block_size);
|
||||
j.storage->write_impl(j.buffer, j.piece, j.offset
|
||||
|
@ -262,25 +214,16 @@ namespace libtorrent
|
|||
break;
|
||||
case disk_io_job::hash:
|
||||
{
|
||||
#ifdef TORRENT_DISK_STATS
|
||||
m_log << log_time() << " hash" << std::endl;
|
||||
#endif
|
||||
sha1_hash h = j.storage->hash_for_piece_impl(j.piece);
|
||||
j.str.resize(20);
|
||||
std::memcpy(&j.str[0], &h[0], 20);
|
||||
}
|
||||
break;
|
||||
case disk_io_job::move_storage:
|
||||
#ifdef TORRENT_DISK_STATS
|
||||
m_log << log_time() << " move" << std::endl;
|
||||
#endif
|
||||
ret = j.storage->move_storage_impl(j.str) ? 1 : 0;
|
||||
j.str = j.storage->save_path().string();
|
||||
break;
|
||||
case disk_io_job::release_files:
|
||||
#ifdef TORRENT_DISK_STATS
|
||||
m_log << log_time() << " release" << std::endl;
|
||||
#endif
|
||||
j.storage->release_files_impl();
|
||||
break;
|
||||
}
|
||||
|
@ -297,7 +240,7 @@ namespace libtorrent
|
|||
try { if (handler) handler(ret, j); }
|
||||
catch (std::exception&) {}
|
||||
|
||||
if (j.buffer && free_buffer)
|
||||
if (j.buffer)
|
||||
{
|
||||
l.lock();
|
||||
m_pool.ordered_free(j.buffer);
|
||||
|
|
|
@ -1,142 +0,0 @@
|
|||
/*
|
||||
|
||||
Copyright (c) 2007, Arvid Norberg
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the author nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
*/
|
||||
|
||||
#if defined __linux__ || defined __MACH__
|
||||
#include <sys/ioctl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
|
||||
#include "libtorrent/enum_net.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
std::vector<address> const& enum_net_interfaces(asio::io_service& ios, asio::error_code& ec)
|
||||
{
|
||||
static std::vector<address> ret;
|
||||
if (!ret.empty()) return ret;
|
||||
|
||||
#if defined __linux__ || defined __MACH__ || defined(__FreeBSD__)
|
||||
int s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0)
|
||||
{
|
||||
ec = asio::error::fault;
|
||||
return ret;
|
||||
}
|
||||
ifconf ifc;
|
||||
char buf[1024];
|
||||
ifc.ifc_len = sizeof(buf);
|
||||
ifc.ifc_buf = buf;
|
||||
if (ioctl(s, SIOCGIFCONF, &ifc) < 0)
|
||||
{
|
||||
close(s);
|
||||
ec = asio::error::fault;
|
||||
return ret;
|
||||
}
|
||||
close(s);
|
||||
|
||||
char *ifr = (char*)ifc.ifc_req;
|
||||
int remaining = ifc.ifc_len;
|
||||
|
||||
while (remaining)
|
||||
{
|
||||
ifreq const& item = *reinterpret_cast<ifreq*>(ifr);
|
||||
if (item.ifr_addr.sa_family == AF_INET)
|
||||
{
|
||||
typedef asio::ip::address_v4::bytes_type bytes_t;
|
||||
bytes_t b;
|
||||
memcpy(&b[0], &((sockaddr_in const*)&item.ifr_addr)->sin_addr, b.size());
|
||||
ret.push_back(address_v4(b));
|
||||
}
|
||||
else if (item.ifr_addr.sa_family == AF_INET6)
|
||||
{
|
||||
typedef asio::ip::address_v6::bytes_type bytes_t;
|
||||
bytes_t b;
|
||||
memcpy(&b[0], &((sockaddr_in6 const*)&item.ifr_addr)->sin6_addr, b.size());
|
||||
ret.push_back(address_v6(b));
|
||||
}
|
||||
|
||||
#if defined __MACH__ || defined(__FreeBSD__)
|
||||
int current_size = item.ifr_addr.sa_len + IFNAMSIZ;
|
||||
#elif defined __linux__
|
||||
int current_size = sizeof(ifreq);
|
||||
#endif
|
||||
ifr += current_size;
|
||||
remaining -= current_size;
|
||||
}
|
||||
|
||||
#elif defined WIN32
|
||||
|
||||
SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s == SOCKET_ERROR)
|
||||
{
|
||||
ec = asio::error::fault;
|
||||
return ret;
|
||||
}
|
||||
|
||||
INTERFACE_INFO buffer[30];
|
||||
DWORD size;
|
||||
|
||||
if (WSAIoctl(s, SIO_GET_INTERFACE_LIST, 0, 0, buffer,
|
||||
sizeof(buffer), &size, 0, 0) != 0)
|
||||
{
|
||||
closesocket(s);
|
||||
ec = asio::error::fault;
|
||||
return ret;
|
||||
}
|
||||
closesocket(s);
|
||||
|
||||
int n = size / sizeof(INTERFACE_INFO);
|
||||
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
sockaddr_in *sockaddr = (sockaddr_in*)&buffer[i].iiAddress;
|
||||
address a(address::from_string(inet_ntoa(sockaddr->sin_addr)));
|
||||
if (a == address_v4::any()) continue;
|
||||
ret.push_back(a);
|
||||
}
|
||||
|
||||
#else
|
||||
// make a best guess of the interface we're using and its IP
|
||||
udp::resolver r(ios);
|
||||
udp::resolver::iterator i = r.resolve(udp::resolver::query(asio::ip::host_name(), "0"));
|
||||
for (;i != udp::resolver_iterator(); ++i)
|
||||
{
|
||||
ret.push_back(i->endpoint().address());
|
||||
}
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -33,14 +33,13 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/pch.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include <cctype>
|
||||
#include <algorithm>
|
||||
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
std::string unescape_string(std::string const& s)
|
||||
|
|
|
@ -247,16 +247,19 @@ namespace libtorrent
|
|||
|
||||
void set_size(size_type s)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#error file.cpp is for posix systems only. use file_win.cpp on windows
|
||||
#else
|
||||
if (ftruncate(m_fd, s) < 0)
|
||||
size_type pos = tell();
|
||||
// Only set size if current file size not equals s.
|
||||
// 2 as "m" argument is to be sure seek() sets SEEK_END on
|
||||
// all compilers.
|
||||
if(s != seek(0, 2))
|
||||
{
|
||||
std::stringstream msg;
|
||||
msg << "ftruncate failed: '" << strerror(errno);
|
||||
throw file_error(msg.str());
|
||||
seek(s - 1);
|
||||
char dummy = 0;
|
||||
read(&dummy, 1);
|
||||
seek(s - 1);
|
||||
write(&dummy, 1);
|
||||
}
|
||||
#endif
|
||||
seek(pos);
|
||||
}
|
||||
|
||||
size_type seek(size_type offset, int m = 1)
|
||||
|
|
|
@ -42,8 +42,6 @@ using boost::bind;
|
|||
namespace libtorrent
|
||||
{
|
||||
|
||||
enum { max_bottled_buffer = 1024 * 1024 };
|
||||
|
||||
void http_connection::get(std::string const& url, time_duration timeout
|
||||
, bool handle_redirect)
|
||||
{
|
||||
|
@ -167,7 +165,6 @@ void http_connection::on_connect(asio::error_code const& e
|
|||
if (!e)
|
||||
{
|
||||
m_last_receive = time_now();
|
||||
if (m_connect_handler) m_connect_handler(*this);
|
||||
asio::async_write(m_sock, asio::buffer(sendbuffer)
|
||||
, bind(&http_connection::on_write, shared_from_this(), _1));
|
||||
}
|
||||
|
@ -313,8 +310,8 @@ void http_connection::on_read(asio::error_code const& e
|
|||
}
|
||||
|
||||
if (int(m_recvbuffer.size()) == m_read_pos)
|
||||
m_recvbuffer.resize((std::min)(m_read_pos + 2048, int(max_bottled_buffer)));
|
||||
if (m_read_pos == max_bottled_buffer)
|
||||
m_recvbuffer.resize((std::min)(m_read_pos + 2048, 1024*500));
|
||||
if (m_read_pos == 1024 * 500)
|
||||
{
|
||||
close();
|
||||
if (m_bottled && m_called) return;
|
||||
|
|
|
@ -148,19 +148,13 @@ namespace libtorrent
|
|||
pos = newline;
|
||||
|
||||
line >> m_protocol;
|
||||
if (m_protocol.substr(0, 5) == "HTTP/")
|
||||
if (m_protocol.substr(0, 5) != "HTTP/")
|
||||
{
|
||||
line >> m_status_code;
|
||||
std::getline(line, m_server_message);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_method = m_protocol;
|
||||
std::transform(m_method.begin(), m_method.end(), m_method.begin(), &to_lower);
|
||||
m_protocol.clear();
|
||||
line >> m_path >> m_protocol;
|
||||
m_status_code = 0;
|
||||
throw std::runtime_error("unknown protocol in HTTP response: "
|
||||
+ m_protocol + " line: " + std::string(pos, newline));
|
||||
}
|
||||
line >> m_status_code;
|
||||
std::getline(line, m_server_message);
|
||||
m_state = read_header;
|
||||
}
|
||||
|
||||
|
@ -256,7 +250,7 @@ namespace libtorrent
|
|||
assert(m_state == read_body);
|
||||
if (m_content_length >= 0)
|
||||
return buffer::const_interval(m_recv_buffer.begin + m_body_start_pos
|
||||
, m_recv_buffer.begin + (std::min)(m_recv_pos
|
||||
, m_recv_buffer.begin + std::min(m_recv_pos
|
||||
, m_body_start_pos + m_content_length));
|
||||
else
|
||||
return buffer::const_interval(m_recv_buffer.begin + m_body_start_pos
|
||||
|
@ -414,7 +408,7 @@ namespace libtorrent
|
|||
{
|
||||
m_send_buffer += "numwant=";
|
||||
m_send_buffer += boost::lexical_cast<std::string>(
|
||||
(std::min)(req.num_want, 999));
|
||||
std::min(req.num_want, 999));
|
||||
m_send_buffer += '&';
|
||||
}
|
||||
if (m_settings.announce_ip != address() && !url_has_argument(request, "ip"))
|
||||
|
@ -465,16 +459,14 @@ namespace libtorrent
|
|||
m_send_buffer += "\r\n\r\n";
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
if (cb)
|
||||
if (has_requester())
|
||||
{
|
||||
cb->debug_log("==> TRACKER_REQUEST [ str: " + m_send_buffer + " ]");
|
||||
requester().debug_log("==> TRACKER_REQUEST [ str: " + m_send_buffer + " ]");
|
||||
std::stringstream info_hash_str;
|
||||
info_hash_str << req.info_hash;
|
||||
cb->debug_log("info_hash: "
|
||||
requester().debug_log("info_hash: "
|
||||
+ boost::lexical_cast<std::string>(req.info_hash));
|
||||
cb->debug_log("name lookup: " + hostname);
|
||||
requester().debug_log("name lookup: " + hostname);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -499,9 +491,8 @@ namespace libtorrent
|
|||
void http_tracker_connection::name_lookup(asio::error_code const& error
|
||||
, tcp::resolver::iterator i) try
|
||||
{
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (cb) cb->debug_log("tracker name lookup handler called");
|
||||
if (has_requester()) requester().debug_log("tracker name lookup handler called");
|
||||
#endif
|
||||
if (error == asio::error::operation_aborted) return;
|
||||
if (m_timed_out) return;
|
||||
|
@ -513,7 +504,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (cb) cb->debug_log("tracker name lookup successful");
|
||||
if (has_requester()) requester().debug_log("tracker name lookup successful");
|
||||
#endif
|
||||
restart_read_timeout();
|
||||
|
||||
|
@ -528,11 +519,11 @@ namespace libtorrent
|
|||
if (target == end)
|
||||
{
|
||||
assert(target_address.address().is_v4() != bind_interface().is_v4());
|
||||
if (cb)
|
||||
if (has_requester())
|
||||
{
|
||||
std::string tracker_address_type = target_address.address().is_v4() ? "IPv4" : "IPv6";
|
||||
std::string bind_address_type = bind_interface().is_v4() ? "IPv4" : "IPv6";
|
||||
cb->tracker_warning("the tracker only resolves to an "
|
||||
requester().tracker_warning("the tracker only resolves to an "
|
||||
+ tracker_address_type + " address, and you're listening on an "
|
||||
+ bind_address_type + " socket. This may prevent you from receiving incoming connections.");
|
||||
}
|
||||
|
@ -542,7 +533,7 @@ namespace libtorrent
|
|||
target_address = *target;
|
||||
}
|
||||
|
||||
if (cb) cb->m_tracker_address = target_address;
|
||||
if (has_requester()) requester().m_tracker_address = target_address;
|
||||
m_socket = instantiate_connection(m_name_lookup.io_service(), m_proxy);
|
||||
|
||||
if (m_proxy.type == proxy_settings::http
|
||||
|
@ -583,8 +574,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
if (cb) cb->debug_log("tracker connection successful");
|
||||
if (has_requester()) requester().debug_log("tracker connection successful");
|
||||
#endif
|
||||
|
||||
restart_read_timeout();
|
||||
|
@ -608,8 +598,7 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
if (cb) cb->debug_log("tracker send data completed");
|
||||
if (has_requester()) requester().debug_log("tracker send data completed");
|
||||
#endif
|
||||
restart_read_timeout();
|
||||
assert(m_buffer.size() - m_recv_pos > 0);
|
||||
|
@ -645,8 +634,7 @@ namespace libtorrent
|
|||
restart_read_timeout();
|
||||
assert(bytes_transferred > 0);
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
if (cb) cb->debug_log("tracker connection reading "
|
||||
if (has_requester()) requester().debug_log("tracker connection reading "
|
||||
+ boost::lexical_cast<std::string>(bytes_transferred));
|
||||
#endif
|
||||
|
||||
|
@ -712,8 +700,6 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
std::string location = m_parser.header<std::string>("location");
|
||||
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
|
||||
if (m_parser.status_code() >= 300 && m_parser.status_code() < 400)
|
||||
{
|
||||
|
@ -734,9 +720,9 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (cb) cb->debug_log("Redirecting to \"" + location + "\"");
|
||||
if (has_requester()) requester().debug_log("Redirecting to \"" + location + "\"");
|
||||
#endif
|
||||
if (cb) cb->tracker_warning("Redirecting to \"" + location + "\"");
|
||||
if (has_requester()) requester().tracker_warning("Redirecting to \"" + location + "\"");
|
||||
tracker_request req = tracker_req();
|
||||
|
||||
req.url = location;
|
||||
|
@ -759,18 +745,20 @@ namespace libtorrent
|
|||
std::string content_encoding = m_parser.header<std::string>("content-encoding");
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
if (cb) cb->debug_log("content-encoding: \"" + content_encoding + "\"");
|
||||
if (has_requester()) requester().debug_log("content-encoding: \"" + content_encoding + "\"");
|
||||
#endif
|
||||
|
||||
if (content_encoding == "gzip" || content_encoding == "x-gzip")
|
||||
{
|
||||
if (!cb)
|
||||
boost::shared_ptr<request_callback> r = m_requester.lock();
|
||||
|
||||
if (!r)
|
||||
{
|
||||
close();
|
||||
return;
|
||||
}
|
||||
m_buffer.erase(m_buffer.begin(), m_buffer.begin() + m_parser.body_start());
|
||||
if (inflate_gzip(m_buffer, tracker_request(), cb.get(),
|
||||
if (inflate_gzip(m_buffer, tracker_request(), r.get(),
|
||||
m_settings.tracker_maximum_response_length))
|
||||
{
|
||||
close();
|
||||
|
@ -847,8 +835,7 @@ namespace libtorrent
|
|||
|
||||
void http_tracker_connection::parse(entry const& e)
|
||||
{
|
||||
boost::shared_ptr<request_callback> cb = requester();
|
||||
if (!cb) return;
|
||||
if (!has_requester()) return;
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -865,7 +852,8 @@ namespace libtorrent
|
|||
try
|
||||
{
|
||||
entry const& warning = e["warning message"];
|
||||
cb->tracker_warning(warning.string());
|
||||
if (has_requester())
|
||||
requester().tracker_warning(warning.string());
|
||||
}
|
||||
catch(type_error const&) {}
|
||||
|
||||
|
@ -879,7 +867,7 @@ namespace libtorrent
|
|||
entry scrape_data = e["files"][ih];
|
||||
int complete = scrape_data["complete"].integer();
|
||||
int incomplete = scrape_data["incomplete"].integer();
|
||||
cb->tracker_response(tracker_request(), peer_list, 0, complete
|
||||
requester().tracker_response(tracker_request(), peer_list, 0, complete
|
||||
, incomplete);
|
||||
return;
|
||||
}
|
||||
|
@ -896,7 +884,12 @@ namespace libtorrent
|
|||
|
||||
peer_entry p;
|
||||
p.pid.clear();
|
||||
p.ip = detail::read_v4_address(i).to_string();
|
||||
std::stringstream ip_str;
|
||||
ip_str << (int)detail::read_uint8(i) << ".";
|
||||
ip_str << (int)detail::read_uint8(i) << ".";
|
||||
ip_str << (int)detail::read_uint8(i) << ".";
|
||||
ip_str << (int)detail::read_uint8(i);
|
||||
p.ip = ip_str.str();
|
||||
p.port = detail::read_uint16(i);
|
||||
peer_list.push_back(p);
|
||||
}
|
||||
|
@ -911,22 +904,6 @@ namespace libtorrent
|
|||
}
|
||||
}
|
||||
|
||||
if (entry const* ipv6_peers = e.find_key("peers6"))
|
||||
{
|
||||
std::string const& peers = ipv6_peers->string();
|
||||
for (std::string::const_iterator i = peers.begin();
|
||||
i != peers.end();)
|
||||
{
|
||||
if (std::distance(i, peers.end()) < 18) break;
|
||||
|
||||
peer_entry p;
|
||||
p.pid.clear();
|
||||
p.ip = detail::read_v6_address(i).to_string();
|
||||
p.port = detail::read_uint16(i);
|
||||
peer_list.push_back(p);
|
||||
}
|
||||
}
|
||||
|
||||
// look for optional scrape info
|
||||
int complete = -1;
|
||||
int incomplete = -1;
|
||||
|
@ -937,16 +914,16 @@ namespace libtorrent
|
|||
try { incomplete = e["incomplete"].integer(); }
|
||||
catch(type_error&) {}
|
||||
|
||||
cb->tracker_response(tracker_request(), peer_list, interval, complete
|
||||
requester().tracker_response(tracker_request(), peer_list, interval, complete
|
||||
, incomplete);
|
||||
}
|
||||
catch(type_error& e)
|
||||
{
|
||||
cb->tracker_request_error(tracker_request(), m_parser.status_code(), e.what());
|
||||
requester().tracker_request_error(tracker_request(), m_parser.status_code(), e.what());
|
||||
}
|
||||
catch(std::runtime_error& e)
|
||||
{
|
||||
cb->tracker_request_error(tracker_request(), m_parser.status_code(), e.what());
|
||||
requester().tracker_request_error(tracker_request(), m_parser.status_code(), e.what());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue