mirror of
https://git.deluge-torrent.org/deluge
synced 2025-08-05 07:58:38 +00:00
libtorrent sync 1592
This commit is contained in:
parent
d44632f0a9
commit
b2fe562dd4
133 changed files with 4077 additions and 3744 deletions
|
@ -25,6 +25,8 @@ extern char const* peer_error_alert_doc;
|
||||||
extern char const* invalid_request_alert_doc;
|
extern char const* invalid_request_alert_doc;
|
||||||
extern char const* peer_request_doc;
|
extern char const* peer_request_doc;
|
||||||
extern char const* torrent_finished_alert_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_failed_alert_doc;
|
||||||
extern char const* metadata_received_alert_doc;
|
extern char const* metadata_received_alert_doc;
|
||||||
extern char const* fastresume_rejected_alert_doc;
|
extern char const* fastresume_rejected_alert_doc;
|
||||||
|
@ -141,6 +143,17 @@ void bind_alert()
|
||||||
.def_readonly("handle", &torrent_finished_alert::handle)
|
.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>(
|
class_<metadata_failed_alert, bases<alert>, noncopyable>(
|
||||||
"metadata_failed_alert", metadata_failed_alert_doc, no_init
|
"metadata_failed_alert", metadata_failed_alert_doc, no_init
|
||||||
)
|
)
|
||||||
|
|
|
@ -257,6 +257,17 @@ char const* torrent_finished_alert_doc =
|
||||||
"It contains a `torrent_handle` to the torrent in question. This alert\n"
|
"It contains a `torrent_handle` to the torrent in question. This alert\n"
|
||||||
"is generated as severity level `alert.severity_levels.info`.";
|
"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 =
|
char const* metadata_failed_alert_doc =
|
||||||
"This alert is generated when the metadata has been completely\n"
|
"This alert is generated when the metadata has been completely\n"
|
||||||
"received and the info-hash failed to match it. i.e. the\n"
|
"received and the info-hash failed to match it. i.e. the\n"
|
||||||
|
|
|
@ -142,7 +142,6 @@ void bind_extensions()
|
||||||
// TODO move to it's own file
|
// TODO move to it's own file
|
||||||
class_<peer_connection, boost::noncopyable>("peer_connection", no_init);
|
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_ut_pex_plugin", create_ut_pex_plugin);
|
||||||
def("create_metadata_plugin", create_metadata_plugin);
|
def("create_metadata_plugin", create_metadata_plugin);
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,11 +86,10 @@ namespace
|
||||||
|
|
||||||
torrent_handle add_torrent(session& s, torrent_info const& ti
|
torrent_handle add_torrent(session& s, torrent_info const& ti
|
||||||
, boost::filesystem::path const& save, entry const& resume
|
, boost::filesystem::path const& save, entry const& resume
|
||||||
, bool compact, int block_size)
|
, bool compact, bool paused)
|
||||||
{
|
{
|
||||||
allow_threading_guard guard;
|
allow_threading_guard guard;
|
||||||
return s.add_torrent(ti, save, resume, compact, block_size
|
return s.add_torrent(ti, save, resume, compact, paused, default_storage_constructor);
|
||||||
, default_storage_constructor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace unnamed
|
} // namespace unnamed
|
||||||
|
@ -175,7 +174,7 @@ void bind_session()
|
||||||
"add_torrent", &add_torrent
|
"add_torrent", &add_torrent
|
||||||
, (
|
, (
|
||||||
arg("torrent_info"), "save_path", arg("resume_data") = entry()
|
arg("torrent_info"), "save_path", arg("resume_data") = entry()
|
||||||
, arg("compact_mode") = true, arg("block_size") = 16 * 1024
|
, arg("compact_mode") = true, arg("paused") = false
|
||||||
)
|
)
|
||||||
, session_add_torrent_doc
|
, session_add_torrent_doc
|
||||||
)
|
)
|
||||||
|
|
|
@ -16,7 +16,6 @@ namespace
|
||||||
return i.trackers().begin();
|
return i.trackers().begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<announce_entry>::const_iterator end_trackers(torrent_info& i)
|
std::vector<announce_entry>::const_iterator end_trackers(torrent_info& i)
|
||||||
{
|
{
|
||||||
return i.trackers().end();
|
return i.trackers().end();
|
||||||
|
@ -41,6 +40,29 @@ namespace
|
||||||
return result;
|
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
|
} // namespace unnamed
|
||||||
|
|
||||||
void bind_torrent_info()
|
void bind_torrent_info()
|
||||||
|
@ -71,9 +93,9 @@ void bind_torrent_info()
|
||||||
.def("hash_for_piece", &torrent_info::hash_for_piece, copy)
|
.def("hash_for_piece", &torrent_info::hash_for_piece, copy)
|
||||||
.def("piece_size", &torrent_info::piece_size)
|
.def("piece_size", &torrent_info::piece_size)
|
||||||
|
|
||||||
.def("num_files", &torrent_info::num_files)
|
.def("num_files", &torrent_info::num_files, (arg("storage")=false))
|
||||||
.def("file_at", &torrent_info::file_at, return_internal_reference<>())
|
.def("file_at", &torrent_info::file_at, return_internal_reference<>())
|
||||||
.def("files", range(&torrent_info::begin_files, &torrent_info::end_files))
|
.def("files", &files, (arg("storage")=false))
|
||||||
|
|
||||||
.def("priv", &torrent_info::priv)
|
.def("priv", &torrent_info::priv)
|
||||||
.def("set_priv", &torrent_info::set_priv)
|
.def("set_priv", &torrent_info::set_priv)
|
||||||
|
@ -84,7 +106,6 @@ void bind_torrent_info()
|
||||||
.def("add_node", &add_node)
|
.def("add_node", &add_node)
|
||||||
.def("nodes", &nodes)
|
.def("nodes", &nodes)
|
||||||
;
|
;
|
||||||
|
|
||||||
class_<file_entry>("file_entry")
|
class_<file_entry>("file_entry")
|
||||||
.add_property(
|
.add_property(
|
||||||
"path"
|
"path"
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
/basic_datagram_socket.hpp/1.40/Thu Jan 4 05:44:43 2007//
|
|
||||||
/basic_deadline_timer.hpp/1.23/Sun May 20 00:49:02 2007//
|
|
||||||
/basic_io_object.hpp/1.8/Thu Jan 4 05:44:43 2007//
|
|
||||||
/basic_socket.hpp/1.16/Mon Jan 8 22:12:45 2007//
|
|
||||||
/basic_socket_acceptor.hpp/1.58/Fri Feb 9 05:47:48 2007//
|
|
||||||
/basic_socket_iostream.hpp/1.8/Thu Jan 18 11:41:36 2007//
|
|
||||||
/basic_socket_streambuf.hpp/1.6/Thu Jan 18 11:41:36 2007//
|
|
||||||
/basic_stream_socket.hpp/1.69/Mon Jan 8 22:12:45 2007//
|
|
||||||
/basic_streambuf.hpp/1.12/Thu Jan 4 10:23:31 2007//
|
|
||||||
/buffer.hpp/1.23/Thu Jun 21 14:03:36 2007//
|
|
||||||
/buffered_read_stream.hpp/1.17/Thu Jan 4 05:44:43 2007//
|
|
||||||
/buffered_read_stream_fwd.hpp/1.5/Thu Jan 4 05:44:43 2007//
|
|
||||||
/buffered_stream.hpp/1.32/Thu Jan 4 05:44:43 2007//
|
|
||||||
/buffered_stream_fwd.hpp/1.9/Thu Jan 4 05:44:43 2007//
|
|
||||||
/buffered_write_stream.hpp/1.17/Thu Jan 4 05:44:43 2007//
|
|
||||||
/buffered_write_stream_fwd.hpp/1.5/Thu Jan 4 05:44:43 2007//
|
|
||||||
/completion_condition.hpp/1.5/Thu Jan 4 05:44:43 2007//
|
|
||||||
/datagram_socket_service.hpp/1.34/Mon Jan 8 22:12:45 2007//
|
|
||||||
/deadline_timer.hpp/1.6/Thu Jan 4 05:44:43 2007//
|
|
||||||
/deadline_timer_service.hpp/1.29/Mon Jan 8 02:47:13 2007//
|
|
||||||
/error.hpp/1.39/Mon Jan 8 22:12:45 2007//
|
|
||||||
/error_code.hpp/1.4/Mon Jan 8 22:12:45 2007//
|
|
||||||
/handler_alloc_hook.hpp/1.11/Thu Jan 4 05:44:43 2007//
|
|
||||||
/handler_invoke_hook.hpp/1.3/Thu Jan 4 05:44:43 2007//
|
|
||||||
/io_service.hpp/1.24/Sun May 20 00:49:02 2007//
|
|
||||||
/is_read_buffered.hpp/1.6/Thu Jan 4 05:44:43 2007//
|
|
||||||
/is_write_buffered.hpp/1.6/Thu Jan 4 05:44:43 2007//
|
|
||||||
/placeholders.hpp/1.10/Thu Jan 4 05:44:43 2007//
|
|
||||||
/read.hpp/1.22/Thu Jan 4 05:44:43 2007//
|
|
||||||
/read_until.hpp/1.8/Thu Jan 4 05:44:44 2007//
|
|
||||||
/socket_acceptor_service.hpp/1.34/Fri Feb 9 05:47:48 2007//
|
|
||||||
/socket_base.hpp/1.23/Mon Jan 8 23:45:36 2007//
|
|
||||||
/ssl.hpp/1.4/Thu Jan 4 05:44:44 2007//
|
|
||||||
/strand.hpp/1.6/Tue May 8 13:13:55 2007//
|
|
||||||
/stream_socket_service.hpp/1.35/Mon Jan 8 22:12:46 2007//
|
|
||||||
/streambuf.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
|
||||||
/system_error.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
|
||||||
/thread.hpp/1.15/Thu Jan 4 05:44:44 2007//
|
|
||||||
/time_traits.hpp/1.9/Thu Jan 4 05:44:44 2007//
|
|
||||||
/version.hpp/1.1/Tue May 8 12:17:36 2007//
|
|
||||||
/write.hpp/1.21/Thu Jan 4 05:44:44 2007//
|
|
||||||
D/detail////
|
|
||||||
D/impl////
|
|
||||||
D/ip////
|
|
||||||
D/ssl////
|
|
|
@ -1 +0,0 @@
|
||||||
asio/include/asio
|
|
|
@ -1 +0,0 @@
|
||||||
:pserver:anonymous@asio.cvs.sourceforge.net:/cvsroot/asio
|
|
|
@ -238,6 +238,9 @@ public:
|
||||||
* with the asio::error::operation_aborted error.
|
* with the asio::error::operation_aborted error.
|
||||||
*
|
*
|
||||||
* @throws asio::system_error Thrown on failure.
|
* @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()
|
void close()
|
||||||
{
|
{
|
||||||
|
@ -265,6 +268,9 @@ public:
|
||||||
* // An error occurred.
|
* // An error occurred.
|
||||||
* }
|
* }
|
||||||
* @endcode
|
* @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)
|
asio::error_code close(asio::error_code& ec)
|
||||||
{
|
{
|
||||||
|
|
|
@ -542,9 +542,10 @@ inline const_buffers_1 buffer(const PodType (&data)[N],
|
||||||
? N * sizeof(PodType) : max_size_in_bytes));
|
? N * sizeof(PodType) : max_size_in_bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582)) \
|
||||||
|
|| BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||||
|
|
||||||
// Borland C++ thinks the overloads:
|
// Borland C++ and Sun Studio think the overloads:
|
||||||
//
|
//
|
||||||
// unspecified buffer(boost::array<PodType, N>& array ...);
|
// unspecified buffer(boost::array<PodType, N>& array ...);
|
||||||
//
|
//
|
||||||
|
@ -610,6 +611,7 @@ buffer(boost::array<PodType, N>& data, std::size_t max_size_in_bytes)
|
||||||
}
|
}
|
||||||
|
|
||||||
#else // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
#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.
|
/// Create a new modifiable buffer that represents the given POD array.
|
||||||
template <typename PodType, std::size_t N>
|
template <typename PodType, std::size_t N>
|
||||||
|
@ -650,6 +652,7 @@ inline const_buffers_1 buffer(boost::array<const PodType, N>& data,
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
#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.
|
/// Create a new non-modifiable buffer that represents the given POD array.
|
||||||
template <typename PodType, std::size_t N>
|
template <typename PodType, std::size_t N>
|
||||||
|
|
|
@ -71,6 +71,28 @@ private:
|
||||||
/// Return a completion condition function object that indicates that a read or
|
/// Return a completion condition function object that indicates that a read or
|
||||||
/// write operation should continue until all of the data has been transferred,
|
/// write operation should continue until all of the data has been transferred,
|
||||||
/// or until an error occurs.
|
/// 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)
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
unspecified transfer_all();
|
unspecified transfer_all();
|
||||||
#else
|
#else
|
||||||
|
@ -83,6 +105,28 @@ inline detail::transfer_all_t transfer_all()
|
||||||
/// Return a completion condition function object that indicates that a read or
|
/// Return a completion condition function object that indicates that a read or
|
||||||
/// write operation should continue until a minimum number of bytes has been
|
/// write operation should continue until a minimum number of bytes has been
|
||||||
/// transferred, or until an error occurs.
|
/// 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)
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
unspecified transfer_at_least(std::size_t minimum);
|
unspecified transfer_at_least(std::size_t minimum);
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
/bind_handler.hpp/1.18/Thu Jan 4 05:44:44 2007//
|
|
||||||
/buffer_resize_guard.hpp/1.9/Thu Jan 4 05:44:44 2007//
|
|
||||||
/buffered_stream_storage.hpp/1.5/Thu Jan 4 05:44:44 2007//
|
|
||||||
/call_stack.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
|
||||||
/const_buffers_iterator.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
|
||||||
/consuming_buffers.hpp/1.7/Sat Jan 13 13:41:09 2007//
|
|
||||||
/deadline_timer_service.hpp/1.7/Mon Jan 8 02:47:13 2007//
|
|
||||||
/epoll_reactor.hpp/1.40/Thu Jan 4 05:44:44 2007//
|
|
||||||
/epoll_reactor_fwd.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
|
||||||
/event.hpp/1.13/Thu Jan 4 05:44:44 2007//
|
|
||||||
/fd_set_adapter.hpp/1.5/Thu Jan 4 05:44:44 2007//
|
|
||||||
/handler_alloc_helpers.hpp/1.8/Thu Jan 4 05:44:44 2007//
|
|
||||||
/handler_invoke_helpers.hpp/1.2/Thu Jan 4 05:44:44 2007//
|
|
||||||
/hash_map.hpp/1.19/Thu Mar 22 21:13:13 2007//
|
|
||||||
/io_control.hpp/1.5/Thu Jan 4 05:44:44 2007//
|
|
||||||
/kqueue_reactor.hpp/1.30/Thu Mar 22 21:08:02 2007//
|
|
||||||
/kqueue_reactor_fwd.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
|
||||||
/local_free_on_block_exit.hpp/1.2/Thu Jan 4 05:44:44 2007//
|
|
||||||
/mutex.hpp/1.13/Thu Jan 4 05:44:44 2007//
|
|
||||||
/noncopyable.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
|
||||||
/null_event.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
|
||||||
/null_mutex.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
|
||||||
/null_signal_blocker.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
|
||||||
/null_thread.hpp/1.5/Mon Jan 8 22:12:46 2007//
|
|
||||||
/null_tss_ptr.hpp/1.3/Thu Jan 4 05:44:44 2007//
|
|
||||||
/old_win_sdk_compat.hpp/1.5/Sat May 12 08:16:25 2007//
|
|
||||||
/pipe_select_interrupter.hpp/1.11/Thu Jan 4 05:44:44 2007//
|
|
||||||
/pop_options.hpp/1.10/Thu Jan 4 05:44:44 2007//
|
|
||||||
/posix_event.hpp/1.16/Thu Jan 4 05:44:44 2007//
|
|
||||||
/posix_fd_set_adapter.hpp/1.4/Tue Feb 13 07:13:29 2007//
|
|
||||||
/posix_mutex.hpp/1.15/Thu Jan 4 05:44:44 2007//
|
|
||||||
/posix_signal_blocker.hpp/1.10/Sat Feb 17 22:57:37 2007//
|
|
||||||
/posix_thread.hpp/1.17/Thu Jan 4 05:44:45 2007//
|
|
||||||
/posix_tss_ptr.hpp/1.10/Thu Jan 4 05:44:45 2007//
|
|
||||||
/push_options.hpp/1.16/Thu Jan 4 05:44:45 2007//
|
|
||||||
/reactive_socket_service.hpp/1.59/Sun May 13 23:00:01 2007//
|
|
||||||
/reactor_op_queue.hpp/1.24/Thu Jan 4 05:44:45 2007//
|
|
||||||
/resolver_service.hpp/1.11/Thu Jan 4 09:06:56 2007//
|
|
||||||
/scoped_lock.hpp/1.9/Thu Jan 4 05:44:45 2007//
|
|
||||||
/select_interrupter.hpp/1.10/Thu Jan 4 05:44:45 2007//
|
|
||||||
/select_reactor.hpp/1.49/Thu Jan 4 05:44:45 2007//
|
|
||||||
/select_reactor_fwd.hpp/1.2/Thu Jan 4 05:44:45 2007//
|
|
||||||
/service_base.hpp/1.2/Thu Jan 4 05:44:45 2007//
|
|
||||||
/service_id.hpp/1.2/Thu Jan 4 05:44:45 2007//
|
|
||||||
/service_registry.hpp/1.19/Tue Feb 13 12:06:43 2007//
|
|
||||||
/service_registry_fwd.hpp/1.2/Thu Jan 4 05:44:45 2007//
|
|
||||||
/signal_blocker.hpp/1.10/Thu Jan 4 05:44:45 2007//
|
|
||||||
/signal_init.hpp/1.11/Thu Jan 4 05:44:45 2007//
|
|
||||||
/socket_holder.hpp/1.10/Thu Jan 4 05:44:45 2007//
|
|
||||||
/socket_ops.hpp/1.74/Mon May 21 12:34:39 2007//
|
|
||||||
/socket_option.hpp/1.7/Sat Feb 17 22:57:37 2007//
|
|
||||||
/socket_select_interrupter.hpp/1.15/Thu May 10 23:48:52 2007//
|
|
||||||
/socket_types.hpp/1.41/Sun May 13 07:59:21 2007//
|
|
||||||
/strand_service.hpp/1.15/Thu Jan 4 05:44:45 2007//
|
|
||||||
/task_io_service.hpp/1.18/Wed Feb 14 13:26:21 2007//
|
|
||||||
/task_io_service_fwd.hpp/1.2/Thu Jan 4 05:44:45 2007//
|
|
||||||
/thread.hpp/1.13/Thu Jan 4 05:44:45 2007//
|
|
||||||
/throw_error.hpp/1.3/Thu Jan 4 05:44:45 2007//
|
|
||||||
/timer_queue.hpp/1.6/Sun Apr 22 07:07:15 2007//
|
|
||||||
/timer_queue_base.hpp/1.2/Thu Jan 4 05:44:45 2007//
|
|
||||||
/tss_ptr.hpp/1.8/Thu Jan 4 05:44:45 2007//
|
|
||||||
/win_event.hpp/1.14/Thu Jan 4 05:44:45 2007//
|
|
||||||
/win_fd_set_adapter.hpp/1.4/Thu Jan 4 05:44:45 2007//
|
|
||||||
/win_iocp_io_service.hpp/1.24/Mon Jan 8 01:09:14 2007//
|
|
||||||
/win_iocp_io_service_fwd.hpp/1.4/Thu Jan 4 05:44:45 2007//
|
|
||||||
/win_iocp_operation.hpp/1.16/Thu Jan 4 05:44:45 2007//
|
|
||||||
/win_iocp_socket_service.hpp/1.75/Sat May 12 09:07:32 2007//
|
|
||||||
/win_mutex.hpp/1.16/Thu Jan 4 05:44:45 2007//
|
|
||||||
/win_signal_blocker.hpp/1.9/Thu Jan 4 05:44:45 2007//
|
|
||||||
/win_thread.hpp/1.20/Thu Jan 4 05:44:45 2007//
|
|
||||||
/win_tss_ptr.hpp/1.10/Thu Jan 4 05:44:45 2007//
|
|
||||||
/winsock_init.hpp/1.16/Thu Jan 4 05:44:45 2007//
|
|
||||||
/wrapped_handler.hpp/1.11/Thu Jan 4 05:44:45 2007//
|
|
||||||
D
|
|
|
@ -1 +0,0 @@
|
||||||
asio/include/asio/detail
|
|
|
@ -1 +0,0 @@
|
||||||
:pserver:anonymous@asio.cvs.sourceforge.net:/cvsroot/asio
|
|
|
@ -157,7 +157,8 @@ public:
|
||||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno, asio::native_ecat);
|
asio::error_code ec(errno,
|
||||||
|
asio::error::system_category);
|
||||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,7 +191,8 @@ public:
|
||||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno, asio::native_ecat);
|
asio::error_code ec(errno,
|
||||||
|
asio::error::system_category);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -219,7 +221,8 @@ public:
|
||||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno, asio::native_ecat);
|
asio::error_code ec(errno,
|
||||||
|
asio::error::system_category);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -250,7 +253,8 @@ public:
|
||||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno, asio::native_ecat);
|
asio::error_code ec(errno,
|
||||||
|
asio::error::system_category);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
|
@ -331,7 +335,10 @@ public:
|
||||||
std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token)
|
std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token)
|
||||||
{
|
{
|
||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
return timer_queue.cancel_timer(token);
|
std::size_t n = timer_queue.cancel_timer(token);
|
||||||
|
if (n > 0)
|
||||||
|
interrupter_.interrupt();
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -347,16 +354,13 @@ private:
|
||||||
read_op_queue_.dispatch_cancellations();
|
read_op_queue_.dispatch_cancellations();
|
||||||
write_op_queue_.dispatch_cancellations();
|
write_op_queue_.dispatch_cancellations();
|
||||||
except_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.
|
// Check if the thread is supposed to stop.
|
||||||
if (stop_thread_)
|
if (stop_thread_)
|
||||||
{
|
{
|
||||||
// Clean up operations. We must not hold the lock since the operations may
|
cleanup_operations_and_timers(lock);
|
||||||
// make calls back into this reactor.
|
|
||||||
lock.unlock();
|
|
||||||
read_op_queue_.cleanup_operations();
|
|
||||||
write_op_queue_.cleanup_operations();
|
|
||||||
except_op_queue_.cleanup_operations();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,12 +369,7 @@ private:
|
||||||
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
|
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
|
||||||
&& except_op_queue_.empty() && all_timer_queues_are_empty())
|
&& except_op_queue_.empty() && all_timer_queues_are_empty())
|
||||||
{
|
{
|
||||||
// Clean up operations. We must not hold the lock since the operations may
|
cleanup_operations_and_timers(lock);
|
||||||
// make calls back into this reactor.
|
|
||||||
lock.unlock();
|
|
||||||
read_op_queue_.cleanup_operations();
|
|
||||||
write_op_queue_.cleanup_operations();
|
|
||||||
except_op_queue_.cleanup_operations();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,20 +396,6 @@ private:
|
||||||
interrupter_.reset();
|
interrupter_.reset();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
|
||||||
if (events[i].events & (EPOLLERR | EPOLLHUP))
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
|
|
||||||
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_reads = false;
|
||||||
bool more_writes = false;
|
bool more_writes = false;
|
||||||
|
@ -419,17 +404,17 @@ private:
|
||||||
|
|
||||||
// Exception operations must be processed first to ensure that any
|
// Exception operations must be processed first to ensure that any
|
||||||
// out-of-band data is read before normal data.
|
// out-of-band data is read before normal data.
|
||||||
if (events[i].events & EPOLLPRI)
|
if (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP))
|
||||||
more_except = except_op_queue_.dispatch_operation(descriptor, ec);
|
more_except = except_op_queue_.dispatch_operation(descriptor, ec);
|
||||||
else
|
else
|
||||||
more_except = except_op_queue_.has_operation(descriptor);
|
more_except = except_op_queue_.has_operation(descriptor);
|
||||||
|
|
||||||
if (events[i].events & EPOLLIN)
|
if (events[i].events & (EPOLLIN | EPOLLERR | EPOLLHUP))
|
||||||
more_reads = read_op_queue_.dispatch_operation(descriptor, ec);
|
more_reads = read_op_queue_.dispatch_operation(descriptor, ec);
|
||||||
else
|
else
|
||||||
more_reads = read_op_queue_.has_operation(descriptor);
|
more_reads = read_op_queue_.has_operation(descriptor);
|
||||||
|
|
||||||
if (events[i].events & EPOLLOUT)
|
if (events[i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP))
|
||||||
more_writes = write_op_queue_.dispatch_operation(descriptor, ec);
|
more_writes = write_op_queue_.dispatch_operation(descriptor, ec);
|
||||||
else
|
else
|
||||||
more_writes = write_op_queue_.has_operation(descriptor);
|
more_writes = write_op_queue_.has_operation(descriptor);
|
||||||
|
@ -446,31 +431,29 @@ private:
|
||||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
{
|
{
|
||||||
ec = asio::error_code(errno, asio::native_ecat);
|
ec = asio::error_code(errno,
|
||||||
|
asio::error::system_category);
|
||||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
read_op_queue_.dispatch_cancellations();
|
read_op_queue_.dispatch_cancellations();
|
||||||
write_op_queue_.dispatch_cancellations();
|
write_op_queue_.dispatch_cancellations();
|
||||||
except_op_queue_.dispatch_cancellations();
|
except_op_queue_.dispatch_cancellations();
|
||||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||||
|
{
|
||||||
timer_queues_[i]->dispatch_timers();
|
timer_queues_[i]->dispatch_timers();
|
||||||
|
timer_queues_[i]->dispatch_cancellations();
|
||||||
|
}
|
||||||
|
|
||||||
// Issue any pending cancellations.
|
// Issue any pending cancellations.
|
||||||
for (size_t i = 0; i < pending_cancellations_.size(); ++i)
|
for (size_t i = 0; i < pending_cancellations_.size(); ++i)
|
||||||
cancel_ops_unlocked(pending_cancellations_[i]);
|
cancel_ops_unlocked(pending_cancellations_[i]);
|
||||||
pending_cancellations_.clear();
|
pending_cancellations_.clear();
|
||||||
|
|
||||||
// Clean up operations. We must not hold the lock since the operations may
|
cleanup_operations_and_timers(lock);
|
||||||
// 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.
|
// Run the select loop in the thread.
|
||||||
|
@ -507,8 +490,10 @@ private:
|
||||||
int fd = epoll_create(epoll_size);
|
int fd = epoll_create(epoll_size);
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{
|
{
|
||||||
boost::throw_exception(asio::system_error(
|
boost::throw_exception(
|
||||||
asio::error_code(errno, asio::native_ecat),
|
asio::system_error(
|
||||||
|
asio::error_code(errno,
|
||||||
|
asio::error::system_category),
|
||||||
"epoll"));
|
"epoll"));
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
|
@ -566,6 +551,22 @@ private:
|
||||||
interrupter_.interrupt();
|
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.
|
// Mutex to protect access to internal data.
|
||||||
asio::detail::mutex mutex_;
|
asio::detail::mutex mutex_;
|
||||||
|
|
||||||
|
@ -590,6 +591,10 @@ private:
|
||||||
// The timer queues.
|
// The timer queues.
|
||||||
std::vector<timer_queue_base*> 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.
|
// The descriptors that are pending cancellation.
|
||||||
std::vector<socket_type> pending_cancellations_;
|
std::vector<socket_type> pending_cancellations_;
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,8 @@ public:
|
||||||
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0);
|
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0);
|
||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno, asio::native_ecat);
|
asio::error_code ec(errno,
|
||||||
|
asio::error::system_category);
|
||||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,7 +177,8 @@ public:
|
||||||
EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
|
EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
|
||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno, asio::native_ecat);
|
asio::error_code ec(errno,
|
||||||
|
asio::error::system_category);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,7 +203,8 @@ public:
|
||||||
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0);
|
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0);
|
||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno, asio::native_ecat);
|
asio::error_code ec(errno,
|
||||||
|
asio::error::system_category);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,7 +227,8 @@ public:
|
||||||
EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
|
EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
|
||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno, asio::native_ecat);
|
asio::error_code ec(errno,
|
||||||
|
asio::error::system_category);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,7 +242,8 @@ public:
|
||||||
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0);
|
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, EV_OOBAND, 0, 0);
|
||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
asio::error_code ec(errno, asio::native_ecat);
|
asio::error_code ec(errno,
|
||||||
|
asio::error::system_category);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||||
}
|
}
|
||||||
|
@ -321,7 +326,10 @@ public:
|
||||||
std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token)
|
std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token)
|
||||||
{
|
{
|
||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
return timer_queue.cancel_timer(token);
|
std::size_t n = timer_queue.cancel_timer(token);
|
||||||
|
if (n > 0)
|
||||||
|
interrupter_.interrupt();
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -337,16 +345,13 @@ private:
|
||||||
read_op_queue_.dispatch_cancellations();
|
read_op_queue_.dispatch_cancellations();
|
||||||
write_op_queue_.dispatch_cancellations();
|
write_op_queue_.dispatch_cancellations();
|
||||||
except_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.
|
// Check if the thread is supposed to stop.
|
||||||
if (stop_thread_)
|
if (stop_thread_)
|
||||||
{
|
{
|
||||||
// Clean up operations. We must not hold the lock since the operations may
|
cleanup_operations_and_timers(lock);
|
||||||
// make calls back into this reactor.
|
|
||||||
lock.unlock();
|
|
||||||
read_op_queue_.cleanup_operations();
|
|
||||||
write_op_queue_.cleanup_operations();
|
|
||||||
except_op_queue_.cleanup_operations();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,12 +360,7 @@ private:
|
||||||
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
|
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
|
||||||
&& except_op_queue_.empty() && all_timer_queues_are_empty())
|
&& except_op_queue_.empty() && all_timer_queues_are_empty())
|
||||||
{
|
{
|
||||||
// Clean up operations. We must not hold the lock since the operations may
|
cleanup_operations_and_timers(lock);
|
||||||
// make calls back into this reactor.
|
|
||||||
lock.unlock();
|
|
||||||
read_op_queue_.cleanup_operations();
|
|
||||||
write_op_queue_.cleanup_operations();
|
|
||||||
except_op_queue_.cleanup_operations();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -397,7 +397,7 @@ private:
|
||||||
if (events[i].flags & EV_ERROR)
|
if (events[i].flags & EV_ERROR)
|
||||||
{
|
{
|
||||||
asio::error_code error(
|
asio::error_code error(
|
||||||
events[i].data, asio::native_ecat);
|
events[i].data, asio::error::system_category);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, error);
|
except_op_queue_.dispatch_all_operations(descriptor, error);
|
||||||
read_op_queue_.dispatch_all_operations(descriptor, error);
|
read_op_queue_.dispatch_all_operations(descriptor, error);
|
||||||
}
|
}
|
||||||
|
@ -427,7 +427,8 @@ private:
|
||||||
EV_SET(&event, descriptor, EVFILT_READ, EV_DELETE, 0, 0, 0);
|
EV_SET(&event, descriptor, EVFILT_READ, EV_DELETE, 0, 0, 0);
|
||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
asio::error_code error(errno, asio::native_ecat);
|
asio::error_code error(errno,
|
||||||
|
asio::error::system_category);
|
||||||
except_op_queue_.dispatch_all_operations(descriptor, error);
|
except_op_queue_.dispatch_all_operations(descriptor, error);
|
||||||
read_op_queue_.dispatch_all_operations(descriptor, error);
|
read_op_queue_.dispatch_all_operations(descriptor, error);
|
||||||
}
|
}
|
||||||
|
@ -439,7 +440,7 @@ private:
|
||||||
if (events[i].flags & EV_ERROR)
|
if (events[i].flags & EV_ERROR)
|
||||||
{
|
{
|
||||||
asio::error_code error(
|
asio::error_code error(
|
||||||
events[i].data, asio::native_ecat);
|
events[i].data, asio::error::system_category);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, error);
|
write_op_queue_.dispatch_all_operations(descriptor, error);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -456,7 +457,8 @@ private:
|
||||||
EV_SET(&event, descriptor, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
|
EV_SET(&event, descriptor, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
|
||||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||||
{
|
{
|
||||||
asio::error_code error(errno, asio::native_ecat);
|
asio::error_code error(errno,
|
||||||
|
asio::error::system_category);
|
||||||
write_op_queue_.dispatch_all_operations(descriptor, error);
|
write_op_queue_.dispatch_all_operations(descriptor, error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -466,19 +468,17 @@ private:
|
||||||
write_op_queue_.dispatch_cancellations();
|
write_op_queue_.dispatch_cancellations();
|
||||||
except_op_queue_.dispatch_cancellations();
|
except_op_queue_.dispatch_cancellations();
|
||||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||||
|
{
|
||||||
timer_queues_[i]->dispatch_timers();
|
timer_queues_[i]->dispatch_timers();
|
||||||
|
timer_queues_[i]->dispatch_cancellations();
|
||||||
|
}
|
||||||
|
|
||||||
// Issue any pending cancellations.
|
// Issue any pending cancellations.
|
||||||
for (std::size_t i = 0; i < pending_cancellations_.size(); ++i)
|
for (std::size_t i = 0; i < pending_cancellations_.size(); ++i)
|
||||||
cancel_ops_unlocked(pending_cancellations_[i]);
|
cancel_ops_unlocked(pending_cancellations_[i]);
|
||||||
pending_cancellations_.clear();
|
pending_cancellations_.clear();
|
||||||
|
|
||||||
// Clean up operations. We must not hold the lock since the operations may
|
cleanup_operations_and_timers(lock);
|
||||||
// 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.
|
// Run the select loop in the thread.
|
||||||
|
@ -512,8 +512,10 @@ private:
|
||||||
int fd = kqueue();
|
int fd = kqueue();
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
{
|
{
|
||||||
boost::throw_exception(asio::system_error(
|
boost::throw_exception(
|
||||||
asio::error_code(errno, asio::native_ecat),
|
asio::system_error(
|
||||||
|
asio::error_code(errno,
|
||||||
|
asio::error::system_category),
|
||||||
"kqueue"));
|
"kqueue"));
|
||||||
}
|
}
|
||||||
return fd;
|
return fd;
|
||||||
|
@ -573,6 +575,22 @@ private:
|
||||||
interrupter_.interrupt();
|
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.
|
// Mutex to protect access to internal data.
|
||||||
asio::detail::mutex mutex_;
|
asio::detail::mutex mutex_;
|
||||||
|
|
||||||
|
@ -597,6 +615,10 @@ private:
|
||||||
// The timer queues.
|
// The timer queues.
|
||||||
std::vector<timer_queue_base*> 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.
|
// The descriptors that are pending cancellation.
|
||||||
std::vector<socket_type> pending_cancellations_;
|
std::vector<socket_type> pending_cancellations_;
|
||||||
|
|
||||||
|
|
|
@ -43,17 +43,20 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signal the event.
|
// Signal the event.
|
||||||
void signal()
|
template <typename Lock>
|
||||||
|
void signal(Lock&)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the event.
|
// Reset the event.
|
||||||
void clear()
|
template <typename Lock>
|
||||||
|
void clear(Lock&)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the event to become signalled.
|
// Wait for the event to become signalled.
|
||||||
void wait()
|
template <typename Lock>
|
||||||
|
void wait(Lock&)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,10 +24,12 @@
|
||||||
#if defined(BOOST_HAS_PTHREADS)
|
#if defined(BOOST_HAS_PTHREADS)
|
||||||
|
|
||||||
#include "asio/detail/push_options.hpp"
|
#include "asio/detail/push_options.hpp"
|
||||||
|
#include <boost/assert.hpp>
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/error.hpp"
|
||||||
#include "asio/system_error.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
|
|
||||||
|
@ -42,21 +44,11 @@ public:
|
||||||
posix_event()
|
posix_event()
|
||||||
: signalled_(false)
|
: signalled_(false)
|
||||||
{
|
{
|
||||||
int error = ::pthread_mutex_init(&mutex_, 0);
|
int error = ::pthread_cond_init(&cond_, 0);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(error, asio::native_ecat),
|
asio::error_code(error, asio::error::system_category),
|
||||||
"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");
|
"event");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -66,37 +58,37 @@ public:
|
||||||
~posix_event()
|
~posix_event()
|
||||||
{
|
{
|
||||||
::pthread_cond_destroy(&cond_);
|
::pthread_cond_destroy(&cond_);
|
||||||
::pthread_mutex_destroy(&mutex_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signal the event.
|
// Signal the event.
|
||||||
void signal()
|
template <typename Lock>
|
||||||
|
void signal(Lock& lock)
|
||||||
{
|
{
|
||||||
::pthread_mutex_lock(&mutex_); // Ignore EINVAL and EDEADLK.
|
BOOST_ASSERT(lock.locked());
|
||||||
|
(void)lock;
|
||||||
signalled_ = true;
|
signalled_ = true;
|
||||||
::pthread_cond_signal(&cond_); // Ignore EINVAL.
|
::pthread_cond_signal(&cond_); // Ignore EINVAL.
|
||||||
::pthread_mutex_unlock(&mutex_); // Ignore EINVAL and EPERM.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the event.
|
// Reset the event.
|
||||||
void clear()
|
template <typename Lock>
|
||||||
|
void clear(Lock& lock)
|
||||||
{
|
{
|
||||||
::pthread_mutex_lock(&mutex_); // Ignore EINVAL and EDEADLK.
|
BOOST_ASSERT(lock.locked());
|
||||||
|
(void)lock;
|
||||||
signalled_ = false;
|
signalled_ = false;
|
||||||
::pthread_mutex_unlock(&mutex_); // Ignore EINVAL and EPERM.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the event to become signalled.
|
// Wait for the event to become signalled.
|
||||||
void wait()
|
template <typename Lock>
|
||||||
|
void wait(Lock& lock)
|
||||||
{
|
{
|
||||||
::pthread_mutex_lock(&mutex_); // Ignore EINVAL and EDEADLK.
|
BOOST_ASSERT(lock.locked());
|
||||||
while (!signalled_)
|
while (!signalled_)
|
||||||
::pthread_cond_wait(&cond_, &mutex_); // Ignore EINVAL.
|
::pthread_cond_wait(&cond_, &lock.mutex().mutex_); // Ignore EINVAL.
|
||||||
::pthread_mutex_unlock(&mutex_); // Ignore EINVAL and EPERM.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::pthread_mutex_t mutex_;
|
|
||||||
::pthread_cond_t cond_;
|
::pthread_cond_t cond_;
|
||||||
bool signalled_;
|
bool signalled_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/error.hpp"
|
||||||
#include "asio/system_error.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
#include "asio/detail/scoped_lock.hpp"
|
#include "asio/detail/scoped_lock.hpp"
|
||||||
|
@ -35,6 +36,8 @@
|
||||||
namespace asio {
|
namespace asio {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
class posix_event;
|
||||||
|
|
||||||
class posix_mutex
|
class posix_mutex
|
||||||
: private noncopyable
|
: private noncopyable
|
||||||
{
|
{
|
||||||
|
@ -48,7 +51,7 @@ public:
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(error, asio::native_ecat),
|
asio::error_code(error, asio::error::system_category),
|
||||||
"mutex");
|
"mutex");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -67,7 +70,7 @@ public:
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(error, asio::native_ecat),
|
asio::error_code(error, asio::error::system_category),
|
||||||
"mutex");
|
"mutex");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -80,13 +83,14 @@ public:
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(error, asio::native_ecat),
|
asio::error_code(error, asio::error::system_category),
|
||||||
"mutex");
|
"mutex");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class posix_event;
|
||||||
::pthread_mutex_t mutex_;
|
::pthread_mutex_t mutex_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/error.hpp"
|
||||||
#include "asio/system_error.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
|
|
||||||
|
@ -52,7 +53,7 @@ public:
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(error, asio::native_ecat),
|
asio::error_code(error, asio::error::system_category),
|
||||||
"thread");
|
"thread");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/error.hpp"
|
||||||
#include "asio/system_error.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ public:
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(error, asio::native_ecat),
|
asio::error_code(error, asio::error::system_category),
|
||||||
"tss");
|
"tss");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,7 +86,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// The maximum number of buffers to support in a single operation.
|
// The maximum number of buffers to support in a single operation.
|
||||||
enum { max_buffers = 16 };
|
enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
|
||||||
|
|
||||||
// Constructor.
|
// Constructor.
|
||||||
reactive_socket_service(asio::io_service& io_service)
|
reactive_socket_service(asio::io_service& io_service)
|
||||||
|
@ -157,7 +157,7 @@ public:
|
||||||
|
|
||||||
if (int err = reactor_.register_descriptor(sock.get()))
|
if (int err = reactor_.register_descriptor(sock.get()))
|
||||||
{
|
{
|
||||||
ec = asio::error_code(err, asio::native_ecat);
|
ec = asio::error_code(err, asio::error::system_category);
|
||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ public:
|
||||||
|
|
||||||
if (int err = reactor_.register_descriptor(native_socket))
|
if (int err = reactor_.register_descriptor(native_socket))
|
||||||
{
|
{
|
||||||
ec = asio::error_code(err, asio::native_ecat);
|
ec = asio::error_code(err, asio::error::system_category);
|
||||||
return ec;
|
return ec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1124,7 +1124,7 @@ public:
|
||||||
bool operator()(const asio::error_code& result)
|
bool operator()(const asio::error_code& result)
|
||||||
{
|
{
|
||||||
// Check whether the operation was successful.
|
// Check whether the operation was successful.
|
||||||
if (result != 0)
|
if (result)
|
||||||
{
|
{
|
||||||
io_service_.post(bind_handler(handler_, result, 0));
|
io_service_.post(bind_handler(handler_, result, 0));
|
||||||
return true;
|
return true;
|
||||||
|
@ -1489,7 +1489,7 @@ public:
|
||||||
if (connect_error)
|
if (connect_error)
|
||||||
{
|
{
|
||||||
ec = asio::error_code(connect_error,
|
ec = asio::error_code(connect_error,
|
||||||
asio::native_ecat);
|
asio::error::system_category);
|
||||||
io_service_.post(bind_handler(handler_, ec));
|
io_service_.post(bind_handler(handler_, ec));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,6 +63,18 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test whether the lock is held.
|
||||||
|
bool locked() const
|
||||||
|
{
|
||||||
|
return locked_;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the underlying mutex.
|
||||||
|
Mutex& mutex()
|
||||||
|
{
|
||||||
|
return mutex_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// The underlying mutex.
|
// The underlying mutex.
|
||||||
Mutex& mutex_;
|
Mutex& mutex_;
|
||||||
|
|
|
@ -229,7 +229,10 @@ public:
|
||||||
std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token)
|
std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token)
|
||||||
{
|
{
|
||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
return timer_queue.cancel_timer(token);
|
std::size_t n = timer_queue.cancel_timer(token);
|
||||||
|
if (n > 0)
|
||||||
|
interrupter_.interrupt();
|
||||||
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -245,16 +248,13 @@ private:
|
||||||
read_op_queue_.dispatch_cancellations();
|
read_op_queue_.dispatch_cancellations();
|
||||||
write_op_queue_.dispatch_cancellations();
|
write_op_queue_.dispatch_cancellations();
|
||||||
except_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.
|
// Check if the thread is supposed to stop.
|
||||||
if (stop_thread_)
|
if (stop_thread_)
|
||||||
{
|
{
|
||||||
// Clean up operations. We must not hold the lock since the operations may
|
cleanup_operations_and_timers(lock);
|
||||||
// make calls back into this reactor.
|
|
||||||
lock.unlock();
|
|
||||||
read_op_queue_.cleanup_operations();
|
|
||||||
write_op_queue_.cleanup_operations();
|
|
||||||
except_op_queue_.cleanup_operations();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,12 +263,7 @@ private:
|
||||||
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
|
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
|
||||||
&& except_op_queue_.empty() && all_timer_queues_are_empty())
|
&& except_op_queue_.empty() && all_timer_queues_are_empty())
|
||||||
{
|
{
|
||||||
// Clean up operations. We must not hold the lock since the operations may
|
cleanup_operations_and_timers(lock);
|
||||||
// make calls back into this reactor.
|
|
||||||
lock.unlock();
|
|
||||||
read_op_queue_.cleanup_operations();
|
|
||||||
write_op_queue_.cleanup_operations();
|
|
||||||
except_op_queue_.cleanup_operations();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,19 +316,17 @@ private:
|
||||||
write_op_queue_.dispatch_cancellations();
|
write_op_queue_.dispatch_cancellations();
|
||||||
}
|
}
|
||||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||||
|
{
|
||||||
timer_queues_[i]->dispatch_timers();
|
timer_queues_[i]->dispatch_timers();
|
||||||
|
timer_queues_[i]->dispatch_cancellations();
|
||||||
|
}
|
||||||
|
|
||||||
// Issue any pending cancellations.
|
// Issue any pending cancellations.
|
||||||
for (size_t i = 0; i < pending_cancellations_.size(); ++i)
|
for (size_t i = 0; i < pending_cancellations_.size(); ++i)
|
||||||
cancel_ops_unlocked(pending_cancellations_[i]);
|
cancel_ops_unlocked(pending_cancellations_[i]);
|
||||||
pending_cancellations_.clear();
|
pending_cancellations_.clear();
|
||||||
|
|
||||||
// Clean up operations. We must not hold the lock since the operations may
|
cleanup_operations_and_timers(lock);
|
||||||
// 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.
|
// Run the select loop in the thread.
|
||||||
|
@ -414,6 +407,22 @@ private:
|
||||||
interrupter_.interrupt();
|
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.
|
// Mutex to protect access to internal data.
|
||||||
asio::detail::mutex mutex_;
|
asio::detail::mutex mutex_;
|
||||||
|
|
||||||
|
@ -435,6 +444,10 @@ private:
|
||||||
// The timer queues.
|
// The timer queues.
|
||||||
std::vector<timer_queue_base*> 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.
|
// The descriptors that are pending cancellation.
|
||||||
std::vector<socket_type> pending_cancellations_;
|
std::vector<socket_type> pending_cancellations_;
|
||||||
|
|
||||||
|
|
|
@ -166,7 +166,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if a service matches the given id.
|
// Check if a service matches the given id.
|
||||||
bool service_id_matches(const asio::io_service::service& service,
|
static bool service_id_matches(
|
||||||
|
const asio::io_service::service& service,
|
||||||
const asio::io_service::id& id)
|
const asio::io_service::id& id)
|
||||||
{
|
{
|
||||||
return service.id_ == &id;
|
return service.id_ == &id;
|
||||||
|
@ -174,7 +175,8 @@ private:
|
||||||
|
|
||||||
// Check if a service matches the given id.
|
// Check if a service matches the given id.
|
||||||
template <typename Service>
|
template <typename Service>
|
||||||
bool service_id_matches(const asio::io_service::service& service,
|
static bool service_id_matches(
|
||||||
|
const asio::io_service::service& service,
|
||||||
const asio::detail::service_id<Service>& /*id*/)
|
const asio::detail::service_id<Service>& /*id*/)
|
||||||
{
|
{
|
||||||
return service.type_info_ != 0 && *service.type_info_ == typeid(Service);
|
return service.type_info_ != 0 && *service.type_info_ == typeid(Service);
|
||||||
|
|
|
@ -52,9 +52,10 @@ inline ReturnType error_wrapper(ReturnType return_value,
|
||||||
asio::error_code& ec)
|
asio::error_code& ec)
|
||||||
{
|
{
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
ec = asio::error_code(WSAGetLastError(), asio::native_ecat);
|
ec = asio::error_code(WSAGetLastError(),
|
||||||
|
asio::error::system_category);
|
||||||
#else
|
#else
|
||||||
ec = asio::error_code(errno, asio::native_ecat);
|
ec = asio::error_code(errno, asio::error::system_category);
|
||||||
#endif
|
#endif
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
@ -923,6 +924,13 @@ inline void gai_free(void* p)
|
||||||
::operator delete(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 };
|
enum { gai_clone_flag = 1 << 30 };
|
||||||
|
|
||||||
inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints,
|
inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints,
|
||||||
|
@ -1292,14 +1300,15 @@ inline int getaddrinfo_emulation(const char* host, const char* service,
|
||||||
if (host != 0 && host[0] != '\0' && hptr->h_name && hptr->h_name[0]
|
if (host != 0 && host[0] != '\0' && hptr->h_name && hptr->h_name[0]
|
||||||
&& (hints.ai_flags & AI_CANONNAME) && canon == 0)
|
&& (hints.ai_flags & AI_CANONNAME) && canon == 0)
|
||||||
{
|
{
|
||||||
canon = gai_alloc<char>(strlen(hptr->h_name) + 1);
|
std::size_t canon_len = strlen(hptr->h_name) + 1;
|
||||||
|
canon = gai_alloc<char>(canon_len);
|
||||||
if (canon == 0)
|
if (canon == 0)
|
||||||
{
|
{
|
||||||
freeaddrinfo_emulation(aihead);
|
freeaddrinfo_emulation(aihead);
|
||||||
socket_ops::freehostent(hptr);
|
socket_ops::freehostent(hptr);
|
||||||
return EAI_MEMORY;
|
return EAI_MEMORY;
|
||||||
}
|
}
|
||||||
strcpy(canon, hptr->h_name);
|
gai_strcpy(canon, hptr->h_name, canon_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an addrinfo structure for each returned address.
|
// Create an addrinfo structure for each returned address.
|
||||||
|
@ -1335,13 +1344,14 @@ inline int getaddrinfo_emulation(const char* host, const char* service,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
aihead->ai_canonname = gai_alloc<char>(strlen(search[0].host) + 1);
|
std::size_t canonname_len = strlen(search[0].host) + 1;
|
||||||
|
aihead->ai_canonname = gai_alloc<char>(canonname_len);
|
||||||
if (aihead->ai_canonname == 0)
|
if (aihead->ai_canonname == 0)
|
||||||
{
|
{
|
||||||
freeaddrinfo_emulation(aihead);
|
freeaddrinfo_emulation(aihead);
|
||||||
return EAI_MEMORY;
|
return EAI_MEMORY;
|
||||||
}
|
}
|
||||||
strcpy(aihead->ai_canonname, search[0].host);
|
gai_strcpy(aihead->ai_canonname, search[0].host, canonname_len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gai_free(canon);
|
gai_free(canon);
|
||||||
|
@ -1424,8 +1434,7 @@ inline asio::error_code getnameinfo_emulation(
|
||||||
*dot = 0;
|
*dot = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*host = '\0';
|
gai_strcpy(host, hptr->h_name, hostlen);
|
||||||
strncat(host, hptr->h_name, hostlen);
|
|
||||||
socket_ops::freehostent(hptr);
|
socket_ops::freehostent(hptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1463,8 +1472,7 @@ inline asio::error_code getnameinfo_emulation(
|
||||||
servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0);
|
servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0);
|
||||||
if (sptr && sptr->s_name && sptr->s_name[0] != '\0')
|
if (sptr && sptr->s_name && sptr->s_name[0] != '\0')
|
||||||
{
|
{
|
||||||
*serv = '\0';
|
gai_strcpy(serv, sptr->s_name, servlen);
|
||||||
strncat(serv, sptr->s_name, servlen);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1504,6 +1512,12 @@ inline asio::error_code translate_addrinfo_error(int error)
|
||||||
case EAI_MEMORY:
|
case EAI_MEMORY:
|
||||||
return asio::error::no_memory;
|
return asio::error::no_memory;
|
||||||
case EAI_NONAME:
|
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;
|
return asio::error::host_not_found;
|
||||||
case EAI_SERVICE:
|
case EAI_SERVICE:
|
||||||
return asio::error::service_not_found;
|
return asio::error::service_not_found;
|
||||||
|
@ -1512,10 +1526,10 @@ inline asio::error_code translate_addrinfo_error(int error)
|
||||||
default: // Possibly the non-portable EAI_SYSTEM.
|
default: // Possibly the non-portable EAI_SYSTEM.
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
return asio::error_code(
|
return asio::error_code(
|
||||||
WSAGetLastError(), asio::native_ecat);
|
WSAGetLastError(), asio::error::system_category);
|
||||||
#else
|
#else
|
||||||
return asio::error_code(
|
return asio::error_code(
|
||||||
errno, asio::native_ecat);
|
errno, asio::error::system_category);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,9 +110,20 @@ public:
|
||||||
template <typename Protocol>
|
template <typename Protocol>
|
||||||
void resize(const Protocol&, std::size_t s)
|
void resize(const Protocol&, std::size_t s)
|
||||||
{
|
{
|
||||||
if (s != sizeof(value_))
|
// 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:
|
||||||
throw std::length_error("boolean socket option resize");
|
throw std::length_error("boolean socket option resize");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int value_;
|
int value_;
|
||||||
|
|
|
@ -98,6 +98,7 @@
|
||||||
# include <arpa/inet.h>
|
# include <arpa/inet.h>
|
||||||
# include <netdb.h>
|
# include <netdb.h>
|
||||||
# include <net/if.h>
|
# include <net/if.h>
|
||||||
|
# include <limits.h>
|
||||||
# if defined(__sun)
|
# if defined(__sun)
|
||||||
# include <sys/filio.h>
|
# include <sys/filio.h>
|
||||||
# include <sys/sockio.h>
|
# include <sys/sockio.h>
|
||||||
|
@ -141,6 +142,11 @@ const int shutdown_both = SD_BOTH;
|
||||||
const int message_peek = MSG_PEEK;
|
const int message_peek = MSG_PEEK;
|
||||||
const int message_out_of_band = MSG_OOB;
|
const int message_out_of_band = MSG_OOB;
|
||||||
const int message_do_not_route = MSG_DONTROUTE;
|
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
|
#else
|
||||||
typedef int socket_type;
|
typedef int socket_type;
|
||||||
const int invalid_socket = -1;
|
const int invalid_socket = -1;
|
||||||
|
@ -166,6 +172,7 @@ const int shutdown_both = SHUT_RDWR;
|
||||||
const int message_peek = MSG_PEEK;
|
const int message_peek = MSG_PEEK;
|
||||||
const int message_out_of_band = MSG_OOB;
|
const int message_out_of_band = MSG_OOB;
|
||||||
const int message_do_not_route = MSG_DONTROUTE;
|
const int message_do_not_route = MSG_DONTROUTE;
|
||||||
|
const int max_iov_len = IOV_MAX;
|
||||||
#endif
|
#endif
|
||||||
const int custom_socket_option_level = 0xA5100000;
|
const int custom_socket_option_level = 0xA5100000;
|
||||||
const int enable_connection_aborted_option = 1;
|
const int enable_connection_aborted_option = 1;
|
||||||
|
|
|
@ -239,6 +239,7 @@ public:
|
||||||
#else
|
#else
|
||||||
BOOST_ASSERT(size <= strand_impl::handler_storage_type::size);
|
BOOST_ASSERT(size <= strand_impl::handler_storage_type::size);
|
||||||
#endif
|
#endif
|
||||||
|
(void)size;
|
||||||
return impl_->handler_storage_.address();
|
return impl_->handler_storage_.address();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -415,14 +416,14 @@ public:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
asio::detail::mutex::scoped_lock lock(impl->mutex_);
|
|
||||||
|
|
||||||
// Allocate and construct an object to wrap the handler.
|
// Allocate and construct an object to wrap the handler.
|
||||||
typedef handler_wrapper<Handler> value_type;
|
typedef handler_wrapper<Handler> value_type;
|
||||||
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
|
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
|
||||||
raw_handler_ptr<alloc_traits> raw_ptr(handler);
|
raw_handler_ptr<alloc_traits> raw_ptr(handler);
|
||||||
handler_ptr<alloc_traits> ptr(raw_ptr, handler);
|
handler_ptr<alloc_traits> ptr(raw_ptr, handler);
|
||||||
|
|
||||||
|
asio::detail::mutex::scoped_lock lock(impl->mutex_);
|
||||||
|
|
||||||
if (impl->current_handler_ == 0)
|
if (impl->current_handler_ == 0)
|
||||||
{
|
{
|
||||||
// This handler now has the lock, so can be dispatched immediately.
|
// This handler now has the lock, so can be dispatched immediately.
|
||||||
|
@ -455,14 +456,14 @@ public:
|
||||||
template <typename Handler>
|
template <typename Handler>
|
||||||
void post(implementation_type& impl, Handler 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.
|
// Allocate and construct an object to wrap the handler.
|
||||||
typedef handler_wrapper<Handler> value_type;
|
typedef handler_wrapper<Handler> value_type;
|
||||||
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
|
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
|
||||||
raw_handler_ptr<alloc_traits> raw_ptr(handler);
|
raw_handler_ptr<alloc_traits> raw_ptr(handler);
|
||||||
handler_ptr<alloc_traits> ptr(raw_ptr, handler);
|
handler_ptr<alloc_traits> ptr(raw_ptr, handler);
|
||||||
|
|
||||||
|
asio::detail::mutex::scoped_lock lock(impl->mutex_);
|
||||||
|
|
||||||
if (impl->current_handler_ == 0)
|
if (impl->current_handler_ == 0)
|
||||||
{
|
{
|
||||||
// This handler now has the lock, so can be dispatched immediately.
|
// This handler now has the lock, so can be dispatched immediately.
|
||||||
|
|
|
@ -40,6 +40,7 @@ public:
|
||||||
: asio::detail::service_base<task_io_service<Task> >(io_service),
|
: asio::detail::service_base<task_io_service<Task> >(io_service),
|
||||||
mutex_(),
|
mutex_(),
|
||||||
task_(use_service<Task>(io_service)),
|
task_(use_service<Task>(io_service)),
|
||||||
|
task_interrupted_(true),
|
||||||
outstanding_work_(0),
|
outstanding_work_(0),
|
||||||
handler_queue_(&task_handler_),
|
handler_queue_(&task_handler_),
|
||||||
handler_queue_end_(&task_handler_),
|
handler_queue_end_(&task_handler_),
|
||||||
|
@ -80,8 +81,7 @@ public:
|
||||||
typename call_stack<task_io_service>::context ctx(this);
|
typename call_stack<task_io_service>::context ctx(this);
|
||||||
|
|
||||||
idle_thread_info this_idle_thread;
|
idle_thread_info this_idle_thread;
|
||||||
this_idle_thread.prev = &this_idle_thread;
|
this_idle_thread.next = 0;
|
||||||
this_idle_thread.next = &this_idle_thread;
|
|
||||||
|
|
||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
|
|
||||||
|
@ -98,8 +98,7 @@ public:
|
||||||
typename call_stack<task_io_service>::context ctx(this);
|
typename call_stack<task_io_service>::context ctx(this);
|
||||||
|
|
||||||
idle_thread_info this_idle_thread;
|
idle_thread_info this_idle_thread;
|
||||||
this_idle_thread.prev = &this_idle_thread;
|
this_idle_thread.next = 0;
|
||||||
this_idle_thread.next = &this_idle_thread;
|
|
||||||
|
|
||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
|
|
||||||
|
@ -134,7 +133,7 @@ public:
|
||||||
void stop()
|
void stop()
|
||||||
{
|
{
|
||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
stop_all_threads();
|
stop_all_threads(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset in preparation for a subsequent run invocation.
|
// Reset in preparation for a subsequent run invocation.
|
||||||
|
@ -156,7 +155,7 @@ public:
|
||||||
{
|
{
|
||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
if (--outstanding_work_ == 0)
|
if (--outstanding_work_ == 0)
|
||||||
stop_all_threads();
|
stop_all_threads(lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Request invocation of the given handler.
|
// Request invocation of the given handler.
|
||||||
|
@ -201,10 +200,15 @@ public:
|
||||||
++outstanding_work_;
|
++outstanding_work_;
|
||||||
|
|
||||||
// Wake up a thread to execute the handler.
|
// Wake up a thread to execute the handler.
|
||||||
if (!interrupt_one_idle_thread())
|
if (!interrupt_one_idle_thread(lock))
|
||||||
if (task_handler_.next_ == 0 && handler_queue_end_ != &task_handler_)
|
{
|
||||||
|
if (!task_interrupted_)
|
||||||
|
{
|
||||||
|
task_interrupted_ = true;
|
||||||
task_.interrupt();
|
task_.interrupt();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct idle_thread_info;
|
struct idle_thread_info;
|
||||||
|
@ -214,7 +218,7 @@ private:
|
||||||
{
|
{
|
||||||
if (outstanding_work_ == 0 && !stopped_)
|
if (outstanding_work_ == 0 && !stopped_)
|
||||||
{
|
{
|
||||||
stop_all_threads();
|
stop_all_threads(lock);
|
||||||
ec = asio::error_code();
|
ec = asio::error_code();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -230,11 +234,14 @@ private:
|
||||||
handler_queue_ = h->next_;
|
handler_queue_ = h->next_;
|
||||||
if (handler_queue_ == 0)
|
if (handler_queue_ == 0)
|
||||||
handler_queue_end_ = 0;
|
handler_queue_end_ = 0;
|
||||||
bool more_handlers = (handler_queue_ != 0);
|
h->next_ = 0;
|
||||||
lock.unlock();
|
|
||||||
|
|
||||||
if (h == &task_handler_)
|
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 the task has already run and we're polling then we're done.
|
||||||
if (task_has_run && polling)
|
if (task_has_run && polling)
|
||||||
{
|
{
|
||||||
|
@ -252,6 +259,7 @@ private:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
lock.unlock();
|
||||||
handler_cleanup c(lock, *this);
|
handler_cleanup c(lock, *this);
|
||||||
|
|
||||||
// Invoke the handler. May throw an exception.
|
// Invoke the handler. May throw an exception.
|
||||||
|
@ -264,31 +272,10 @@ private:
|
||||||
else if (this_idle_thread)
|
else if (this_idle_thread)
|
||||||
{
|
{
|
||||||
// Nothing to run right now, so just wait for work to do.
|
// Nothing to run right now, so just wait for work to do.
|
||||||
if (first_idle_thread_)
|
|
||||||
{
|
|
||||||
this_idle_thread->next = 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;
|
first_idle_thread_ = this_idle_thread;
|
||||||
this_idle_thread->wakeup_event.clear();
|
this_idle_thread->wakeup_event.clear(lock);
|
||||||
lock.unlock();
|
this_idle_thread->wakeup_event.wait(lock);
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
|
@ -302,39 +289,44 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop the task and all idle threads.
|
// Stop the task and all idle threads.
|
||||||
void stop_all_threads()
|
void stop_all_threads(
|
||||||
|
asio::detail::mutex::scoped_lock& lock)
|
||||||
{
|
{
|
||||||
stopped_ = true;
|
stopped_ = true;
|
||||||
interrupt_all_idle_threads();
|
interrupt_all_idle_threads(lock);
|
||||||
if (task_handler_.next_ == 0 && handler_queue_end_ != &task_handler_)
|
if (!task_interrupted_)
|
||||||
|
{
|
||||||
|
task_interrupted_ = true;
|
||||||
task_.interrupt();
|
task_.interrupt();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Interrupt a single idle thread. Returns true if a thread was interrupted,
|
// Interrupt a single idle thread. Returns true if a thread was interrupted,
|
||||||
// false if no running thread could be found to interrupt.
|
// false if no running thread could be found to interrupt.
|
||||||
bool interrupt_one_idle_thread()
|
bool interrupt_one_idle_thread(
|
||||||
|
asio::detail::mutex::scoped_lock& lock)
|
||||||
{
|
{
|
||||||
if (first_idle_thread_)
|
if (first_idle_thread_)
|
||||||
{
|
{
|
||||||
first_idle_thread_->wakeup_event.signal();
|
idle_thread_info* idle_thread = first_idle_thread_;
|
||||||
first_idle_thread_ = first_idle_thread_->next;
|
first_idle_thread_ = idle_thread->next;
|
||||||
|
idle_thread->next = 0;
|
||||||
|
idle_thread->wakeup_event.signal(lock);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interrupt all idle threads.
|
// Interrupt all idle threads.
|
||||||
void interrupt_all_idle_threads()
|
void interrupt_all_idle_threads(
|
||||||
|
asio::detail::mutex::scoped_lock& lock)
|
||||||
{
|
{
|
||||||
if (first_idle_thread_)
|
while (first_idle_thread_)
|
||||||
{
|
{
|
||||||
first_idle_thread_->wakeup_event.signal();
|
idle_thread_info* idle_thread = first_idle_thread_;
|
||||||
idle_thread_info* current_idle_thread = first_idle_thread_->next;
|
first_idle_thread_ = idle_thread->next;
|
||||||
while (current_idle_thread != first_idle_thread_)
|
idle_thread->next = 0;
|
||||||
{
|
idle_thread->wakeup_event.signal(lock);
|
||||||
current_idle_thread->wakeup_event.signal();
|
|
||||||
current_idle_thread = current_idle_thread->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,6 +432,7 @@ private:
|
||||||
{
|
{
|
||||||
// Reinsert the task at the end of the handler queue.
|
// Reinsert the task at the end of the handler queue.
|
||||||
lock_.lock();
|
lock_.lock();
|
||||||
|
task_io_service_.task_interrupted_ = true;
|
||||||
task_io_service_.task_handler_.next_ = 0;
|
task_io_service_.task_handler_.next_ = 0;
|
||||||
if (task_io_service_.handler_queue_end_)
|
if (task_io_service_.handler_queue_end_)
|
||||||
{
|
{
|
||||||
|
@ -478,7 +471,7 @@ private:
|
||||||
{
|
{
|
||||||
lock_.lock();
|
lock_.lock();
|
||||||
if (--task_io_service_.outstanding_work_ == 0)
|
if (--task_io_service_.outstanding_work_ == 0)
|
||||||
task_io_service_.stop_all_threads();
|
task_io_service_.stop_all_threads(lock_);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -503,6 +496,9 @@ private:
|
||||||
}
|
}
|
||||||
} task_handler_;
|
} task_handler_;
|
||||||
|
|
||||||
|
// Whether the task has been interrupted.
|
||||||
|
bool task_interrupted_;
|
||||||
|
|
||||||
// The count of unfinished work.
|
// The count of unfinished work.
|
||||||
int outstanding_work_;
|
int outstanding_work_;
|
||||||
|
|
||||||
|
@ -522,7 +518,6 @@ private:
|
||||||
struct idle_thread_info
|
struct idle_thread_info
|
||||||
{
|
{
|
||||||
event wakeup_event;
|
event wakeup_event;
|
||||||
idle_thread_info* prev;
|
|
||||||
idle_thread_info* next;
|
idle_thread_info* next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,9 @@ public:
|
||||||
// Constructor.
|
// Constructor.
|
||||||
timer_queue()
|
timer_queue()
|
||||||
: timers_(),
|
: timers_(),
|
||||||
heap_()
|
heap_(),
|
||||||
|
cancelled_timers_(0),
|
||||||
|
cleanup_timers_(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,12 +113,17 @@ public:
|
||||||
{
|
{
|
||||||
timer_base* t = heap_[0];
|
timer_base* t = heap_[0];
|
||||||
remove_timer(t);
|
remove_timer(t);
|
||||||
|
t->prev_ = 0;
|
||||||
|
t->next_ = cleanup_timers_;
|
||||||
|
cleanup_timers_ = t;
|
||||||
t->invoke(asio::error_code());
|
t->invoke(asio::error_code());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cancel the timer with the given token. The handler will be invoked
|
// Cancel the timers with the given token. Any timers pending for the token
|
||||||
// immediately with the result operation_aborted.
|
// will be notified that they have been cancelled next time
|
||||||
|
// dispatch_cancellations is called. Returns the number of timers that were
|
||||||
|
// cancelled.
|
||||||
std::size_t cancel_timer(void* timer_token)
|
std::size_t cancel_timer(void* timer_token)
|
||||||
{
|
{
|
||||||
std::size_t num_cancelled = 0;
|
std::size_t num_cancelled = 0;
|
||||||
|
@ -129,7 +136,9 @@ public:
|
||||||
{
|
{
|
||||||
timer_base* next = t->next_;
|
timer_base* next = t->next_;
|
||||||
remove_timer(t);
|
remove_timer(t);
|
||||||
t->invoke(asio::error::operation_aborted);
|
t->prev_ = 0;
|
||||||
|
t->next_ = cancelled_timers_;
|
||||||
|
cancelled_timers_ = t;
|
||||||
t = next;
|
t = next;
|
||||||
++num_cancelled;
|
++num_cancelled;
|
||||||
}
|
}
|
||||||
|
@ -137,6 +146,31 @@ public:
|
||||||
return num_cancelled;
|
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.
|
// Destroy all timers.
|
||||||
virtual void destroy_timers()
|
virtual void destroy_timers()
|
||||||
{
|
{
|
||||||
|
@ -151,6 +185,7 @@ public:
|
||||||
}
|
}
|
||||||
heap_.clear();
|
heap_.clear();
|
||||||
timers_.clear();
|
timers_.clear();
|
||||||
|
cleanup_timers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -238,8 +273,7 @@ private:
|
||||||
static void invoke_handler(timer_base* base,
|
static void invoke_handler(timer_base* base,
|
||||||
const asio::error_code& result)
|
const asio::error_code& result)
|
||||||
{
|
{
|
||||||
std::auto_ptr<timer<Handler> > t(static_cast<timer<Handler>*>(base));
|
static_cast<timer<Handler>*>(base)->handler_(result);
|
||||||
t->handler_(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Destroy the handler.
|
// Destroy the handler.
|
||||||
|
@ -338,6 +372,12 @@ private:
|
||||||
|
|
||||||
// The heap of timers, with the earliest timer at the front.
|
// The heap of timers, with the earliest timer at the front.
|
||||||
std::vector<timer_base*> heap_;
|
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
|
} // namespace detail
|
||||||
|
|
|
@ -44,6 +44,12 @@ public:
|
||||||
// Dispatch all ready timers.
|
// Dispatch all ready timers.
|
||||||
virtual void dispatch_timers() = 0;
|
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.
|
// Destroy all timers.
|
||||||
virtual void destroy_timers() = 0;
|
virtual void destroy_timers() = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,11 +23,13 @@
|
||||||
|
|
||||||
#if defined(BOOST_WINDOWS)
|
#if defined(BOOST_WINDOWS)
|
||||||
|
|
||||||
|
#include "asio/error.hpp"
|
||||||
#include "asio/system_error.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
|
|
||||||
#include "asio/detail/push_options.hpp"
|
#include "asio/detail/push_options.hpp"
|
||||||
|
#include <boost/assert.hpp>
|
||||||
#include <boost/throw_exception.hpp>
|
#include <boost/throw_exception.hpp>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
@ -46,7 +48,8 @@ public:
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(last_error, asio::native_ecat),
|
asio::error_code(last_error,
|
||||||
|
asio::error::system_category),
|
||||||
"event");
|
"event");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -59,21 +62,31 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Signal the event.
|
// Signal the event.
|
||||||
void signal()
|
template <typename Lock>
|
||||||
|
void signal(Lock& lock)
|
||||||
{
|
{
|
||||||
|
BOOST_ASSERT(lock.locked());
|
||||||
|
(void)lock;
|
||||||
::SetEvent(event_);
|
::SetEvent(event_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset the event.
|
// Reset the event.
|
||||||
void clear()
|
template <typename Lock>
|
||||||
|
void clear(Lock& lock)
|
||||||
{
|
{
|
||||||
|
BOOST_ASSERT(lock.locked());
|
||||||
|
(void)lock;
|
||||||
::ResetEvent(event_);
|
::ResetEvent(event_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the event to become signalled.
|
// Wait for the event to become signalled.
|
||||||
void wait()
|
template <typename Lock>
|
||||||
|
void wait(Lock& lock)
|
||||||
{
|
{
|
||||||
|
BOOST_ASSERT(lock.locked());
|
||||||
|
lock.unlock();
|
||||||
::WaitForSingleObject(event_, INFINITE);
|
::WaitForSingleObject(event_, INFINITE);
|
||||||
|
lock.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -63,7 +63,8 @@ public:
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(last_error, asio::native_ecat),
|
asio::error_code(last_error,
|
||||||
|
asio::error::system_category),
|
||||||
"iocp");
|
"iocp");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -173,7 +174,8 @@ public:
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(last_error, asio::native_ecat),
|
asio::error_code(last_error,
|
||||||
|
asio::error::system_category),
|
||||||
"pqcs");
|
"pqcs");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -228,7 +230,8 @@ public:
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(last_error, asio::native_ecat),
|
asio::error_code(last_error,
|
||||||
|
asio::error::system_category),
|
||||||
"pqcs");
|
"pqcs");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -247,7 +250,8 @@ public:
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(last_error, asio::native_ecat),
|
asio::error_code(last_error,
|
||||||
|
asio::error::system_category),
|
||||||
"pqcs");
|
"pqcs");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -312,7 +316,7 @@ private:
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
ec = asio::error_code(last_error,
|
ec = asio::error_code(last_error,
|
||||||
asio::native_ecat);
|
asio::error::system_category);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
#include "asio/detail/pop_options.hpp"
|
#include "asio/detail/pop_options.hpp"
|
||||||
|
|
||||||
|
#include "asio/detail/socket_types.hpp"
|
||||||
|
|
||||||
// This service is only supported on Win32 (NT4 and later).
|
// This service is only supported on Win32 (NT4 and later).
|
||||||
#if !defined(ASIO_DISABLE_IOCP)
|
#if !defined(ASIO_DISABLE_IOCP)
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
|
|
|
@ -137,7 +137,7 @@ public:
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
enable_connection_aborted = 1, // User wants connection_aborted errors.
|
enable_connection_aborted = 1, // User wants connection_aborted errors.
|
||||||
user_set_linger = 2, // The user set the linger option.
|
close_might_block = 2, // User set linger option for blocking close.
|
||||||
user_set_non_blocking = 4 // The user wants a non-blocking socket.
|
user_set_non_blocking = 4 // The user wants a non-blocking socket.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ public:
|
||||||
typedef detail::select_reactor<true> reactor_type;
|
typedef detail::select_reactor<true> reactor_type;
|
||||||
|
|
||||||
// The maximum number of buffers to support in a single operation.
|
// The maximum number of buffers to support in a single operation.
|
||||||
enum { max_buffers = 16 };
|
enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
|
||||||
|
|
||||||
// Constructor.
|
// Constructor.
|
||||||
win_iocp_socket_service(asio::io_service& io_service)
|
win_iocp_socket_service(asio::io_service& io_service)
|
||||||
|
@ -192,7 +192,7 @@ public:
|
||||||
while (impl)
|
while (impl)
|
||||||
{
|
{
|
||||||
asio::error_code ignored_ec;
|
asio::error_code ignored_ec;
|
||||||
close(*impl, ignored_ec);
|
close_for_destruction(*impl);
|
||||||
impl = impl->next_;
|
impl = impl->next_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,34 +217,7 @@ public:
|
||||||
// Destroy a socket implementation.
|
// Destroy a socket implementation.
|
||||||
void destroy(implementation_type& impl)
|
void destroy(implementation_type& impl)
|
||||||
{
|
{
|
||||||
if (impl.socket_ != invalid_socket)
|
close_for_destruction(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_);
|
|
||||||
|
|
||||||
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.
|
// Remove implementation from linked list of all implementations.
|
||||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||||
|
@ -353,6 +326,25 @@ public:
|
||||||
{
|
{
|
||||||
ec = asio::error::bad_descriptor;
|
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)
|
else if (impl.safe_cancellation_thread_id_ == 0)
|
||||||
{
|
{
|
||||||
// No operations have been started, so there's nothing to cancel.
|
// No operations have been started, so there's nothing to cancel.
|
||||||
|
@ -367,7 +359,8 @@ public:
|
||||||
if (!::CancelIo(sock_as_handle))
|
if (!::CancelIo(sock_as_handle))
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
ec = asio::error_code(last_error, asio::native_ecat);
|
ec = asio::error_code(last_error,
|
||||||
|
asio::error::system_category);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -475,7 +468,12 @@ public:
|
||||||
if (option.level(impl.protocol_) == SOL_SOCKET
|
if (option.level(impl.protocol_) == SOL_SOCKET
|
||||||
&& option.name(impl.protocol_) == SO_LINGER)
|
&& option.name(impl.protocol_) == SO_LINGER)
|
||||||
{
|
{
|
||||||
impl.flags_ |= implementation_type::user_set_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;
|
||||||
}
|
}
|
||||||
|
|
||||||
socket_ops::setsockopt(impl.socket_,
|
socket_ops::setsockopt(impl.socket_,
|
||||||
|
@ -668,7 +666,8 @@ public:
|
||||||
last_error = WSAECONNRESET;
|
last_error = WSAECONNRESET;
|
||||||
else if (last_error == ERROR_PORT_UNREACHABLE)
|
else if (last_error == ERROR_PORT_UNREACHABLE)
|
||||||
last_error = WSAECONNREFUSED;
|
last_error = WSAECONNREFUSED;
|
||||||
ec = asio::error_code(last_error, asio::native_ecat);
|
ec = asio::error_code(last_error,
|
||||||
|
asio::error::system_category);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -719,7 +718,8 @@ public:
|
||||||
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
|
||||||
// Map non-portable errors to their portable counterparts.
|
// Map non-portable errors to their portable counterparts.
|
||||||
asio::error_code ec(last_error, asio::native_ecat);
|
asio::error_code ec(last_error,
|
||||||
|
asio::error::system_category);
|
||||||
if (ec.value() == ERROR_NETNAME_DELETED)
|
if (ec.value() == ERROR_NETNAME_DELETED)
|
||||||
{
|
{
|
||||||
if (handler_op->cancel_token_.expired())
|
if (handler_op->cancel_token_.expired())
|
||||||
|
@ -821,7 +821,8 @@ public:
|
||||||
{
|
{
|
||||||
asio::io_service::work work(this->io_service());
|
asio::io_service::work work(this->io_service());
|
||||||
ptr.reset();
|
ptr.reset();
|
||||||
asio::error_code ec(last_error, asio::native_ecat);
|
asio::error_code ec(last_error,
|
||||||
|
asio::error::system_category);
|
||||||
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -865,7 +866,8 @@ public:
|
||||||
DWORD last_error = ::WSAGetLastError();
|
DWORD last_error = ::WSAGetLastError();
|
||||||
if (last_error == ERROR_PORT_UNREACHABLE)
|
if (last_error == ERROR_PORT_UNREACHABLE)
|
||||||
last_error = WSAECONNREFUSED;
|
last_error = WSAECONNREFUSED;
|
||||||
ec = asio::error_code(last_error, asio::native_ecat);
|
ec = asio::error_code(last_error,
|
||||||
|
asio::error::system_category);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -914,7 +916,8 @@ public:
|
||||||
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
|
||||||
// Map non-portable errors to their portable counterparts.
|
// Map non-portable errors to their portable counterparts.
|
||||||
asio::error_code ec(last_error, asio::native_ecat);
|
asio::error_code ec(last_error,
|
||||||
|
asio::error::system_category);
|
||||||
if (ec.value() == ERROR_PORT_UNREACHABLE)
|
if (ec.value() == ERROR_PORT_UNREACHABLE)
|
||||||
{
|
{
|
||||||
ec = asio::error::connection_refused;
|
ec = asio::error::connection_refused;
|
||||||
|
@ -997,7 +1000,8 @@ public:
|
||||||
{
|
{
|
||||||
asio::io_service::work work(this->io_service());
|
asio::io_service::work work(this->io_service());
|
||||||
ptr.reset();
|
ptr.reset();
|
||||||
asio::error_code ec(last_error, asio::native_ecat);
|
asio::error_code ec(last_error,
|
||||||
|
asio::error::system_category);
|
||||||
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1051,7 +1055,8 @@ public:
|
||||||
last_error = WSAECONNRESET;
|
last_error = WSAECONNRESET;
|
||||||
else if (last_error == ERROR_PORT_UNREACHABLE)
|
else if (last_error == ERROR_PORT_UNREACHABLE)
|
||||||
last_error = WSAECONNREFUSED;
|
last_error = WSAECONNREFUSED;
|
||||||
ec = asio::error_code(last_error, asio::native_ecat);
|
ec = asio::error_code(last_error,
|
||||||
|
asio::error::system_category);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (bytes_transferred == 0)
|
if (bytes_transferred == 0)
|
||||||
|
@ -1109,7 +1114,8 @@ public:
|
||||||
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
|
||||||
// Map non-portable errors to their portable counterparts.
|
// Map non-portable errors to their portable counterparts.
|
||||||
asio::error_code ec(last_error, asio::native_ecat);
|
asio::error_code ec(last_error,
|
||||||
|
asio::error::system_category);
|
||||||
if (ec.value() == ERROR_NETNAME_DELETED)
|
if (ec.value() == ERROR_NETNAME_DELETED)
|
||||||
{
|
{
|
||||||
if (handler_op->cancel_token_.expired())
|
if (handler_op->cancel_token_.expired())
|
||||||
|
@ -1216,7 +1222,8 @@ public:
|
||||||
{
|
{
|
||||||
asio::io_service::work work(this->io_service());
|
asio::io_service::work work(this->io_service());
|
||||||
ptr.reset();
|
ptr.reset();
|
||||||
asio::error_code ec(last_error, asio::native_ecat);
|
asio::error_code ec(last_error,
|
||||||
|
asio::error::system_category);
|
||||||
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1262,7 +1269,8 @@ public:
|
||||||
DWORD last_error = ::WSAGetLastError();
|
DWORD last_error = ::WSAGetLastError();
|
||||||
if (last_error == ERROR_PORT_UNREACHABLE)
|
if (last_error == ERROR_PORT_UNREACHABLE)
|
||||||
last_error = WSAECONNREFUSED;
|
last_error = WSAECONNREFUSED;
|
||||||
ec = asio::error_code(last_error, asio::native_ecat);
|
ec = asio::error_code(last_error,
|
||||||
|
asio::error::system_category);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (bytes_transferred == 0)
|
if (bytes_transferred == 0)
|
||||||
|
@ -1328,7 +1336,8 @@ public:
|
||||||
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
|
|
||||||
// Map non-portable errors to their portable counterparts.
|
// Map non-portable errors to their portable counterparts.
|
||||||
asio::error_code ec(last_error, asio::native_ecat);
|
asio::error_code ec(last_error,
|
||||||
|
asio::error::system_category);
|
||||||
if (ec.value() == ERROR_PORT_UNREACHABLE)
|
if (ec.value() == ERROR_PORT_UNREACHABLE)
|
||||||
{
|
{
|
||||||
ec = asio::error::connection_refused;
|
ec = asio::error::connection_refused;
|
||||||
|
@ -1422,7 +1431,8 @@ public:
|
||||||
{
|
{
|
||||||
asio::io_service::work work(this->io_service());
|
asio::io_service::work work(this->io_service());
|
||||||
ptr.reset();
|
ptr.reset();
|
||||||
asio::error_code ec(last_error, asio::native_ecat);
|
asio::error_code ec(last_error,
|
||||||
|
asio::error::system_category);
|
||||||
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
iocp_service_.post(bind_handler(handler, ec, bytes_transferred));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1659,7 +1669,8 @@ public:
|
||||||
ptr.reset();
|
ptr.reset();
|
||||||
|
|
||||||
// Call the handler.
|
// Call the handler.
|
||||||
asio::error_code ec(last_error, asio::native_ecat);
|
asio::error_code ec(last_error,
|
||||||
|
asio::error::system_category);
|
||||||
asio_handler_invoke_helpers::invoke(
|
asio_handler_invoke_helpers::invoke(
|
||||||
detail::bind_handler(handler, ec), &handler);
|
detail::bind_handler(handler, ec), &handler);
|
||||||
}
|
}
|
||||||
|
@ -1759,7 +1770,8 @@ public:
|
||||||
{
|
{
|
||||||
asio::io_service::work work(this->io_service());
|
asio::io_service::work work(this->io_service());
|
||||||
ptr.reset();
|
ptr.reset();
|
||||||
asio::error_code ec(last_error, asio::native_ecat);
|
asio::error_code ec(last_error,
|
||||||
|
asio::error::system_category);
|
||||||
iocp_service_.post(bind_handler(handler, ec));
|
iocp_service_.post(bind_handler(handler, ec));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1835,8 +1847,8 @@ public:
|
||||||
// If connection failed then post the handler with the error code.
|
// If connection failed then post the handler with the error code.
|
||||||
if (connect_error)
|
if (connect_error)
|
||||||
{
|
{
|
||||||
ec = asio::error_code(
|
ec = asio::error_code(connect_error,
|
||||||
connect_error, asio::native_ecat);
|
asio::error::system_category);
|
||||||
io_service_.post(bind_handler(handler_, ec));
|
io_service_.post(bind_handler(handler_, ec));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1950,26 +1962,66 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Helper function to provide InterlockedCompareExchangePointer functionality
|
// Helper function to close a socket when the associated object is being
|
||||||
// on very old Platform SDKs.
|
// 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.
|
||||||
void* interlocked_compare_exchange_pointer(void** dest, void* exch, void* cmp)
|
void* interlocked_compare_exchange_pointer(void** dest, void* exch, void* cmp)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32_WINNT) && (_WIN32_WINNT <= 0x400) && (_M_IX86)
|
#if defined(_M_IX86)
|
||||||
return reinterpret_cast<void*>(InterlockedCompareExchange(
|
return reinterpret_cast<void*>(InterlockedCompareExchange(
|
||||||
reinterpret_cast<LONG*>(dest), reinterpret_cast<LONG>(exch),
|
reinterpret_cast<PLONG>(dest), reinterpret_cast<LONG>(exch),
|
||||||
reinterpret_cast<LONG>(cmp)));
|
reinterpret_cast<LONG>(cmp)));
|
||||||
#else
|
#else
|
||||||
return InterlockedCompareExchangePointer(dest, exch, cmp);
|
return InterlockedCompareExchangePointer(dest, exch, cmp);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to provide InterlockedExchangePointer functionality on very
|
// Helper function to emulate InterlockedExchangePointer functionality for:
|
||||||
// old Platform SDKs.
|
// - very old Platform SDKs; and
|
||||||
|
// - platform SDKs where MSVC's /Wp64 option causes spurious warnings.
|
||||||
void* interlocked_exchange_pointer(void** dest, void* val)
|
void* interlocked_exchange_pointer(void** dest, void* val)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32_WINNT) && (_WIN32_WINNT <= 0x400) && (_M_IX86)
|
#if defined(_M_IX86)
|
||||||
return reinterpret_cast<void*>(InterlockedExchange(
|
return reinterpret_cast<void*>(InterlockedExchange(
|
||||||
reinterpret_cast<LONG*>(dest), reinterpret_cast<LONG>(val)));
|
reinterpret_cast<PLONG>(dest), reinterpret_cast<LONG>(val)));
|
||||||
#else
|
#else
|
||||||
return InterlockedExchangePointer(dest, val);
|
return InterlockedExchangePointer(dest, val);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#if defined(BOOST_WINDOWS)
|
#if defined(BOOST_WINDOWS)
|
||||||
|
|
||||||
|
#include "asio/error.hpp"
|
||||||
#include "asio/system_error.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
|
@ -48,7 +49,7 @@ public:
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(error, asio::native_ecat),
|
asio::error_code(error, asio::error::system_category),
|
||||||
"mutex");
|
"mutex");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
@ -67,7 +68,7 @@ public:
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(error, asio::native_ecat),
|
asio::error_code(error, asio::error::system_category),
|
||||||
"mutex");
|
"mutex");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#if defined(BOOST_WINDOWS)
|
#if defined(BOOST_WINDOWS)
|
||||||
|
|
||||||
|
#include "asio/error.hpp"
|
||||||
#include "asio/system_error.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
|
@ -54,7 +55,8 @@ public:
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(last_error, asio::native_ecat),
|
asio::error_code(last_error,
|
||||||
|
asio::error::system_category),
|
||||||
"thread");
|
"thread");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
|
|
||||||
#if defined(BOOST_WINDOWS)
|
#if defined(BOOST_WINDOWS)
|
||||||
|
|
||||||
|
#include "asio/error.hpp"
|
||||||
#include "asio/system_error.hpp"
|
#include "asio/system_error.hpp"
|
||||||
#include "asio/detail/noncopyable.hpp"
|
#include "asio/detail/noncopyable.hpp"
|
||||||
#include "asio/detail/socket_types.hpp"
|
#include "asio/detail/socket_types.hpp"
|
||||||
|
@ -47,7 +48,8 @@ public:
|
||||||
{
|
{
|
||||||
DWORD last_error = ::GetLastError();
|
DWORD last_error = ::GetLastError();
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(last_error, asio::native_ecat),
|
asio::error_code(last_error,
|
||||||
|
asio::error::system_category),
|
||||||
"tss");
|
"tss");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,7 +85,8 @@ public:
|
||||||
if (this != &instance_ && ref_->result() != 0)
|
if (this != &instance_ && ref_->result() != 0)
|
||||||
{
|
{
|
||||||
asio::system_error e(
|
asio::system_error e(
|
||||||
asio::error_code(ref_->result(), asio::native_ecat),
|
asio::error_code(ref_->result(),
|
||||||
|
asio::error::system_category),
|
||||||
"winsock");
|
"winsock");
|
||||||
boost::throw_exception(e);
|
boost::throw_exception(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,10 @@
|
||||||
|
|
||||||
#include "asio/detail/push_options.hpp"
|
#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/bind_handler.hpp"
|
||||||
#include "asio/detail/handler_alloc_helpers.hpp"
|
#include "asio/detail/handler_alloc_helpers.hpp"
|
||||||
#include "asio/detail/handler_invoke_helpers.hpp"
|
#include "asio/detail/handler_invoke_helpers.hpp"
|
||||||
|
@ -30,7 +34,9 @@ class wrapped_handler
|
||||||
public:
|
public:
|
||||||
typedef void result_type;
|
typedef void result_type;
|
||||||
|
|
||||||
wrapped_handler(Dispatcher& dispatcher, Handler handler)
|
wrapped_handler(
|
||||||
|
typename boost::add_reference<Dispatcher>::type dispatcher,
|
||||||
|
Handler handler)
|
||||||
: dispatcher_(dispatcher),
|
: dispatcher_(dispatcher),
|
||||||
handler_(handler)
|
handler_(handler)
|
||||||
{
|
{
|
||||||
|
@ -117,7 +123,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
//private:
|
//private:
|
||||||
Dispatcher& dispatcher_;
|
Dispatcher dispatcher_;
|
||||||
Handler handler_;
|
Handler handler_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -171,9 +177,9 @@ inline void asio_handler_invoke(const Function& function,
|
||||||
function, this_handler->handler_));
|
function, this_handler->handler_));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Function, typename Dispatcher, typename Handler>
|
template <typename Function, typename Handler, typename Context>
|
||||||
inline void asio_handler_invoke(const Function& function,
|
inline void asio_handler_invoke(const Function& function,
|
||||||
rewrapped_handler<Dispatcher, Handler>* this_handler)
|
rewrapped_handler<Handler, Context>* this_handler)
|
||||||
{
|
{
|
||||||
asio_handler_invoke_helpers::invoke(
|
asio_handler_invoke_helpers::invoke(
|
||||||
function, &this_handler->context_);
|
function, &this_handler->context_);
|
||||||
|
|
|
@ -37,327 +37,195 @@
|
||||||
/// INTERNAL ONLY.
|
/// INTERNAL ONLY.
|
||||||
# define ASIO_WIN_OR_POSIX(e_win, e_posix) implementation_defined
|
# define ASIO_WIN_OR_POSIX(e_win, e_posix) implementation_defined
|
||||||
#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
# define ASIO_NATIVE_ERROR(e) \
|
# define ASIO_NATIVE_ERROR(e) e
|
||||||
asio::error_code(e, \
|
# define ASIO_SOCKET_ERROR(e) WSA ## e
|
||||||
asio::native_ecat)
|
# define ASIO_NETDB_ERROR(e) WSA ## e
|
||||||
# define ASIO_SOCKET_ERROR(e) \
|
# define ASIO_GETADDRINFO_ERROR(e) WSA ## 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
|
# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_win
|
||||||
#else
|
#else
|
||||||
# define ASIO_NATIVE_ERROR(e) \
|
# define ASIO_NATIVE_ERROR(e) e
|
||||||
asio::error_code(e, \
|
# define ASIO_SOCKET_ERROR(e) e
|
||||||
asio::native_ecat)
|
# define ASIO_NETDB_ERROR(e) e
|
||||||
# define ASIO_SOCKET_ERROR(e) \
|
# define ASIO_GETADDRINFO_ERROR(e) 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
|
# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_posix
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
|
namespace error {
|
||||||
|
|
||||||
namespace detail {
|
enum basic_errors
|
||||||
|
|
||||||
/// Hack to keep asio library header-file-only.
|
|
||||||
template <typename T>
|
|
||||||
class error_base
|
|
||||||
{
|
{
|
||||||
public:
|
|
||||||
// boostify: error category declarations go here.
|
|
||||||
|
|
||||||
/// Permission denied.
|
/// Permission denied.
|
||||||
static const asio::error_code access_denied;
|
access_denied = ASIO_SOCKET_ERROR(EACCES),
|
||||||
|
|
||||||
/// Address family not supported by protocol.
|
/// Address family not supported by protocol.
|
||||||
static const asio::error_code address_family_not_supported;
|
address_family_not_supported = ASIO_SOCKET_ERROR(EAFNOSUPPORT),
|
||||||
|
|
||||||
/// Address already in use.
|
/// Address already in use.
|
||||||
static const asio::error_code address_in_use;
|
address_in_use = ASIO_SOCKET_ERROR(EADDRINUSE),
|
||||||
|
|
||||||
/// Transport endpoint is already connected.
|
/// Transport endpoint is already connected.
|
||||||
static const asio::error_code already_connected;
|
already_connected = ASIO_SOCKET_ERROR(EISCONN),
|
||||||
|
|
||||||
/// Already open.
|
|
||||||
static const asio::error_code already_open;
|
|
||||||
|
|
||||||
/// Operation already in progress.
|
/// Operation already in progress.
|
||||||
static const asio::error_code already_started;
|
already_started = ASIO_SOCKET_ERROR(EALREADY),
|
||||||
|
|
||||||
/// A connection has been aborted.
|
/// A connection has been aborted.
|
||||||
static const asio::error_code connection_aborted;
|
connection_aborted = ASIO_SOCKET_ERROR(ECONNABORTED),
|
||||||
|
|
||||||
/// Connection refused.
|
/// Connection refused.
|
||||||
static const asio::error_code connection_refused;
|
connection_refused = ASIO_SOCKET_ERROR(ECONNREFUSED),
|
||||||
|
|
||||||
/// Connection reset by peer.
|
/// Connection reset by peer.
|
||||||
static const asio::error_code connection_reset;
|
connection_reset = ASIO_SOCKET_ERROR(ECONNRESET),
|
||||||
|
|
||||||
/// Bad file descriptor.
|
/// Bad file descriptor.
|
||||||
static const asio::error_code bad_descriptor;
|
bad_descriptor = ASIO_SOCKET_ERROR(EBADF),
|
||||||
|
|
||||||
/// End of file or stream.
|
|
||||||
static const asio::error_code eof;
|
|
||||||
|
|
||||||
/// Bad address.
|
/// Bad address.
|
||||||
static const asio::error_code fault;
|
fault = ASIO_SOCKET_ERROR(EFAULT),
|
||||||
|
|
||||||
/// 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.
|
/// No route to host.
|
||||||
static const asio::error_code host_unreachable;
|
host_unreachable = ASIO_SOCKET_ERROR(EHOSTUNREACH),
|
||||||
|
|
||||||
/// Operation now in progress.
|
/// Operation now in progress.
|
||||||
static const asio::error_code in_progress;
|
in_progress = ASIO_SOCKET_ERROR(EINPROGRESS),
|
||||||
|
|
||||||
/// Interrupted system call.
|
/// Interrupted system call.
|
||||||
static const asio::error_code interrupted;
|
interrupted = ASIO_SOCKET_ERROR(EINTR),
|
||||||
|
|
||||||
/// Invalid argument.
|
/// Invalid argument.
|
||||||
static const asio::error_code invalid_argument;
|
invalid_argument = ASIO_SOCKET_ERROR(EINVAL),
|
||||||
|
|
||||||
/// Message too long.
|
/// Message too long.
|
||||||
static const asio::error_code message_size;
|
message_size = ASIO_SOCKET_ERROR(EMSGSIZE),
|
||||||
|
|
||||||
/// Network is down.
|
/// Network is down.
|
||||||
static const asio::error_code network_down;
|
network_down = ASIO_SOCKET_ERROR(ENETDOWN),
|
||||||
|
|
||||||
/// Network dropped connection on reset.
|
/// Network dropped connection on reset.
|
||||||
static const asio::error_code network_reset;
|
network_reset = ASIO_SOCKET_ERROR(ENETRESET),
|
||||||
|
|
||||||
/// Network is unreachable.
|
/// Network is unreachable.
|
||||||
static const asio::error_code network_unreachable;
|
network_unreachable = ASIO_SOCKET_ERROR(ENETUNREACH),
|
||||||
|
|
||||||
/// Too many open files.
|
/// Too many open files.
|
||||||
static const asio::error_code no_descriptors;
|
no_descriptors = ASIO_SOCKET_ERROR(EMFILE),
|
||||||
|
|
||||||
/// No buffer space available.
|
/// No buffer space available.
|
||||||
static const asio::error_code no_buffer_space;
|
no_buffer_space = ASIO_SOCKET_ERROR(ENOBUFS),
|
||||||
|
|
||||||
/// The query is valid but does not have associated address data.
|
|
||||||
static const asio::error_code no_data;
|
|
||||||
|
|
||||||
/// Cannot allocate memory.
|
/// Cannot allocate memory.
|
||||||
static const asio::error_code no_memory;
|
no_memory = ASIO_WIN_OR_POSIX(
|
||||||
|
ASIO_NATIVE_ERROR(ERROR_OUTOFMEMORY),
|
||||||
|
ASIO_NATIVE_ERROR(ENOMEM)),
|
||||||
|
|
||||||
/// Operation not permitted.
|
/// Operation not permitted.
|
||||||
static const asio::error_code no_permission;
|
no_permission = ASIO_WIN_OR_POSIX(
|
||||||
|
ASIO_NATIVE_ERROR(ERROR_ACCESS_DENIED),
|
||||||
|
ASIO_NATIVE_ERROR(EPERM)),
|
||||||
|
|
||||||
/// Protocol not available.
|
/// Protocol not available.
|
||||||
static const asio::error_code no_protocol_option;
|
no_protocol_option = ASIO_SOCKET_ERROR(ENOPROTOOPT),
|
||||||
|
|
||||||
/// A non-recoverable error occurred.
|
|
||||||
static const asio::error_code no_recovery;
|
|
||||||
|
|
||||||
/// Transport endpoint is not connected.
|
/// Transport endpoint is not connected.
|
||||||
static const asio::error_code not_connected;
|
not_connected = ASIO_SOCKET_ERROR(ENOTCONN),
|
||||||
|
|
||||||
/// Element not found.
|
|
||||||
static const asio::error_code not_found;
|
|
||||||
|
|
||||||
/// Socket operation on non-socket.
|
/// Socket operation on non-socket.
|
||||||
static const asio::error_code not_socket;
|
not_socket = ASIO_SOCKET_ERROR(ENOTSOCK),
|
||||||
|
|
||||||
/// Operation cancelled.
|
/// Operation cancelled.
|
||||||
static const asio::error_code operation_aborted;
|
operation_aborted = ASIO_WIN_OR_POSIX(
|
||||||
|
ASIO_NATIVE_ERROR(ERROR_OPERATION_ABORTED),
|
||||||
|
ASIO_NATIVE_ERROR(ECANCELED)),
|
||||||
|
|
||||||
/// Operation not supported.
|
/// Operation not supported.
|
||||||
static const asio::error_code operation_not_supported;
|
operation_not_supported = ASIO_SOCKET_ERROR(EOPNOTSUPP),
|
||||||
|
|
||||||
/// 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.
|
/// Cannot send after transport endpoint shutdown.
|
||||||
static const asio::error_code shut_down;
|
shut_down = ASIO_SOCKET_ERROR(ESHUTDOWN),
|
||||||
|
|
||||||
/// Connection timed out.
|
/// Connection timed out.
|
||||||
static const asio::error_code timed_out;
|
timed_out = ASIO_SOCKET_ERROR(ETIMEDOUT),
|
||||||
|
|
||||||
/// Resource temporarily unavailable.
|
/// Resource temporarily unavailable.
|
||||||
static const asio::error_code try_again;
|
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.
|
/// The socket is marked non-blocking and the requested operation would block.
|
||||||
static const asio::error_code would_block;
|
would_block = ASIO_SOCKET_ERROR(EWOULDBLOCK)
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
enum netdb_errors
|
||||||
error_base();
|
{
|
||||||
|
/// 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,
|
||||||
|
|
||||||
|
/// End of file or stream.
|
||||||
|
eof,
|
||||||
|
|
||||||
|
/// Element not found.
|
||||||
|
not_found
|
||||||
};
|
};
|
||||||
|
|
||||||
// boostify: error category definitions go here.
|
// boostify: error category definitions go here.
|
||||||
|
|
||||||
template <typename T> const asio::error_code
|
inline asio::error_code make_error_code(basic_errors e)
|
||||||
error_base<T>::access_denied = ASIO_SOCKET_ERROR(EACCES);
|
|
||||||
|
|
||||||
template <typename T> const asio::error_code
|
|
||||||
error_base<T>::address_family_not_supported = ASIO_SOCKET_ERROR(
|
|
||||||
EAFNOSUPPORT);
|
|
||||||
|
|
||||||
template <typename T> const asio::error_code
|
|
||||||
error_base<T>::address_in_use = ASIO_SOCKET_ERROR(EADDRINUSE);
|
|
||||||
|
|
||||||
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:
|
return asio::error_code(static_cast<int>(e), system_category);
|
||||||
error();
|
}
|
||||||
};
|
|
||||||
|
|
||||||
|
inline asio::error_code make_error_code(netdb_errors e)
|
||||||
|
{
|
||||||
|
return asio::error_code(static_cast<int>(e), netdb_category);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline asio::error_code make_error_code(addrinfo_errors e)
|
||||||
|
{
|
||||||
|
return asio::error_code(static_cast<int>(e), addrinfo_category);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline asio::error_code make_error_code(misc_errors e)
|
||||||
|
{
|
||||||
|
return asio::error_code(static_cast<int>(e), misc_category);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace error
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
|
|
||||||
#undef ASIO_NATIVE_ERROR
|
#undef ASIO_NATIVE_ERROR
|
||||||
#undef ASIO_SOCKET_ERROR
|
#undef ASIO_SOCKET_ERROR
|
||||||
#undef ASIO_NETDB_ERROR
|
#undef ASIO_NETDB_ERROR
|
||||||
#undef ASIO_GETADDRINFO_ERROR
|
#undef ASIO_GETADDRINFO_ERROR
|
||||||
#undef ASIO_MISC_ERROR
|
|
||||||
#undef ASIO_WIN_OR_POSIX
|
#undef ASIO_WIN_OR_POSIX
|
||||||
|
|
||||||
#include "asio/impl/error_code.ipp"
|
#include "asio/impl/error_code.ipp"
|
||||||
|
|
|
@ -32,24 +32,27 @@
|
||||||
|
|
||||||
namespace asio {
|
namespace asio {
|
||||||
|
|
||||||
|
namespace error
|
||||||
|
{
|
||||||
/// Available error code categories.
|
/// Available error code categories.
|
||||||
enum error_category
|
enum error_category
|
||||||
{
|
{
|
||||||
/// Native error codes.
|
/// System error codes.
|
||||||
native_ecat = ASIO_WIN_OR_POSIX(0, 0),
|
system_category = ASIO_WIN_OR_POSIX(0, 0),
|
||||||
|
|
||||||
/// Error codes from NetDB functions.
|
/// Error codes from NetDB functions.
|
||||||
netdb_ecat = ASIO_WIN_OR_POSIX(native_ecat, 1),
|
netdb_category = ASIO_WIN_OR_POSIX(system_category, 1),
|
||||||
|
|
||||||
/// Error codes from getaddrinfo.
|
/// Error codes from getaddrinfo.
|
||||||
addrinfo_ecat = ASIO_WIN_OR_POSIX(native_ecat, 2),
|
addrinfo_category = ASIO_WIN_OR_POSIX(system_category, 2),
|
||||||
|
|
||||||
/// Miscellaneous error codes.
|
/// Miscellaneous error codes.
|
||||||
misc_ecat = ASIO_WIN_OR_POSIX(3, 3),
|
misc_category = ASIO_WIN_OR_POSIX(3, 3),
|
||||||
|
|
||||||
/// SSL error codes.
|
/// SSL error codes.
|
||||||
ssl_ecat = ASIO_WIN_OR_POSIX(4, 4)
|
ssl_category = ASIO_WIN_OR_POSIX(4, 4)
|
||||||
};
|
};
|
||||||
|
} // namespace error
|
||||||
|
|
||||||
/// Class to represent an error code value.
|
/// Class to represent an error code value.
|
||||||
class error_code
|
class error_code
|
||||||
|
@ -61,17 +64,24 @@ public:
|
||||||
/// Default constructor.
|
/// Default constructor.
|
||||||
error_code()
|
error_code()
|
||||||
: value_(0),
|
: value_(0),
|
||||||
category_(native_ecat)
|
category_(error::system_category)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct with specific error code and category.
|
/// Construct with specific error code and category.
|
||||||
error_code(value_type v, error_category c)
|
error_code(value_type v, error::error_category c)
|
||||||
: value_(v),
|
: value_(v),
|
||||||
category_(c)
|
category_(c)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct from an error code enum.
|
||||||
|
template <typename ErrorEnum>
|
||||||
|
error_code(ErrorEnum e)
|
||||||
|
{
|
||||||
|
*this = make_error_code(e);
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the error value.
|
/// Get the error value.
|
||||||
value_type value() const
|
value_type value() const
|
||||||
{
|
{
|
||||||
|
@ -79,7 +89,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the error category.
|
/// Get the error category.
|
||||||
error_category category() const
|
error::error_category category() const
|
||||||
{
|
{
|
||||||
return category_;
|
return category_;
|
||||||
}
|
}
|
||||||
|
@ -125,7 +135,7 @@ private:
|
||||||
value_type value_;
|
value_type value_;
|
||||||
|
|
||||||
// The category associated with the error code.
|
// The category associated with the error code.
|
||||||
error_category category_;
|
error::error_category category_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace asio
|
} // namespace asio
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
/error_code.ipp/1.6/Sun Mar 25 14:06:36 2007//
|
|
||||||
/io_service.ipp/1.12/Mon Jan 8 01:04:08 2007//
|
|
||||||
/read.ipp/1.16/Sat Jan 13 13:30:12 2007//
|
|
||||||
/read_until.ipp/1.10/Sun Jan 7 08:05:53 2007//
|
|
||||||
/write.ipp/1.14/Sat Jan 13 13:30:12 2007//
|
|
||||||
D
|
|
|
@ -1 +0,0 @@
|
||||||
asio/include/asio/impl
|
|
|
@ -1 +0,0 @@
|
||||||
:pserver:anonymous@asio.cvs.sourceforge.net:/cvsroot/asio
|
|
|
@ -35,10 +35,12 @@ inline std::string error_code::message() const
|
||||||
return "Already open.";
|
return "Already open.";
|
||||||
if (*this == error::not_found)
|
if (*this == error::not_found)
|
||||||
return "Not found.";
|
return "Not found.";
|
||||||
if (category_ == ssl_ecat)
|
if (category_ == error::ssl_category)
|
||||||
return "SSL error.";
|
return "SSL error.";
|
||||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||||
value_type value = value_;
|
value_type value = value_;
|
||||||
|
if (category() != error::system_category && *this != error::eof)
|
||||||
|
return "asio error";
|
||||||
if (*this == error::eof)
|
if (*this == error::eof)
|
||||||
value = ERROR_HANDLE_EOF;
|
value = ERROR_HANDLE_EOF;
|
||||||
char* msg = 0;
|
char* msg = 0;
|
||||||
|
@ -76,6 +78,8 @@ inline std::string error_code::message() const
|
||||||
return "Service not found.";
|
return "Service not found.";
|
||||||
if (*this == error::socket_type_not_supported)
|
if (*this == error::socket_type_not_supported)
|
||||||
return "Socket type not supported.";
|
return "Socket type not supported.";
|
||||||
|
if (category() != error::system_category)
|
||||||
|
return "asio error";
|
||||||
#if defined(__sun) || defined(__QNX__)
|
#if defined(__sun) || defined(__QNX__)
|
||||||
return strerror(value_);
|
return strerror(value_);
|
||||||
#elif defined(__MACH__) && defined(__APPLE__) \
|
#elif defined(__MACH__) && defined(__APPLE__) \
|
||||||
|
|
|
@ -128,11 +128,11 @@ template <typename Handler>
|
||||||
#if defined(GENERATING_DOCUMENTATION)
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
unspecified
|
unspecified
|
||||||
#else
|
#else
|
||||||
inline detail::wrapped_handler<io_service, Handler>
|
inline detail::wrapped_handler<io_service&, Handler>
|
||||||
#endif
|
#endif
|
||||||
io_service::wrap(Handler handler)
|
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)
|
inline io_service::work::work(asio::io_service& io_service)
|
||||||
|
|
|
@ -311,7 +311,8 @@ namespace detail
|
||||||
if (streambuf_.size() == streambuf_.max_size())
|
if (streambuf_.size() == streambuf_.max_size())
|
||||||
{
|
{
|
||||||
std::size_t bytes = 0;
|
std::size_t bytes = 0;
|
||||||
handler_(error::not_found, bytes);
|
asio::error_code ec(error::not_found);
|
||||||
|
handler_(ec, bytes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -388,7 +389,8 @@ void async_read_until(AsyncReadStream& s,
|
||||||
// No match. Check if buffer is full.
|
// No match. Check if buffer is full.
|
||||||
if (b.size() == b.max_size())
|
if (b.size() == b.max_size())
|
||||||
{
|
{
|
||||||
s.io_service().post(detail::bind_handler(handler, error::not_found, 0));
|
asio::error_code ec(error::not_found);
|
||||||
|
s.io_service().post(detail::bind_handler(handler, ec, 0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -469,7 +471,8 @@ namespace detail
|
||||||
if (streambuf_.size() == streambuf_.max_size())
|
if (streambuf_.size() == streambuf_.max_size())
|
||||||
{
|
{
|
||||||
std::size_t bytes = 0;
|
std::size_t bytes = 0;
|
||||||
handler_(error::not_found, bytes);
|
asio::error_code ec(error::not_found);
|
||||||
|
handler_(ec, bytes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,7 +562,8 @@ void async_read_until(AsyncReadStream& s,
|
||||||
// Check if buffer is full.
|
// Check if buffer is full.
|
||||||
if (b.size() == b.max_size())
|
if (b.size() == b.max_size())
|
||||||
{
|
{
|
||||||
s.io_service().post(detail::bind_handler(handler, error::not_found, 0));
|
asio::error_code ec(error::not_found);
|
||||||
|
s.io_service().post(detail::bind_handler(handler, ec, 0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,7 +645,8 @@ namespace detail
|
||||||
if (streambuf_.size() == streambuf_.max_size())
|
if (streambuf_.size() == streambuf_.max_size())
|
||||||
{
|
{
|
||||||
std::size_t bytes = 0;
|
std::size_t bytes = 0;
|
||||||
handler_(error::not_found, bytes);
|
asio::error_code ec(error::not_found);
|
||||||
|
handler_(ec, bytes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,7 +736,8 @@ void async_read_until(AsyncReadStream& s,
|
||||||
// Check if buffer is full.
|
// Check if buffer is full.
|
||||||
if (b.size() == b.max_size())
|
if (b.size() == b.max_size())
|
||||||
{
|
{
|
||||||
s.io_service().post(detail::bind_handler(handler, error::not_found, 0));
|
asio::error_code ec(error::not_found);
|
||||||
|
s.io_service().post(detail::bind_handler(handler, ec, 0));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -320,7 +320,7 @@ public:
|
||||||
#if defined(GENERATING_DOCUMENTATION)
|
#if defined(GENERATING_DOCUMENTATION)
|
||||||
unspecified
|
unspecified
|
||||||
#else
|
#else
|
||||||
detail::wrapped_handler<io_service, Handler>
|
detail::wrapped_handler<io_service&, Handler>
|
||||||
#endif
|
#endif
|
||||||
wrap(Handler handler);
|
wrap(Handler handler);
|
||||||
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
/address.hpp/1.9/Thu Jan 4 05:44:46 2007//
|
|
||||||
/address_v4.hpp/1.11/Thu Jan 4 05:44:46 2007//
|
|
||||||
/address_v6.hpp/1.11/Mon Feb 19 01:46:31 2007//
|
|
||||||
/basic_endpoint.hpp/1.16/Wed Feb 14 13:26:26 2007//
|
|
||||||
/basic_resolver.hpp/1.5/Thu Jan 4 05:44:46 2007//
|
|
||||||
/basic_resolver_entry.hpp/1.5/Thu Jan 4 05:44:46 2007//
|
|
||||||
/basic_resolver_iterator.hpp/1.10/Sun Apr 8 23:47:05 2007//
|
|
||||||
/basic_resolver_query.hpp/1.12/Thu Jan 4 05:44:46 2007//
|
|
||||||
/host_name.hpp/1.5/Thu Jan 4 05:44:46 2007//
|
|
||||||
/multicast.hpp/1.8/Sat Feb 17 22:57:39 2007//
|
|
||||||
/resolver_query_base.hpp/1.3/Thu Jan 4 05:44:46 2007//
|
|
||||||
/resolver_service.hpp/1.7/Thu Jan 4 05:44:46 2007//
|
|
||||||
/tcp.hpp/1.14/Sun May 20 00:49:02 2007//
|
|
||||||
/udp.hpp/1.12/Sun May 20 00:49:02 2007//
|
|
||||||
/unicast.hpp/1.2/Sat Feb 17 22:57:39 2007//
|
|
||||||
/v6_only.hpp/1.2/Sun May 13 07:59:22 2007//
|
|
||||||
D/detail////
|
|
|
@ -1 +0,0 @@
|
||||||
asio/include/asio/ip
|
|
|
@ -1 +0,0 @@
|
||||||
:pserver:anonymous@asio.cvs.sourceforge.net:/cvsroot/asio
|
|
|
@ -172,7 +172,7 @@ public:
|
||||||
/// The protocol associated with the endpoint.
|
/// The protocol associated with the endpoint.
|
||||||
protocol_type protocol() const
|
protocol_type protocol() const
|
||||||
{
|
{
|
||||||
if (is_v4())
|
if (is_v4(data_))
|
||||||
return InternetProtocol::v4();
|
return InternetProtocol::v4();
|
||||||
return InternetProtocol::v6();
|
return InternetProtocol::v6();
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,7 @@ public:
|
||||||
/// Get the underlying size of the endpoint in the native type.
|
/// Get the underlying size of the endpoint in the native type.
|
||||||
size_type size() const
|
size_type size() const
|
||||||
{
|
{
|
||||||
if (is_v4())
|
if (is_v4(data_))
|
||||||
return sizeof(asio::detail::sockaddr_in4_type);
|
return sizeof(asio::detail::sockaddr_in4_type);
|
||||||
else
|
else
|
||||||
return sizeof(asio::detail::sockaddr_in6_type);
|
return sizeof(asio::detail::sockaddr_in6_type);
|
||||||
|
@ -218,7 +218,7 @@ public:
|
||||||
/// the host's byte order.
|
/// the host's byte order.
|
||||||
unsigned short port() const
|
unsigned short port() const
|
||||||
{
|
{
|
||||||
if (is_v4())
|
if (is_v4(data_))
|
||||||
{
|
{
|
||||||
return asio::detail::socket_ops::network_to_host_short(
|
return asio::detail::socket_ops::network_to_host_short(
|
||||||
reinterpret_cast<const asio::detail::sockaddr_in4_type&>(
|
reinterpret_cast<const asio::detail::sockaddr_in4_type&>(
|
||||||
|
@ -236,7 +236,7 @@ public:
|
||||||
/// the host's byte order.
|
/// the host's byte order.
|
||||||
void port(unsigned short port_num)
|
void port(unsigned short port_num)
|
||||||
{
|
{
|
||||||
if (is_v4())
|
if (is_v4(data_))
|
||||||
{
|
{
|
||||||
reinterpret_cast<asio::detail::sockaddr_in4_type&>(data_).sin_port
|
reinterpret_cast<asio::detail::sockaddr_in4_type&>(data_).sin_port
|
||||||
= asio::detail::socket_ops::host_to_network_short(port_num);
|
= asio::detail::socket_ops::host_to_network_short(port_num);
|
||||||
|
@ -252,7 +252,7 @@ public:
|
||||||
asio::ip::address address() const
|
asio::ip::address address() const
|
||||||
{
|
{
|
||||||
using namespace std; // For memcpy.
|
using namespace std; // For memcpy.
|
||||||
if (is_v4())
|
if (is_v4(data_))
|
||||||
{
|
{
|
||||||
const asio::detail::sockaddr_in4_type& data
|
const asio::detail::sockaddr_in4_type& data
|
||||||
= reinterpret_cast<const asio::detail::sockaddr_in4_type&>(
|
= reinterpret_cast<const asio::detail::sockaddr_in4_type&>(
|
||||||
|
@ -306,15 +306,27 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Helper function to determine whether the endpoint is IPv4.
|
// Helper function to determine whether the endpoint is IPv4.
|
||||||
bool is_v4() const
|
|
||||||
{
|
|
||||||
#if defined(_AIX)
|
#if defined(_AIX)
|
||||||
return data_.__ss_family == AF_INET;
|
template <typename T, unsigned char (T::*)> struct is_v4_helper {};
|
||||||
#else
|
|
||||||
return data_.ss_family == AF_INET;
|
template <typename T>
|
||||||
#endif
|
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;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static bool is_v4(const asio::detail::sockaddr_storage_type& ss)
|
||||||
|
{
|
||||||
|
return ss.ss_family == AF_INET;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// The underlying IP socket address.
|
// The underlying IP socket address.
|
||||||
asio::detail::sockaddr_storage_type data_;
|
asio::detail::sockaddr_storage_type data_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
/basic_context.hpp/1.11/Thu Dec 21 12:29:03 2006//
|
|
||||||
/context.hpp/1.3/Mon Apr 10 12:17:44 2006//
|
|
||||||
/context_base.hpp/1.6/Sun Sep 24 07:46:22 2006//
|
|
||||||
/context_service.hpp/1.11/Fri Dec 29 02:01:24 2006//
|
|
||||||
/stream.hpp/1.13/Thu Dec 21 12:29:03 2006//
|
|
||||||
/stream_base.hpp/1.4/Wed Nov 30 01:57:07 2005//
|
|
||||||
/stream_service.hpp/1.10/Fri Dec 29 02:01:24 2006//
|
|
||||||
D/detail////
|
|
|
@ -1 +0,0 @@
|
||||||
asio/include/asio/ssl
|
|
|
@ -1 +0,0 @@
|
||||||
:pserver:anonymous@asio.cvs.sourceforge.net:/cvsroot/asio
|
|
|
@ -174,12 +174,12 @@ public:
|
||||||
if (error_code == SSL_ERROR_SYSCALL)
|
if (error_code == SSL_ERROR_SYSCALL)
|
||||||
{
|
{
|
||||||
return handler_(asio::error_code(
|
return handler_(asio::error_code(
|
||||||
sys_error_code, asio::native_ecat), rc);
|
sys_error_code, asio::error::system_category), rc);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return handler_(asio::error_code(
|
return handler_(asio::error_code(
|
||||||
error_code, asio::ssl_ecat), rc);
|
error_code, asio::error::ssl_category), rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <cassert>
|
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -56,6 +55,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "libtorrent/time.hpp"
|
#include "libtorrent/time.hpp"
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
#ifndef TORRENT_MAX_ALERT_TYPES
|
#ifndef TORRENT_MAX_ALERT_TYPES
|
||||||
#define TORRENT_MAX_ALERT_TYPES 15
|
#define TORRENT_MAX_ALERT_TYPES 15
|
||||||
|
|
|
@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
#include "libtorrent/peer_connection.hpp"
|
#include "libtorrent/peer_connection.hpp"
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
@ -223,7 +224,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
block_downloading_alert(
|
block_downloading_alert(
|
||||||
const torrent_handle& h
|
const torrent_handle& h
|
||||||
, std::string& speedmsg
|
, char const* speedmsg
|
||||||
, int block_num
|
, int block_num
|
||||||
, int piece_num
|
, int piece_num
|
||||||
, const std::string& msg)
|
, const std::string& msg)
|
||||||
|
@ -261,6 +262,17 @@ namespace libtorrent
|
||||||
{ return std::auto_ptr<alert>(new torrent_paused_alert(*this)); }
|
{ 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
|
struct TORRENT_EXPORT url_seed_alert: torrent_alert
|
||||||
{
|
{
|
||||||
url_seed_alert(
|
url_seed_alert(
|
||||||
|
|
52
libtorrent/include/libtorrent/assert.hpp
Normal file
52
libtorrent/include/libtorrent/assert.hpp
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
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 __GNUC__
|
||||||
|
#ifdef assert
|
||||||
|
#undef assert
|
||||||
|
#endif
|
||||||
|
|
||||||
|
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,6 +83,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/socket_type.hpp"
|
#include "libtorrent/socket_type.hpp"
|
||||||
#include "libtorrent/connection_queue.hpp"
|
#include "libtorrent/connection_queue.hpp"
|
||||||
#include "libtorrent/disk_io_thread.hpp"
|
#include "libtorrent/disk_io_thread.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
@ -240,12 +241,12 @@ namespace libtorrent
|
||||||
bool is_listening() const;
|
bool is_listening() const;
|
||||||
|
|
||||||
torrent_handle add_torrent(
|
torrent_handle add_torrent(
|
||||||
torrent_info const& ti
|
boost::intrusive_ptr<torrent_info> ti
|
||||||
, fs::path const& save_path
|
, fs::path const& save_path
|
||||||
, entry const& resume_data
|
, entry const& resume_data
|
||||||
, bool compact_mode
|
, bool compact_mode
|
||||||
, int block_size
|
, storage_constructor_type sc
|
||||||
, storage_constructor_type sc);
|
, bool paused);
|
||||||
|
|
||||||
torrent_handle add_torrent(
|
torrent_handle add_torrent(
|
||||||
char const* tracker_url
|
char const* tracker_url
|
||||||
|
@ -254,8 +255,8 @@ namespace libtorrent
|
||||||
, fs::path const& save_path
|
, fs::path const& save_path
|
||||||
, entry const& resume_data
|
, entry const& resume_data
|
||||||
, bool compact_mode
|
, bool compact_mode
|
||||||
, int block_size
|
, storage_constructor_type sc
|
||||||
, storage_constructor_type sc);
|
, bool paused);
|
||||||
|
|
||||||
void remove_torrent(torrent_handle const& h);
|
void remove_torrent(torrent_handle const& h);
|
||||||
|
|
||||||
|
@ -273,8 +274,21 @@ namespace libtorrent
|
||||||
void set_max_connections(int limit);
|
void set_max_connections(int limit);
|
||||||
void set_max_uploads(int limit);
|
void set_max_uploads(int limit);
|
||||||
|
|
||||||
int num_uploads() const;
|
int max_connections() const { return m_max_connections; }
|
||||||
int num_connections() const;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
session_status status() const;
|
session_status status() const;
|
||||||
void set_peer_id(peer_id const& id);
|
void set_peer_id(peer_id const& id);
|
||||||
|
@ -417,6 +431,28 @@ namespace libtorrent
|
||||||
int m_max_uploads;
|
int m_max_uploads;
|
||||||
int m_max_connections;
|
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.
|
// statistics gathered from all torrents.
|
||||||
stat m_stat;
|
stat m_stat;
|
||||||
|
|
||||||
|
@ -459,7 +495,7 @@ namespace libtorrent
|
||||||
// This implements a round robin.
|
// This implements a round robin.
|
||||||
int m_next_connect_torrent;
|
int m_next_connect_torrent;
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void check_invariant(const char *place = 0);
|
void check_invariant() const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef TORRENT_STATS
|
#ifdef TORRENT_STATS
|
||||||
|
|
|
@ -33,9 +33,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef TORRENT_BANDWIDTH_MANAGER_HPP_INCLUDED
|
#ifndef TORRENT_BANDWIDTH_MANAGER_HPP_INCLUDED
|
||||||
#define 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/shared_ptr.hpp>
|
||||||
#include <boost/intrusive_ptr.hpp>
|
#include <boost/intrusive_ptr.hpp>
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
|
@ -44,11 +41,17 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <boost/thread/mutex.hpp>
|
#include <boost/thread/mutex.hpp>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
|
||||||
|
#include "libtorrent/socket.hpp"
|
||||||
|
#include "libtorrent/invariant_check.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
using boost::weak_ptr;
|
using boost::weak_ptr;
|
||||||
using boost::shared_ptr;
|
using boost::shared_ptr;
|
||||||
using boost::intrusive_ptr;
|
using boost::intrusive_ptr;
|
||||||
using boost::bind;
|
using boost::bind;
|
||||||
|
|
||||||
|
//#define TORRENT_VERBOSE_BANDWIDTH_LIMIT
|
||||||
|
|
||||||
namespace libtorrent {
|
namespace libtorrent {
|
||||||
|
|
||||||
// the maximum block of bandwidth quota to
|
// the maximum block of bandwidth quota to
|
||||||
|
@ -237,8 +240,10 @@ struct bandwidth_manager
|
||||||
i = j;
|
i = j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
|
||||||
if (m_queue.size() == 1) hand_out_bandwidth();
|
std::cerr << " req_bandwidht. m_queue.size() = " << m_queue.size() << std::endl;
|
||||||
|
#endif
|
||||||
|
if (!m_queue.empty()) hand_out_bandwidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
@ -337,10 +342,18 @@ private:
|
||||||
// available bandwidth to hand out
|
// available bandwidth to hand out
|
||||||
int amount = limit - m_current_quota;
|
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)
|
while (!m_queue.empty() && amount > 0)
|
||||||
{
|
{
|
||||||
assert(amount == limit - m_current_quota);
|
assert(amount == limit - m_current_quota);
|
||||||
bw_queue_entry<PeerConnection> qe = m_queue.front();
|
bw_queue_entry<PeerConnection> qe = m_queue.front();
|
||||||
|
assert(qe.max_block_size > 0);
|
||||||
m_queue.pop_front();
|
m_queue.pop_front();
|
||||||
|
|
||||||
shared_ptr<Torrent> t = qe.peer->associated_torrent().lock();
|
shared_ptr<Torrent> t = qe.peer->associated_torrent().lock();
|
||||||
|
@ -374,13 +387,12 @@ private:
|
||||||
// block size must be smaller for lower rates. This is because
|
// block size must be smaller for lower rates. This is because
|
||||||
// the history window is one second, and the block will be forgotten
|
// the history window is one second, and the block will be forgotten
|
||||||
// after one second.
|
// after one second.
|
||||||
int block_size = (std::min)(qe.max_block_size
|
int block_size = (std::min)(qe.peer->bandwidth_throttle(m_channel)
|
||||||
, (std::min)(qe.peer->bandwidth_throttle(m_channel)
|
, m_limit / 10);
|
||||||
, m_limit / 10));
|
|
||||||
|
|
||||||
if (block_size < min_bandwidth_block_size)
|
if (block_size < min_bandwidth_block_size)
|
||||||
{
|
{
|
||||||
block_size = min_bandwidth_block_size;
|
block_size = (std::min)(int(min_bandwidth_block_size), m_limit);
|
||||||
}
|
}
|
||||||
else if (block_size > max_bandwidth_block_size)
|
else if (block_size > max_bandwidth_block_size)
|
||||||
{
|
{
|
||||||
|
@ -399,7 +411,11 @@ private:
|
||||||
/ (m_limit / max_bandwidth_block_size);
|
/ (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)
|
if (amount < block_size / 2)
|
||||||
{
|
{
|
||||||
m_queue.push_front(qe);
|
m_queue.push_front(qe);
|
||||||
|
|
|
@ -79,6 +79,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/entry.hpp"
|
#include "libtorrent/entry.hpp"
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
|
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
|
|
80
libtorrent/include/libtorrent/broadcast_socket.hpp
Normal file
80
libtorrent/include/libtorrent/broadcast_socket.hpp
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
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);
|
||||||
|
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);
|
||||||
|
|
||||||
|
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,7 +65,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/alert.hpp"
|
#include "libtorrent/alert.hpp"
|
||||||
#include "libtorrent/torrent_handle.hpp"
|
#include "libtorrent/torrent_handle.hpp"
|
||||||
#include "libtorrent/torrent.hpp"
|
#include "libtorrent/torrent.hpp"
|
||||||
#include "libtorrent/allocate_resources.hpp"
|
|
||||||
#include "libtorrent/peer_request.hpp"
|
#include "libtorrent/peer_request.hpp"
|
||||||
#include "libtorrent/piece_block_progress.hpp"
|
#include "libtorrent/piece_block_progress.hpp"
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
|
@ -122,7 +121,15 @@ namespace libtorrent
|
||||||
msg_request,
|
msg_request,
|
||||||
msg_piece,
|
msg_piece,
|
||||||
msg_cancel,
|
msg_cancel,
|
||||||
|
// DHT extension
|
||||||
msg_dht_port,
|
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,
|
msg_extended = 20,
|
||||||
|
|
||||||
|
@ -174,8 +181,17 @@ namespace libtorrent
|
||||||
void on_request(int received);
|
void on_request(int received);
|
||||||
void on_piece(int received);
|
void on_piece(int received);
|
||||||
void on_cancel(int received);
|
void on_cancel(int received);
|
||||||
|
|
||||||
|
// DHT extension
|
||||||
void on_dht_port(int received);
|
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(int received);
|
||||||
|
|
||||||
void on_extended_handshake();
|
void on_extended_handshake();
|
||||||
|
@ -201,7 +217,16 @@ namespace libtorrent
|
||||||
void write_metadata(std::pair<int, int> req);
|
void write_metadata(std::pair<int, int> req);
|
||||||
void write_metadata_request(std::pair<int, int> req);
|
void write_metadata_request(std::pair<int, int> req);
|
||||||
void write_keepalive();
|
void write_keepalive();
|
||||||
|
|
||||||
|
// DHT extension
|
||||||
void write_dht_port(int listen_port);
|
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_connected();
|
||||||
void on_metadata();
|
void on_metadata();
|
||||||
|
|
||||||
|
@ -325,6 +350,7 @@ namespace libtorrent
|
||||||
bool m_supports_extensions;
|
bool m_supports_extensions;
|
||||||
#endif
|
#endif
|
||||||
bool m_supports_dht_port;
|
bool m_supports_dht_port;
|
||||||
|
bool m_supports_fast;
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
// this is set to true after the encryption method has been
|
// this is set to true after the encryption method has been
|
||||||
|
|
|
@ -34,8 +34,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
//#define TORRENT_BUFFER_DEBUG
|
//#define TORRENT_BUFFER_DEBUG
|
||||||
|
|
||||||
#include "libtorrent/invariant_check.hpp"
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include "libtorrent/invariant_check.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent {
|
namespace libtorrent {
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define TORRENT_CONFIG_HPP_INCLUDED
|
#define TORRENT_CONFIG_HPP_INCLUDED
|
||||||
|
|
||||||
#include <boost/config.hpp>
|
#include <boost/config.hpp>
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
#if defined(__GNUC__) && __GNUC__ >= 4
|
#if defined(__GNUC__) && __GNUC__ >= 4
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
|
#include <boost/thread/recursive_mutex.hpp>
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
#include "libtorrent/time.hpp"
|
#include "libtorrent/time.hpp"
|
||||||
|
|
||||||
|
@ -88,6 +89,10 @@ private:
|
||||||
int m_half_open_limit;
|
int m_half_open_limit;
|
||||||
|
|
||||||
deadline_timer m_timer;
|
deadline_timer m_timer;
|
||||||
|
|
||||||
|
typedef boost::recursive_mutex mutex_t;
|
||||||
|
mutable mutex_t m_mutex;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
bool m_in_timeout_function;
|
bool m_in_timeout_function;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -80,3 +80,4 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TORRENT_DEBUG_HPP_INCLUDED
|
#endif // TORRENT_DEBUG_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
|
@ -64,10 +64,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include "libtorrent/size_type.hpp"
|
#include "libtorrent/size_type.hpp"
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
|
44
libtorrent/include/libtorrent/enum_net.hpp
Normal file
44
libtorrent/include/libtorrent/enum_net.hpp
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
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,6 +131,15 @@ namespace libtorrent
|
||||||
virtual bool on_bitfield(std::vector<bool> const& bitfield)
|
virtual bool on_bitfield(std::vector<bool> const& bitfield)
|
||||||
{ return false; }
|
{ 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)
|
virtual bool on_request(peer_request const& req)
|
||||||
{ return false; }
|
{ return false; }
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "libtorrent/peer_id.hpp"
|
#include "libtorrent/peer_id.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
@ -91,3 +92,4 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // TORRENT_FINGERPRINT_HPP_INCLUDED
|
#endif // TORRENT_FINGERPRINT_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef TORRENT_HASHER_HPP_INCLUDED
|
#ifndef TORRENT_HASHER_HPP_INCLUDED
|
||||||
#define TORRENT_HASHER_HPP_INCLUDED
|
#define TORRENT_HASHER_HPP_INCLUDED
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
|
|
||||||
#include "libtorrent/peer_id.hpp"
|
#include "libtorrent/peer_id.hpp"
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
|
|
||||||
#ifdef TORRENT_USE_OPENSSL
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
|
|
|
@ -44,13 +44,18 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
#include "libtorrent/http_tracker_connection.hpp"
|
#include "libtorrent/http_tracker_connection.hpp"
|
||||||
#include "libtorrent/time.hpp"
|
#include "libtorrent/time.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
|
||||||
|
struct http_connection;
|
||||||
|
|
||||||
typedef boost::function<void(asio::error_code const&
|
typedef boost::function<void(asio::error_code const&
|
||||||
, http_parser const&, char const* data, int size)> http_handler;
|
, http_parser const&, char const* data, int size)> http_handler;
|
||||||
|
|
||||||
|
typedef boost::function<void(http_connection&)> http_connect_handler;
|
||||||
|
|
||||||
// TODO: add bind interface
|
// TODO: add bind interface
|
||||||
|
|
||||||
// when bottled, the last two arguments to the handler
|
// when bottled, the last two arguments to the handler
|
||||||
|
@ -58,11 +63,13 @@ typedef boost::function<void(asio::error_code const&
|
||||||
struct http_connection : boost::enable_shared_from_this<http_connection>, boost::noncopyable
|
struct http_connection : boost::enable_shared_from_this<http_connection>, boost::noncopyable
|
||||||
{
|
{
|
||||||
http_connection(asio::io_service& ios, connection_queue& cc
|
http_connection(asio::io_service& ios, connection_queue& cc
|
||||||
, http_handler handler, bool bottled = true)
|
, http_handler const& handler, bool bottled = true
|
||||||
|
, http_connect_handler const& ch = http_connect_handler())
|
||||||
: m_sock(ios)
|
: m_sock(ios)
|
||||||
, m_read_pos(0)
|
, m_read_pos(0)
|
||||||
, m_resolver(ios)
|
, m_resolver(ios)
|
||||||
, m_handler(handler)
|
, m_handler(handler)
|
||||||
|
, m_connect_handler(ch)
|
||||||
, m_timer(ios)
|
, m_timer(ios)
|
||||||
, m_last_receive(time_now())
|
, m_last_receive(time_now())
|
||||||
, m_bottled(bottled)
|
, m_bottled(bottled)
|
||||||
|
@ -92,6 +99,8 @@ struct http_connection : boost::enable_shared_from_this<http_connection>, boost:
|
||||||
, time_duration timeout, bool handle_redirect = true);
|
, time_duration timeout, bool handle_redirect = true);
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
|
tcp::socket const& socket() const { return m_sock; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void on_resolve(asio::error_code const& e
|
void on_resolve(asio::error_code const& e
|
||||||
|
@ -112,6 +121,7 @@ private:
|
||||||
tcp::resolver m_resolver;
|
tcp::resolver m_resolver;
|
||||||
http_parser m_parser;
|
http_parser m_parser;
|
||||||
http_handler m_handler;
|
http_handler m_handler;
|
||||||
|
http_connect_handler m_connect_handler;
|
||||||
deadline_timer m_timer;
|
deadline_timer m_timer;
|
||||||
time_duration m_timeout;
|
time_duration m_timeout;
|
||||||
ptime m_last_receive;
|
ptime m_last_receive;
|
||||||
|
|
|
@ -73,6 +73,8 @@ namespace libtorrent
|
||||||
T header(char const* key) const;
|
T header(char const* key) const;
|
||||||
std::string const& protocol() const { return m_protocol; }
|
std::string const& protocol() const { return m_protocol; }
|
||||||
int status_code() const { return m_status_code; }
|
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; }
|
std::string message() const { return m_server_message; }
|
||||||
buffer::const_interval get_body() const;
|
buffer::const_interval get_body() const;
|
||||||
bool header_finished() const { return m_state == read_body; }
|
bool header_finished() const { return m_state == read_body; }
|
||||||
|
@ -85,6 +87,8 @@ namespace libtorrent
|
||||||
private:
|
private:
|
||||||
int m_recv_pos;
|
int m_recv_pos;
|
||||||
int m_status_code;
|
int m_status_code;
|
||||||
|
std::string m_method;
|
||||||
|
std::string m_path;
|
||||||
std::string m_protocol;
|
std::string m_protocol;
|
||||||
std::string m_server_message;
|
std::string m_server_message;
|
||||||
|
|
||||||
|
@ -176,3 +180,4 @@ namespace libtorrent
|
||||||
|
|
||||||
#endif // TORRENT_HTTP_TRACKER_CONNECTION_HPP_INCLUDED
|
#endif // TORRENT_HTTP_TRACKER_CONNECTION_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,14 +34,17 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define TORRENT_INTRUSIVE_PTR_BASE
|
#define TORRENT_INTRUSIVE_PTR_BASE
|
||||||
|
|
||||||
#include <boost/detail/atomic_count.hpp>
|
#include <boost/detail/atomic_count.hpp>
|
||||||
#include <cassert>
|
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
template<class T>
|
template<class T>
|
||||||
struct intrusive_ptr_base
|
struct intrusive_ptr_base
|
||||||
{
|
{
|
||||||
|
intrusive_ptr_base(const intrusive_ptr_base<T>& b)
|
||||||
|
: m_refs(0) {}
|
||||||
|
|
||||||
friend void intrusive_ptr_add_ref(intrusive_ptr_base<T> const* s)
|
friend void intrusive_ptr_add_ref(intrusive_ptr_base<T> const* s)
|
||||||
{
|
{
|
||||||
assert(s->m_refs >= 0);
|
assert(s->m_refs >= 0);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#ifndef TORRENT_INVARIANT_ACCESS_HPP_INCLUDED
|
#ifndef TORRENT_INVARIANT_ACCESS_HPP_INCLUDED
|
||||||
#define TORRENT_INVARIANT_ACCESS_HPP_INCLUDED
|
#define TORRENT_INVARIANT_ACCESS_HPP_INCLUDED
|
||||||
|
|
||||||
#include <cassert>
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,6 +33,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef TORRENT_IP_FILTER_HPP
|
#ifndef TORRENT_IP_FILTER_HPP
|
||||||
#define TORRENT_IP_FILTER_HPP
|
#define TORRENT_IP_FILTER_HPP
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push, 1)
|
#pragma warning(push, 1)
|
||||||
#endif
|
#endif
|
||||||
|
@ -48,8 +51,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
#include <set>
|
#include "libtorrent/assert.hpp"
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,7 +34,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define NODE_HPP
|
#define NODE_HPP
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
@ -45,6 +44,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <libtorrent/io.hpp>
|
#include <libtorrent/io.hpp>
|
||||||
#include <libtorrent/session_settings.hpp>
|
#include <libtorrent/session_settings.hpp>
|
||||||
|
#include <libtorrent/assert.hpp>
|
||||||
|
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
#include <boost/optional.hpp>
|
#include <boost/optional.hpp>
|
||||||
|
|
|
@ -33,10 +33,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define NODE_ID_HPP
|
#define NODE_ID_HPP
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
#include "libtorrent/peer_id.hpp"
|
#include "libtorrent/peer_id.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent { namespace dht
|
namespace libtorrent { namespace dht
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,6 +50,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <libtorrent/kademlia/node_entry.hpp>
|
#include <libtorrent/kademlia/node_entry.hpp>
|
||||||
#include <libtorrent/session_settings.hpp>
|
#include <libtorrent/session_settings.hpp>
|
||||||
#include <libtorrent/size_type.hpp>
|
#include <libtorrent/size_type.hpp>
|
||||||
|
#include <libtorrent/assert.hpp>
|
||||||
|
|
||||||
namespace libtorrent { namespace dht
|
namespace libtorrent { namespace dht
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
#include "libtorrent/peer_id.hpp"
|
#include "libtorrent/peer_id.hpp"
|
||||||
|
#include "libtorrent/broadcast_socket.hpp"
|
||||||
|
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
|
@ -58,35 +59,26 @@ public:
|
||||||
, peer_callback_t const& cb);
|
, peer_callback_t const& cb);
|
||||||
~lsd();
|
~lsd();
|
||||||
|
|
||||||
void rebind(address const& listen_interface);
|
// void rebind(address const& listen_interface);
|
||||||
|
|
||||||
void announce(sha1_hash const& ih, int listen_port);
|
void announce(sha1_hash const& ih, int listen_port);
|
||||||
void close();
|
void close();
|
||||||
|
|
||||||
private:
|
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 resend_announce(asio::error_code const& e, std::string msg);
|
||||||
void on_announce(asio::error_code const& e
|
void on_announce(udp::endpoint const& from, char* buffer
|
||||||
, std::size_t bytes_transferred);
|
, std::size_t bytes_transferred);
|
||||||
void setup_receive();
|
// void setup_receive();
|
||||||
|
|
||||||
peer_callback_t m_callback;
|
peer_callback_t m_callback;
|
||||||
|
|
||||||
// current retry count
|
// current retry count
|
||||||
int m_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
|
// the udp socket used to send and receive
|
||||||
// multicast messages on
|
// multicast messages on
|
||||||
datagram_socket m_socket;
|
broadcast_socket m_socket;
|
||||||
|
|
||||||
// used to resend udp packets in case
|
// used to resend udp packets in case
|
||||||
// they time out
|
// they time out
|
||||||
|
|
|
@ -35,13 +35,12 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef TORRENT_PE_CRYPTO_HPP_INCLUDED
|
#ifndef TORRENT_PE_CRYPTO_HPP_INCLUDED
|
||||||
#define TORRENT_PE_CRYPTO_HPP_INCLUDED
|
#define TORRENT_PE_CRYPTO_HPP_INCLUDED
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
|
|
||||||
#include <openssl/dh.h>
|
#include <openssl/dh.h>
|
||||||
#include <openssl/engine.h>
|
#include <openssl/engine.h>
|
||||||
#include <openssl/rc4.h>
|
#include <openssl/rc4.h>
|
||||||
|
|
||||||
#include "peer_id.hpp" // For sha1_hash
|
#include "libtorrent/peer_id.hpp" // For sha1_hash
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
|
|
@ -64,7 +64,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/alert.hpp"
|
#include "libtorrent/alert.hpp"
|
||||||
#include "libtorrent/torrent_handle.hpp"
|
#include "libtorrent/torrent_handle.hpp"
|
||||||
#include "libtorrent/torrent.hpp"
|
#include "libtorrent/torrent.hpp"
|
||||||
#include "libtorrent/allocate_resources.hpp"
|
|
||||||
#include "libtorrent/peer_request.hpp"
|
#include "libtorrent/peer_request.hpp"
|
||||||
#include "libtorrent/piece_block_progress.hpp"
|
#include "libtorrent/piece_block_progress.hpp"
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
|
@ -73,6 +72,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/policy.hpp"
|
#include "libtorrent/policy.hpp"
|
||||||
#include "libtorrent/socket_type.hpp"
|
#include "libtorrent/socket_type.hpp"
|
||||||
#include "libtorrent/intrusive_ptr_base.hpp"
|
#include "libtorrent/intrusive_ptr_base.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
@ -131,6 +131,8 @@ namespace libtorrent
|
||||||
enum peer_speed_t { slow, medium, fast };
|
enum peer_speed_t { slow, medium, fast };
|
||||||
peer_speed_t peer_speed();
|
peer_speed_t peer_speed();
|
||||||
|
|
||||||
|
void send_allowed_set();
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||||
void add_extension(boost::shared_ptr<peer_plugin>);
|
void add_extension(boost::shared_ptr<peer_plugin>);
|
||||||
#endif
|
#endif
|
||||||
|
@ -151,11 +153,17 @@ namespace libtorrent
|
||||||
int upload_limit() const { return m_upload_limit; }
|
int upload_limit() const { return m_upload_limit; }
|
||||||
int download_limit() const { return m_download_limit; }
|
int download_limit() const { return m_download_limit; }
|
||||||
|
|
||||||
bool prefer_whole_pieces() const
|
int prefer_whole_pieces() const
|
||||||
{ return m_prefer_whole_pieces; }
|
{
|
||||||
|
if (on_parole()) return 1;
|
||||||
|
return m_prefer_whole_pieces;
|
||||||
|
}
|
||||||
|
|
||||||
void prefer_whole_pieces(bool b)
|
bool on_parole() const
|
||||||
{ m_prefer_whole_pieces = b; }
|
{ return peer_info_struct() && peer_info_struct()->on_parole; }
|
||||||
|
|
||||||
|
void prefer_whole_pieces(int num)
|
||||||
|
{ m_prefer_whole_pieces = num; }
|
||||||
|
|
||||||
bool request_large_blocks() const
|
bool request_large_blocks() const
|
||||||
{ return m_request_large_blocks; }
|
{ return m_request_large_blocks; }
|
||||||
|
@ -186,9 +194,9 @@ namespace libtorrent
|
||||||
void set_pid(const peer_id& pid) { m_peer_id = pid; }
|
void set_pid(const peer_id& pid) { m_peer_id = pid; }
|
||||||
bool has_piece(int i) const;
|
bool has_piece(int i) const;
|
||||||
|
|
||||||
const std::deque<piece_block>& download_queue() const;
|
std::deque<piece_block> const& download_queue() const;
|
||||||
const std::deque<piece_block>& request_queue() const;
|
std::deque<piece_block> const& request_queue() const;
|
||||||
const std::deque<peer_request>& upload_queue() const;
|
std::deque<peer_request> const& upload_queue() const;
|
||||||
|
|
||||||
bool is_interesting() const { return m_interesting; }
|
bool is_interesting() const { return m_interesting; }
|
||||||
bool is_choked() const { return m_choked; }
|
bool is_choked() const { return m_choked; }
|
||||||
|
@ -211,12 +219,14 @@ namespace libtorrent
|
||||||
void add_stat(size_type downloaded, size_type uploaded);
|
void add_stat(size_type downloaded, size_type uploaded);
|
||||||
|
|
||||||
// is called once every second by the main loop
|
// is called once every second by the main loop
|
||||||
void second_tick(float tick_interval);
|
void second_tick(float tick_interval) throw();
|
||||||
|
|
||||||
boost::shared_ptr<socket_type> get_socket() const { return m_socket; }
|
boost::shared_ptr<socket_type> get_socket() const { return m_socket; }
|
||||||
tcp::endpoint const& remote() const { return m_remote; }
|
tcp::endpoint const& remote() const { return m_remote; }
|
||||||
|
|
||||||
std::vector<bool> const& get_bitfield() const;
|
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();
|
void timed_out();
|
||||||
// this will cause this peer_connection to be disconnected.
|
// this will cause this peer_connection to be disconnected.
|
||||||
|
@ -294,8 +304,15 @@ namespace libtorrent
|
||||||
void incoming_piece(peer_request const& p, char const* data);
|
void incoming_piece(peer_request const& p, char const* data);
|
||||||
void incoming_piece_fragment();
|
void incoming_piece_fragment();
|
||||||
void incoming_cancel(peer_request const& r);
|
void incoming_cancel(peer_request const& r);
|
||||||
|
|
||||||
void incoming_dht_port(int listen_port);
|
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
|
// the following functions appends messages
|
||||||
// to the send buffer
|
// to the send buffer
|
||||||
void send_choke();
|
void send_choke();
|
||||||
|
@ -373,6 +390,9 @@ namespace libtorrent
|
||||||
virtual void write_keepalive() = 0;
|
virtual void write_keepalive() = 0;
|
||||||
virtual void write_piece(peer_request const& r, char const* buffer) = 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_connected() = 0;
|
||||||
virtual void on_tick() {}
|
virtual void on_tick() {}
|
||||||
|
|
||||||
|
@ -482,6 +502,11 @@ namespace libtorrent
|
||||||
// the time we sent a request to
|
// the time we sent a request to
|
||||||
// this peer the last time
|
// this peer the last time
|
||||||
ptime m_last_request;
|
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_packet_size;
|
||||||
int m_recv_pos;
|
int m_recv_pos;
|
||||||
|
@ -529,7 +554,7 @@ namespace libtorrent
|
||||||
// set to the torrent it belongs to.
|
// set to the torrent it belongs to.
|
||||||
boost::weak_ptr<torrent> m_torrent;
|
boost::weak_ptr<torrent> m_torrent;
|
||||||
// is true if it was we that connected to the peer
|
// is true if it was we that connected to the peer
|
||||||
// and false if we got an incomming connection
|
// and false if we got an incoming connection
|
||||||
// could be considered: true = local, false = remote
|
// could be considered: true = local, false = remote
|
||||||
bool m_active;
|
bool m_active;
|
||||||
|
|
||||||
|
@ -563,6 +588,10 @@ namespace libtorrent
|
||||||
|
|
||||||
// the pieces the other end have
|
// the pieces the other end have
|
||||||
std::vector<bool> m_have_piece;
|
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
|
// the number of pieces this peer
|
||||||
// has. Must be the same as
|
// has. Must be the same as
|
||||||
|
@ -575,7 +604,7 @@ namespace libtorrent
|
||||||
std::deque<peer_request> m_requests;
|
std::deque<peer_request> m_requests;
|
||||||
|
|
||||||
// the blocks we have reserved in the piece
|
// the blocks we have reserved in the piece
|
||||||
// picker and will send to this peer.
|
// picker and will request from this peer.
|
||||||
std::deque<piece_block> m_request_queue;
|
std::deque<piece_block> m_request_queue;
|
||||||
|
|
||||||
// the queue of blocks we have requested
|
// the queue of blocks we have requested
|
||||||
|
@ -643,12 +672,13 @@ namespace libtorrent
|
||||||
bool m_writing;
|
bool m_writing;
|
||||||
bool m_reading;
|
bool m_reading;
|
||||||
|
|
||||||
// if set to true, this peer will always prefer
|
// if set to non-zero, this peer will always prefer
|
||||||
// to request entire pieces, rather than blocks.
|
// to request entire n pieces, rather than blocks.
|
||||||
// if it is false, the download rate limit setting
|
// where n is the value of this variable.
|
||||||
|
// if it is 0, the download rate limit setting
|
||||||
// will be used to determine if whole pieces
|
// will be used to determine if whole pieces
|
||||||
// are preferred.
|
// are preferred.
|
||||||
bool m_prefer_whole_pieces;
|
int m_prefer_whole_pieces;
|
||||||
|
|
||||||
// if this is true, the blocks picked by the piece
|
// if this is true, the blocks picked by the piece
|
||||||
// picker will be merged before passed to the
|
// picker will be merged before passed to the
|
||||||
|
@ -695,6 +725,18 @@ namespace libtorrent
|
||||||
// was last updated
|
// was last updated
|
||||||
ptime m_remote_dl_update;
|
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
|
// the number of bytes send to the disk-io
|
||||||
// thread that hasn't yet been completely written.
|
// thread that hasn't yet been completely written.
|
||||||
int m_outstanding_writing_bytes;
|
int m_outstanding_writing_bytes;
|
||||||
|
|
|
@ -35,12 +35,12 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <cassert>
|
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,10 +56,11 @@ namespace libtorrent
|
||||||
connecting = 0x80,
|
connecting = 0x80,
|
||||||
queued = 0x100,
|
queued = 0x100,
|
||||||
on_parole = 0x200,
|
on_parole = 0x200,
|
||||||
seed = 0x400
|
seed = 0x400,
|
||||||
|
optimistic_unchoke = 0x800
|
||||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||||
, rc4_encrypted = 0x800,
|
, rc4_encrypted = 0x100000,
|
||||||
plaintext_encrypted = 0x1000
|
plaintext_encrypted = 0x200000
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -116,6 +117,11 @@ namespace libtorrent
|
||||||
// for yet
|
// for yet
|
||||||
int download_queue_length;
|
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
|
// this is the number of requests
|
||||||
// the peer has sent to us
|
// the peer has sent to us
|
||||||
// that we haven't sent yet
|
// that we haven't sent yet
|
||||||
|
|
|
@ -35,7 +35,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <cassert>
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -52,6 +51,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
#include "libtorrent/session_settings.hpp"
|
#include "libtorrent/session_settings.hpp"
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
@ -191,11 +191,33 @@ namespace libtorrent
|
||||||
// THIS IS DONE BY THE peer_connection::send_request() MEMBER FUNCTION!
|
// THIS IS DONE BY THE peer_connection::send_request() MEMBER FUNCTION!
|
||||||
// The last argument is the policy::peer pointer for the peer that
|
// The last argument is the policy::peer pointer for the peer that
|
||||||
// we'll download from.
|
// we'll download from.
|
||||||
void pick_pieces(const std::vector<bool>& pieces
|
void pick_pieces(std::vector<bool> const& pieces
|
||||||
, std::vector<piece_block>& interesting_blocks
|
, std::vector<piece_block>& interesting_blocks
|
||||||
, int num_pieces, bool prefer_whole_pieces
|
, int num_pieces, int prefer_whole_pieces
|
||||||
, void* peer, piece_state_t speed
|
, void* peer, piece_state_t speed
|
||||||
, bool rarest_first) const;
|
, 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;
|
||||||
|
|
||||||
// clears the peer pointer in all downloading pieces with this
|
// clears the peer pointer in all downloading pieces with this
|
||||||
// peer pointer
|
// peer pointer
|
||||||
|
@ -253,6 +275,8 @@ namespace libtorrent
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
// used in debug mode
|
// used in debug mode
|
||||||
void check_invariant(const torrent* t = 0) const;
|
void check_invariant(const torrent* t = 0) const;
|
||||||
|
void verify_pick(std::vector<piece_block> const& picked
|
||||||
|
, std::vector<bool> const& bitfield) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// functor that compares indices on downloading_pieces
|
// functor that compares indices on downloading_pieces
|
||||||
|
@ -271,6 +295,10 @@ namespace libtorrent
|
||||||
|
|
||||||
private:
|
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
|
struct piece_pos
|
||||||
{
|
{
|
||||||
piece_pos() {}
|
piece_pos() {}
|
||||||
|
@ -320,9 +348,9 @@ namespace libtorrent
|
||||||
|
|
||||||
int priority(int limit) const
|
int priority(int limit) const
|
||||||
{
|
{
|
||||||
if (filtered() || have()) return 0;
|
if (downloading || filtered() || have()) return 0;
|
||||||
// pieces we are currently downloading have high priority
|
// pieces we are currently downloading have high priority
|
||||||
int prio = downloading ? (std::min)(1, int(peer_count)) : peer_count * 2;
|
int prio = peer_count * 2;
|
||||||
// if the peer_count is 0 or 1, the priority cannot be higher
|
// if the peer_count is 0 or 1, the priority cannot be higher
|
||||||
if (prio <= 1) return prio;
|
if (prio <= 1) return prio;
|
||||||
if (prio >= limit * 2) prio = limit * 2;
|
if (prio >= limit * 2) prio = limit * 2;
|
||||||
|
@ -358,14 +386,6 @@ namespace libtorrent
|
||||||
void move(int vec_index, int elem_index);
|
void move(int vec_index, int elem_index);
|
||||||
void sort_piece(std::vector<downloading_piece>::iterator dp);
|
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();
|
downloading_piece& add_download_piece();
|
||||||
void erase_download_piece(std::vector<downloading_piece>::iterator i);
|
void erase_download_piece(std::vector<downloading_piece>::iterator i);
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ namespace libtorrent
|
||||||
void new_connection(peer_connection& c);
|
void new_connection(peer_connection& c);
|
||||||
|
|
||||||
// the given connection was just closed
|
// the given connection was just closed
|
||||||
void connection_closed(const peer_connection& c);
|
void connection_closed(const peer_connection& c) throw();
|
||||||
|
|
||||||
// the peer has got at least one interesting piece
|
// the peer has got at least one interesting piece
|
||||||
void peer_is_interesting(peer_connection& c);
|
void peer_is_interesting(peer_connection& c);
|
||||||
|
@ -155,6 +155,13 @@ namespace libtorrent
|
||||||
// this is true if the peer is a seed
|
// this is true if the peer is a seed
|
||||||
bool 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 time when this peer was optimistically unchoked
|
||||||
// the last time.
|
// the last time.
|
||||||
libtorrent::ptime last_optimistically_unchoked;
|
libtorrent::ptime last_optimistically_unchoked;
|
||||||
|
@ -203,15 +210,7 @@ namespace libtorrent
|
||||||
peer_connection* connection;
|
peer_connection* connection;
|
||||||
};
|
};
|
||||||
|
|
||||||
int num_peers() const
|
int num_peers() const { return m_peers.size(); }
|
||||||
{
|
|
||||||
return m_peers.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
int num_uploads() const
|
|
||||||
{
|
|
||||||
return m_num_unchoked;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef std::list<peer>::iterator iterator;
|
typedef std::list<peer>::iterator iterator;
|
||||||
typedef std::list<peer>::const_iterator const_iterator;
|
typedef std::list<peer>::const_iterator const_iterator;
|
||||||
|
@ -219,9 +218,10 @@ namespace libtorrent
|
||||||
iterator end_peer() { return m_peers.end(); }
|
iterator end_peer() { return m_peers.end(); }
|
||||||
|
|
||||||
bool connect_one_peer();
|
bool connect_one_peer();
|
||||||
|
bool disconnect_one_peer();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/*
|
||||||
bool unchoke_one_peer();
|
bool unchoke_one_peer();
|
||||||
void choke_one_peer();
|
void choke_one_peer();
|
||||||
iterator find_choke_candidate();
|
iterator find_choke_candidate();
|
||||||
|
@ -233,8 +233,7 @@ namespace libtorrent
|
||||||
void seed_choke_one_peer();
|
void seed_choke_one_peer();
|
||||||
iterator find_seed_choke_candidate();
|
iterator find_seed_choke_candidate();
|
||||||
iterator find_seed_unchoke_candidate();
|
iterator find_seed_unchoke_candidate();
|
||||||
|
*/
|
||||||
bool disconnect_one_peer();
|
|
||||||
iterator find_disconnect_candidate();
|
iterator find_disconnect_candidate();
|
||||||
iterator find_connect_candidate();
|
iterator find_connect_candidate();
|
||||||
|
|
||||||
|
@ -242,10 +241,6 @@ namespace libtorrent
|
||||||
|
|
||||||
torrent* m_torrent;
|
torrent* m_torrent;
|
||||||
|
|
||||||
// the number of unchoked peers
|
|
||||||
// at any given time
|
|
||||||
int m_num_unchoked;
|
|
||||||
|
|
||||||
// free download we have got that hasn't
|
// free download we have got that hasn't
|
||||||
// been distributed yet.
|
// been distributed yet.
|
||||||
size_type m_available_free_upload;
|
size_type m_available_free_upload;
|
||||||
|
@ -253,7 +248,7 @@ namespace libtorrent
|
||||||
// if there is a connection limit,
|
// if there is a connection limit,
|
||||||
// we disconnect one peer every minute in hope of
|
// we disconnect one peer every minute in hope of
|
||||||
// establishing a connection with a better peer
|
// establishing a connection with a better peer
|
||||||
ptime m_last_optimistic_disconnect;
|
// ptime m_last_optimistic_disconnect;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "libtorrent/config.hpp"
|
||||||
#include "libtorrent/torrent_handle.hpp"
|
#include "libtorrent/torrent_handle.hpp"
|
||||||
#include "libtorrent/entry.hpp"
|
#include "libtorrent/entry.hpp"
|
||||||
#include "libtorrent/alert.hpp"
|
#include "libtorrent/alert.hpp"
|
||||||
|
@ -60,7 +61,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/version.hpp"
|
#include "libtorrent/version.hpp"
|
||||||
#include "libtorrent/fingerprint.hpp"
|
#include "libtorrent/fingerprint.hpp"
|
||||||
|
|
||||||
#include "libtorrent/resource_request.hpp"
|
|
||||||
#include "libtorrent/storage.hpp"
|
#include "libtorrent/storage.hpp"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -141,22 +141,16 @@ namespace libtorrent
|
||||||
, fs::path const& save_path
|
, fs::path const& save_path
|
||||||
, entry const& resume_data = entry()
|
, entry const& resume_data = entry()
|
||||||
, bool compact_mode = true
|
, bool compact_mode = true
|
||||||
, int block_size = 16 * 1024
|
, bool paused = false
|
||||||
, storage_constructor_type sc = default_storage_constructor);
|
, storage_constructor_type sc = default_storage_constructor) TORRENT_DEPRECATED;
|
||||||
|
|
||||||
// ==== deprecated, this is for backwards compatibility only
|
|
||||||
// instead, use one of the other add_torrent overloads
|
|
||||||
torrent_handle add_torrent(
|
torrent_handle add_torrent(
|
||||||
entry const& e
|
boost::intrusive_ptr<torrent_info> ti
|
||||||
, fs::path const& save_path
|
, fs::path const& save_path
|
||||||
, entry const& resume_data = entry()
|
, entry const& resume_data = entry()
|
||||||
, bool compact_mode = true
|
, bool compact_mode = true
|
||||||
, int block_size = 16 * 1024
|
, bool paused = false
|
||||||
, storage_constructor_type sc = default_storage_constructor) TORRENT_DEPRECATED
|
, storage_constructor_type sc = default_storage_constructor);
|
||||||
{
|
|
||||||
return add_torrent(torrent_info(e), save_path, resume_data
|
|
||||||
, compact_mode, block_size, sc);
|
|
||||||
}
|
|
||||||
|
|
||||||
torrent_handle add_torrent(
|
torrent_handle add_torrent(
|
||||||
char const* tracker_url
|
char const* tracker_url
|
||||||
|
@ -165,7 +159,7 @@ namespace libtorrent
|
||||||
, fs::path const& save_path
|
, fs::path const& save_path
|
||||||
, entry const& resume_data = entry()
|
, entry const& resume_data = entry()
|
||||||
, bool compact_mode = true
|
, bool compact_mode = true
|
||||||
, int block_size = 16 * 1024
|
, bool paused = false
|
||||||
, storage_constructor_type sc = default_storage_constructor);
|
, storage_constructor_type sc = default_storage_constructor);
|
||||||
|
|
||||||
session_proxy abort() { return session_proxy(m_impl); }
|
session_proxy abort() { return session_proxy(m_impl); }
|
||||||
|
@ -243,6 +237,7 @@ namespace libtorrent
|
||||||
|
|
||||||
int upload_rate_limit() const;
|
int upload_rate_limit() const;
|
||||||
int download_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_upload_rate_limit(int bytes_per_second);
|
||||||
void set_download_rate_limit(int bytes_per_second);
|
void set_download_rate_limit(int bytes_per_second);
|
||||||
|
@ -265,12 +260,6 @@ namespace libtorrent
|
||||||
void stop_natpmp();
|
void stop_natpmp();
|
||||||
void stop_upnp();
|
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:
|
private:
|
||||||
|
|
||||||
// just a way to initialize boost.filesystem
|
// just a way to initialize boost.filesystem
|
||||||
|
|
|
@ -105,9 +105,11 @@ namespace libtorrent
|
||||||
, send_redundant_have(false)
|
, send_redundant_have(false)
|
||||||
, lazy_bitfields(true)
|
, lazy_bitfields(true)
|
||||||
, inactivity_timeout(600)
|
, inactivity_timeout(600)
|
||||||
, unchoke_interval(20)
|
, unchoke_interval(15)
|
||||||
|
, optimistic_unchoke_multiplier(4)
|
||||||
, num_want(200)
|
, num_want(200)
|
||||||
, initial_picker_threshold(4)
|
, initial_picker_threshold(4)
|
||||||
|
, allowed_fast_set_size(10)
|
||||||
, max_outstanding_disk_bytes_per_connection(64 * 1024)
|
, max_outstanding_disk_bytes_per_connection(64 * 1024)
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
, use_dht_as_fallback(true)
|
, use_dht_as_fallback(true)
|
||||||
|
@ -241,6 +243,10 @@ namespace libtorrent
|
||||||
// the number of seconds between chokes/unchokes
|
// the number of seconds between chokes/unchokes
|
||||||
int unchoke_interval;
|
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
|
// if this is set, this IP will be reported do the
|
||||||
// tracker in the ip= parameter.
|
// tracker in the ip= parameter.
|
||||||
address announce_ip;
|
address announce_ip;
|
||||||
|
@ -252,6 +258,10 @@ namespace libtorrent
|
||||||
// random pieces instead of rarest first.
|
// random pieces instead of rarest first.
|
||||||
int initial_picker_threshold;
|
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
|
// the maximum number of bytes a connection may have
|
||||||
// pending in the disk write queue before its download
|
// pending in the disk write queue before its download
|
||||||
// rate is being throttled. This prevents fast downloads
|
// rate is being throttled. This prevents fast downloads
|
||||||
|
|
|
@ -40,6 +40,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/size_type.hpp"
|
#include "libtorrent/size_type.hpp"
|
||||||
#include "libtorrent/invariant_check.hpp"
|
#include "libtorrent/invariant_check.hpp"
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
|
|
@ -43,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <boost/limits.hpp>
|
#include <boost/limits.hpp>
|
||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/intrusive_ptr.hpp>
|
||||||
#include <boost/filesystem/path.hpp>
|
#include <boost/filesystem/path.hpp>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -147,10 +148,11 @@ namespace libtorrent
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef storage_interface* (&storage_constructor_type)(
|
typedef storage_interface* (&storage_constructor_type)(
|
||||||
torrent_info const&, fs::path const&
|
boost::intrusive_ptr<torrent_info const>, fs::path const&
|
||||||
, file_pool&);
|
, file_pool&);
|
||||||
|
|
||||||
TORRENT_EXPORT storage_interface* default_storage_constructor(torrent_info const& ti
|
TORRENT_EXPORT storage_interface* default_storage_constructor(
|
||||||
|
boost::intrusive_ptr<torrent_info const> ti
|
||||||
, fs::path const& path, file_pool& fp);
|
, fs::path const& path, file_pool& fp);
|
||||||
|
|
||||||
// returns true if the filesystem the path relies on supports
|
// returns true if the filesystem the path relies on supports
|
||||||
|
@ -169,7 +171,7 @@ namespace libtorrent
|
||||||
|
|
||||||
piece_manager(
|
piece_manager(
|
||||||
boost::shared_ptr<void> const& torrent
|
boost::shared_ptr<void> const& torrent
|
||||||
, torrent_info const& ti
|
, boost::intrusive_ptr<torrent_info const> ti
|
||||||
, fs::path const& path
|
, fs::path const& path
|
||||||
, file_pool& fp
|
, file_pool& fp
|
||||||
, disk_io_thread& io
|
, disk_io_thread& io
|
||||||
|
@ -199,7 +201,8 @@ namespace libtorrent
|
||||||
|
|
||||||
void async_read(
|
void async_read(
|
||||||
peer_request const& r
|
peer_request const& r
|
||||||
, boost::function<void(int, disk_io_job const&)> const& handler);
|
, boost::function<void(int, disk_io_job const&)> const& handler
|
||||||
|
, char* buffer = 0);
|
||||||
|
|
||||||
void async_write(
|
void async_write(
|
||||||
peer_request const& r
|
peer_request const& r
|
||||||
|
@ -227,7 +230,7 @@ namespace libtorrent
|
||||||
{ return m_compact_mode; }
|
{ return m_compact_mode; }
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
std::string name() const { return m_info.name(); }
|
std::string name() const { return m_info->name(); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -283,7 +286,7 @@ namespace libtorrent
|
||||||
// a bitmask representing the pieces we have
|
// a bitmask representing the pieces we have
|
||||||
std::vector<bool> m_have_piece;
|
std::vector<bool> m_have_piece;
|
||||||
|
|
||||||
torrent_info const& m_info;
|
boost::intrusive_ptr<torrent_info const> m_info;
|
||||||
|
|
||||||
// slots that haven't had any file storage allocated
|
// slots that haven't had any file storage allocated
|
||||||
std::vector<int> m_unallocated_slots;
|
std::vector<int> m_unallocated_slots;
|
||||||
|
@ -313,12 +316,6 @@ namespace libtorrent
|
||||||
|
|
||||||
mutable boost::recursive_mutex m_mutex;
|
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 {
|
enum {
|
||||||
// the default initial state
|
// the default initial state
|
||||||
state_none,
|
state_none,
|
||||||
|
@ -333,6 +330,11 @@ namespace libtorrent
|
||||||
} m_state;
|
} m_state;
|
||||||
int m_current_slot;
|
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;
|
std::vector<char> m_piece_data;
|
||||||
|
|
||||||
// this maps a piece hash to piece index. It will be
|
// this maps a piece hash to piece index. It will be
|
||||||
|
@ -340,6 +342,8 @@ namespace libtorrent
|
||||||
// isn't needed)
|
// isn't needed)
|
||||||
std::multimap<sha1_hash, int> m_hash_to_piece;
|
std::multimap<sha1_hash, int> m_hash_to_piece;
|
||||||
|
|
||||||
|
// this map contains partial hashes for downloading
|
||||||
|
// pieces.
|
||||||
std::map<int, partial_hash> m_piece_hasher;
|
std::map<int, partial_hash> m_piece_hasher;
|
||||||
|
|
||||||
disk_io_thread& m_io_thread;
|
disk_io_thread& m_io_thread;
|
||||||
|
|
|
@ -55,6 +55,7 @@ namespace libtorrent
|
||||||
|| _POSIX_MONOTONIC_CLOCK < 0)) || defined (TORRENT_USE_BOOST_DATE_TIME)
|
|| _POSIX_MONOTONIC_CLOCK < 0)) || defined (TORRENT_USE_BOOST_DATE_TIME)
|
||||||
|
|
||||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
@ -85,6 +86,7 @@ namespace libtorrent
|
||||||
|
|
||||||
#include <asio/time_traits.hpp>
|
#include <asio/time_traits.hpp>
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
@ -170,6 +172,7 @@ namespace asio
|
||||||
|
|
||||||
#include <mach/mach_time.h>
|
#include <mach/mach_time.h>
|
||||||
#include <boost/cstdint.hpp>
|
#include <boost/cstdint.hpp>
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
// high precision timer for darwin intel and ppc
|
// high precision timer for darwin intel and ppc
|
||||||
|
|
||||||
|
@ -249,6 +252,7 @@ namespace libtorrent
|
||||||
#define WIN32_LEAN_AND_MEAN
|
#define WIN32_LEAN_AND_MEAN
|
||||||
#endif
|
#endif
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
@ -335,6 +339,7 @@ namespace libtorrent
|
||||||
#elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
|
#elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
|
||||||
|
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
|
|
@ -62,13 +62,13 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/tracker_manager.hpp"
|
#include "libtorrent/tracker_manager.hpp"
|
||||||
#include "libtorrent/stat.hpp"
|
#include "libtorrent/stat.hpp"
|
||||||
#include "libtorrent/alert.hpp"
|
#include "libtorrent/alert.hpp"
|
||||||
#include "libtorrent/resource_request.hpp"
|
|
||||||
#include "libtorrent/piece_picker.hpp"
|
#include "libtorrent/piece_picker.hpp"
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
#include "libtorrent/escape_string.hpp"
|
#include "libtorrent/escape_string.hpp"
|
||||||
#include "libtorrent/bandwidth_manager.hpp"
|
#include "libtorrent/bandwidth_manager.hpp"
|
||||||
#include "libtorrent/storage.hpp"
|
#include "libtorrent/storage.hpp"
|
||||||
#include "libtorrent/hasher.hpp"
|
#include "libtorrent/hasher.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
@ -98,13 +98,13 @@ namespace libtorrent
|
||||||
torrent(
|
torrent(
|
||||||
aux::session_impl& ses
|
aux::session_impl& ses
|
||||||
, aux::checker_impl& checker
|
, aux::checker_impl& checker
|
||||||
, torrent_info const& tf
|
, boost::intrusive_ptr<torrent_info> tf
|
||||||
, fs::path const& save_path
|
, fs::path const& save_path
|
||||||
, tcp::endpoint const& net_interface
|
, tcp::endpoint const& net_interface
|
||||||
, bool compact_mode
|
, bool compact_mode
|
||||||
, int block_size
|
, int block_size
|
||||||
, session_settings const& s
|
, storage_constructor_type sc
|
||||||
, storage_constructor_type sc);
|
, bool paused);
|
||||||
|
|
||||||
// used with metadata-less torrents
|
// used with metadata-less torrents
|
||||||
// (the metadata is downloaded from the peers)
|
// (the metadata is downloaded from the peers)
|
||||||
|
@ -118,8 +118,8 @@ namespace libtorrent
|
||||||
, tcp::endpoint const& net_interface
|
, tcp::endpoint const& net_interface
|
||||||
, bool compact_mode
|
, bool compact_mode
|
||||||
, int block_size
|
, int block_size
|
||||||
, session_settings const& s
|
, storage_constructor_type sc
|
||||||
, storage_constructor_type sc);
|
, bool paused);
|
||||||
|
|
||||||
~torrent();
|
~torrent();
|
||||||
|
|
||||||
|
@ -154,10 +154,6 @@ namespace libtorrent
|
||||||
bool verify_resume_data(entry& rd, std::string& error)
|
bool verify_resume_data(entry& rd, std::string& error)
|
||||||
{ assert(m_storage); return m_storage->verify_resume_data(rd, 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);
|
void second_tick(stat& accumulator, float tick_interval);
|
||||||
|
|
||||||
// debug purpose only
|
// debug purpose only
|
||||||
|
@ -254,6 +250,15 @@ namespace libtorrent
|
||||||
void remove_url_seed(std::string const& url)
|
void remove_url_seed(std::string const& url)
|
||||||
{ m_web_seeds.erase(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
|
// used by peer_connection to attach itself to a torrent
|
||||||
// since incoming connections don't know what torrent
|
// since incoming connections don't know what torrent
|
||||||
// they're a part of until they have received an info_hash.
|
// they're a part of until they have received an info_hash.
|
||||||
|
@ -465,14 +470,14 @@ namespace libtorrent
|
||||||
bool is_seed() const
|
bool is_seed() const
|
||||||
{
|
{
|
||||||
return valid_metadata()
|
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
|
// this is true if we have all the pieces that we want
|
||||||
bool is_finished() const
|
bool is_finished() const
|
||||||
{
|
{
|
||||||
if (is_seed()) return true;
|
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;
|
- m_num_pieces - m_picker->num_filtered() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +499,7 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
piece_manager& filesystem();
|
piece_manager& filesystem();
|
||||||
torrent_info const& torrent_file() const
|
torrent_info const& torrent_file() const
|
||||||
{ return m_torrent_file; }
|
{ return *m_torrent_file; }
|
||||||
|
|
||||||
std::vector<announce_entry> const& trackers() const
|
std::vector<announce_entry> const& trackers() const
|
||||||
{ return m_trackers; }
|
{ return m_trackers; }
|
||||||
|
@ -516,11 +521,6 @@ namespace libtorrent
|
||||||
// --------------------------------------------
|
// --------------------------------------------
|
||||||
// RESOURCE MANAGEMENT
|
// 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_upload_limit(tcp::endpoint ip, int limit);
|
||||||
void set_peer_download_limit(tcp::endpoint ip, int limit);
|
void set_peer_download_limit(tcp::endpoint ip, int limit);
|
||||||
|
|
||||||
|
@ -530,7 +530,9 @@ namespace libtorrent
|
||||||
int download_limit() const;
|
int download_limit() const;
|
||||||
|
|
||||||
void set_max_uploads(int limit);
|
void set_max_uploads(int limit);
|
||||||
|
int max_uploads() const { return m_max_uploads; }
|
||||||
void set_max_connections(int limit);
|
void set_max_connections(int limit);
|
||||||
|
int max_connections() const { return m_max_connections; }
|
||||||
void move_storage(fs::path const& save_path);
|
void move_storage(fs::path const& save_path);
|
||||||
|
|
||||||
// unless this returns true, new connections must wait
|
// unless this returns true, new connections must wait
|
||||||
|
@ -538,7 +540,7 @@ namespace libtorrent
|
||||||
bool ready_for_connections() const
|
bool ready_for_connections() const
|
||||||
{ return m_connections_initialized; }
|
{ return m_connections_initialized; }
|
||||||
bool valid_metadata() const
|
bool valid_metadata() const
|
||||||
{ return m_torrent_file.is_valid(); }
|
{ return m_torrent_file->is_valid(); }
|
||||||
|
|
||||||
// parses the info section from the given
|
// parses the info section from the given
|
||||||
// bencoded tree and moves the torrent
|
// bencoded tree and moves the torrent
|
||||||
|
@ -562,7 +564,7 @@ namespace libtorrent
|
||||||
|
|
||||||
void update_peer_interest();
|
void update_peer_interest();
|
||||||
|
|
||||||
torrent_info m_torrent_file;
|
boost::intrusive_ptr<torrent_info> m_torrent_file;
|
||||||
|
|
||||||
// is set to true when the torrent has
|
// is set to true when the torrent has
|
||||||
// been aborted.
|
// been aborted.
|
||||||
|
@ -705,9 +707,9 @@ namespace libtorrent
|
||||||
// determine the timeout until next try.
|
// determine the timeout until next try.
|
||||||
int m_failed_trackers;
|
int m_failed_trackers;
|
||||||
|
|
||||||
// this is a counter that is increased every
|
// this is a counter that is decreased every
|
||||||
// second, and when it reaches 10, the policy::pulse()
|
// second, and when it reaches 0, the policy::pulse()
|
||||||
// is called and the time scaler is reset to 0.
|
// is called and the time scaler is reset to 10.
|
||||||
int m_time_scaler;
|
int m_time_scaler;
|
||||||
|
|
||||||
// the bitmask that says which pieces we have
|
// the bitmask that says which pieces we have
|
||||||
|
@ -775,6 +777,15 @@ namespace libtorrent
|
||||||
|
|
||||||
storage_constructor_type m_storage_constructor;
|
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
|
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||||
typedef std::list<boost::shared_ptr<torrent_plugin> > extension_list_t;
|
typedef std::list<boost::shared_ptr<torrent_plugin> > extension_list_t;
|
||||||
extension_list_t m_extensions;
|
extension_list_t m_extensions;
|
||||||
|
|
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define TORRENT_TORRENT_HANDLE_HPP_INCLUDED
|
#define TORRENT_TORRENT_HANDLE_HPP_INCLUDED
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(push, 1)
|
#pragma warning(push, 1)
|
||||||
|
@ -273,7 +274,9 @@ namespace libtorrent
|
||||||
std::vector<announce_entry> const& trackers() const;
|
std::vector<announce_entry> const& trackers() const;
|
||||||
void replace_trackers(std::vector<announce_entry> const&) const;
|
void replace_trackers(std::vector<announce_entry> const&) const;
|
||||||
|
|
||||||
void add_url_seed(std::string const& url);
|
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;
|
||||||
|
|
||||||
bool has_metadata() const;
|
bool has_metadata() const;
|
||||||
const torrent_info& get_torrent_info() const;
|
const torrent_info& get_torrent_info() const;
|
||||||
|
|
|
@ -57,6 +57,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/peer_request.hpp"
|
#include "libtorrent/peer_request.hpp"
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
#include "libtorrent/time.hpp"
|
#include "libtorrent/time.hpp"
|
||||||
|
#include "libtorrent/intrusive_ptr_base.hpp"
|
||||||
|
#include "libtorrent/assert.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
@ -71,7 +73,7 @@ namespace libtorrent
|
||||||
size_type offset; // the offset of this file inside the torrent
|
size_type offset; // the offset of this file inside the torrent
|
||||||
size_type size; // the size of this file
|
size_type size; // the size of this file
|
||||||
// if the path was incorrectly encoded, this is
|
// if the path was incorrectly encoded, this is
|
||||||
// the origianal corrupt encoded string. It is
|
// the original corrupt encoded string. It is
|
||||||
// preserved in order to be able to reproduce
|
// preserved in order to be able to reproduce
|
||||||
// the correct info-hash
|
// the correct info-hash
|
||||||
boost::shared_ptr<const fs::path> orig_path;
|
boost::shared_ptr<const fs::path> orig_path;
|
||||||
|
@ -96,7 +98,7 @@ namespace libtorrent
|
||||||
virtual const char* what() const throw() { return "invalid torrent file"; }
|
virtual const char* what() const throw() { return "invalid torrent file"; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class TORRENT_EXPORT torrent_info
|
class TORRENT_EXPORT torrent_info : public intrusive_ptr_base<torrent_info>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -115,8 +117,12 @@ namespace libtorrent
|
||||||
void add_file(fs::path file, size_type size);
|
void add_file(fs::path file, size_type size);
|
||||||
void add_url_seed(std::string const& url);
|
void add_url_seed(std::string const& url);
|
||||||
|
|
||||||
std::vector<file_slice> map_block(int piece, size_type offset, int size) const;
|
bool remap_files(std::vector<std::pair<std::string, libtorrent::size_type> > const& map);
|
||||||
peer_request map_file(int file, size_type offset, int size) const;
|
|
||||||
|
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<std::string> const& url_seeds() const
|
std::vector<std::string> const& url_seeds() const
|
||||||
{
|
{
|
||||||
|
@ -128,15 +134,60 @@ namespace libtorrent
|
||||||
typedef std::vector<file_entry>::const_reverse_iterator reverse_file_iterator;
|
typedef std::vector<file_entry>::const_reverse_iterator reverse_file_iterator;
|
||||||
|
|
||||||
// list the files in the torrent file
|
// list the files in the torrent file
|
||||||
file_iterator begin_files() const { return m_files.begin(); }
|
file_iterator begin_files(bool storage = false) const
|
||||||
file_iterator end_files() const { return m_files.end(); }
|
{
|
||||||
reverse_file_iterator rbegin_files() const { return m_files.rbegin(); }
|
if (!storage || m_remapped_files.empty())
|
||||||
reverse_file_iterator rend_files() const { return m_files.rend(); }
|
return m_files.begin();
|
||||||
|
else
|
||||||
|
return m_remapped_files.begin();
|
||||||
|
}
|
||||||
|
|
||||||
int num_files() const
|
file_iterator end_files(bool storage = false) const
|
||||||
{ assert(m_piece_length > 0); return (int)m_files.size(); }
|
{
|
||||||
const file_entry& file_at(int index) const
|
if (!storage || m_remapped_files.empty())
|
||||||
{ assert(index >= 0 && index < (int)m_files.size()); return m_files[index]; }
|
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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<announce_entry>& trackers() const { return m_urls; }
|
const std::vector<announce_entry>& trackers() const { return m_urls; }
|
||||||
|
|
||||||
|
@ -218,6 +269,13 @@ namespace libtorrent
|
||||||
// the list of files that this torrent consists of
|
// the list of files that this torrent consists of
|
||||||
std::vector<file_entry> m_files;
|
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;
|
nodes_t m_nodes;
|
||||||
|
|
||||||
// the sum of all filesizes
|
// the sum of all filesizes
|
||||||
|
@ -264,8 +322,10 @@ namespace libtorrent
|
||||||
entry m_extra_info;
|
entry m_extra_info;
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
|
public:
|
||||||
// this is set to true when seed_free() is called
|
// this is set to true when seed_free() is called
|
||||||
bool m_half_metadata;
|
bool m_half_metadata;
|
||||||
|
private:
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define TORRENT_UPNP_HPP
|
#define TORRENT_UPNP_HPP
|
||||||
|
|
||||||
#include "libtorrent/socket.hpp"
|
#include "libtorrent/socket.hpp"
|
||||||
|
#include "libtorrent/broadcast_socket.hpp"
|
||||||
#include "libtorrent/http_connection.hpp"
|
#include "libtorrent/http_connection.hpp"
|
||||||
#include "libtorrent/connection_queue.hpp"
|
#include "libtorrent/connection_queue.hpp"
|
||||||
|
|
||||||
|
@ -56,9 +57,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
|
||||||
bool is_local(address const& a);
|
|
||||||
address_v4 guess_local_address(asio::io_service&);
|
|
||||||
|
|
||||||
// int: external tcp port
|
// int: external tcp port
|
||||||
// int: external udp port
|
// int: external udp port
|
||||||
// std::string: error message
|
// std::string: error message
|
||||||
|
@ -72,8 +70,6 @@ public:
|
||||||
, portmap_callback_t const& cb);
|
, portmap_callback_t const& cb);
|
||||||
~upnp();
|
~upnp();
|
||||||
|
|
||||||
void rebind(address const& listen_interface);
|
|
||||||
|
|
||||||
// maps the ports, if a port is set to 0
|
// maps the ports, if a port is set to 0
|
||||||
// it will not be mapped
|
// it will not be mapped
|
||||||
void set_mappings(int tcp, int udp);
|
void set_mappings(int tcp, int udp);
|
||||||
|
@ -90,7 +86,7 @@ private:
|
||||||
|
|
||||||
void update_mapping(int i, int port);
|
void update_mapping(int i, int port);
|
||||||
void resend_request(asio::error_code const& e);
|
void resend_request(asio::error_code const& e);
|
||||||
void on_reply(asio::error_code const& e
|
void on_reply(udp::endpoint const& from, char* buffer
|
||||||
, std::size_t bytes_transferred);
|
, std::size_t bytes_transferred);
|
||||||
void discover_device();
|
void discover_device();
|
||||||
|
|
||||||
|
@ -106,12 +102,15 @@ private:
|
||||||
, int mapping);
|
, int mapping);
|
||||||
void on_expire(asio::error_code const& e);
|
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 map_port(rootdevice& d, int i);
|
||||||
void unmap_port(rootdevice& d, int i);
|
void unmap_port(rootdevice& d, int i);
|
||||||
void disable();
|
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
|
struct mapping_t
|
||||||
{
|
{
|
||||||
mapping_t()
|
mapping_t()
|
||||||
|
@ -198,18 +197,13 @@ private:
|
||||||
// current retry count
|
// current retry count
|
||||||
int m_retry_count;
|
int m_retry_count;
|
||||||
|
|
||||||
// used to receive responses in
|
asio::io_service& m_io_service;
|
||||||
char m_receive_buffer[1024];
|
|
||||||
|
|
||||||
// the endpoint we received the message from
|
asio::strand m_strand;
|
||||||
udp::endpoint m_remote;
|
|
||||||
|
|
||||||
// the local address we're listening on
|
|
||||||
address_v4 m_local_ip;
|
|
||||||
|
|
||||||
// the udp socket used to send and receive
|
// the udp socket used to send and receive
|
||||||
// multicast messages on the network
|
// multicast messages on the network
|
||||||
datagram_socket m_socket;
|
broadcast_socket m_socket;
|
||||||
|
|
||||||
// used to resend udp packets in case
|
// used to resend udp packets in case
|
||||||
// they time out
|
// they time out
|
||||||
|
@ -218,8 +212,6 @@ private:
|
||||||
// timer used to refresh mappings
|
// timer used to refresh mappings
|
||||||
deadline_timer m_refresh_timer;
|
deadline_timer m_refresh_timer;
|
||||||
|
|
||||||
asio::strand m_strand;
|
|
||||||
|
|
||||||
bool m_disabled;
|
bool m_disabled;
|
||||||
bool m_closing;
|
bool m_closing;
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/alert.hpp"
|
#include "libtorrent/alert.hpp"
|
||||||
#include "libtorrent/torrent_handle.hpp"
|
#include "libtorrent/torrent_handle.hpp"
|
||||||
#include "libtorrent/torrent.hpp"
|
#include "libtorrent/torrent.hpp"
|
||||||
#include "libtorrent/allocate_resources.hpp"
|
|
||||||
#include "libtorrent/peer_request.hpp"
|
#include "libtorrent/peer_request.hpp"
|
||||||
#include "libtorrent/piece_block_progress.hpp"
|
#include "libtorrent/piece_block_progress.hpp"
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
|
@ -126,6 +125,8 @@ namespace libtorrent
|
||||||
void write_piece(peer_request const& r, char const* buffer) { assert(false); }
|
void write_piece(peer_request const& r, char const* buffer) { assert(false); }
|
||||||
void write_keepalive() {}
|
void write_keepalive() {}
|
||||||
void on_connected();
|
void on_connected();
|
||||||
|
void write_reject_request(peer_request const&) {}
|
||||||
|
void write_allow_fast(int) {}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void check_invariant() const;
|
void check_invariant() const;
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue