libtorrent sync 1592
This commit is contained in:
parent
d44632f0a9
commit
b2fe562dd4
|
@ -25,6 +25,8 @@ extern char const* peer_error_alert_doc;
|
|||
extern char const* invalid_request_alert_doc;
|
||||
extern char const* peer_request_doc;
|
||||
extern char const* torrent_finished_alert_doc;
|
||||
extern char const* torrent_paused_alert_doc;
|
||||
extern char const* storage_moved_alert_doc;
|
||||
extern char const* metadata_failed_alert_doc;
|
||||
extern char const* metadata_received_alert_doc;
|
||||
extern char const* fastresume_rejected_alert_doc;
|
||||
|
@ -140,7 +142,18 @@ void bind_alert()
|
|||
)
|
||||
.def_readonly("handle", &torrent_finished_alert::handle)
|
||||
;
|
||||
|
||||
|
||||
class_<torrent_paused_alert, bases<alert>, noncopyable>(
|
||||
"torrent_paused_alert", torrent_paused_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("handle", &torrent_paused_alert::handle)
|
||||
;
|
||||
|
||||
class_<storage_moved_alert, bases<alert>, noncopyable>(
|
||||
"storage_moved_alert", storage_moved_alert_doc, no_init
|
||||
)
|
||||
.def_readonly("handle", &storage_moved_alert::handle)
|
||||
;
|
||||
class_<metadata_failed_alert, bases<alert>, noncopyable>(
|
||||
"metadata_failed_alert", metadata_failed_alert_doc, no_init
|
||||
)
|
||||
|
|
|
@ -164,14 +164,14 @@ char const* session_set_severity_level_doc =
|
|||
"";
|
||||
char const* session_pop_alert_doc =
|
||||
"";
|
||||
char const* session_start_upnp_doc =
|
||||
char const* session_start_upnp_doc =
|
||||
"";
|
||||
char const* session_stop_upnp_doc =
|
||||
char const* session_stop_upnp_doc =
|
||||
"";
|
||||
char const* session_start_natpmp_doc =
|
||||
char const* session_start_natpmp_doc =
|
||||
"";
|
||||
char const* session_stop_natpmp_doc =
|
||||
"";
|
||||
char const* session_stop_natpmp_doc =
|
||||
"";
|
||||
// -- alert -----------------------------------------------------------------
|
||||
|
||||
char const* alert_doc =
|
||||
|
@ -257,6 +257,17 @@ char const* torrent_finished_alert_doc =
|
|||
"It contains a `torrent_handle` to the torrent in question. This alert\n"
|
||||
"is generated as severity level `alert.severity_levels.info`.";
|
||||
|
||||
char const* torrent_paused_alert_doc =
|
||||
"This alert is generated when a torrent switches from being a\n"
|
||||
"active to paused.\n"
|
||||
"It contains a `torrent_handle` to the torrent in question. This alert\n"
|
||||
"is generated as severity level `alert.severity_levels.warning`.";
|
||||
|
||||
char const* storage_moved_alert_doc =
|
||||
"This alert is generated when a torrent moves storage.\n"
|
||||
"It contains a `torrent_handle` to the torrent in question. This alert\n"
|
||||
"is generated as severity level `alert.severity_levels.warning`.";
|
||||
|
||||
char const* metadata_failed_alert_doc =
|
||||
"This alert is generated when the metadata has been completely\n"
|
||||
"received and the info-hash failed to match it. i.e. the\n"
|
||||
|
|
|
@ -142,7 +142,6 @@ void bind_extensions()
|
|||
// TODO move to it's own file
|
||||
class_<peer_connection, boost::noncopyable>("peer_connection", no_init);
|
||||
|
||||
class_<torrent_plugin, boost::shared_ptr<torrent_plugin> >("torrent_plugin", no_init);
|
||||
def("create_ut_pex_plugin", create_ut_pex_plugin);
|
||||
def("create_metadata_plugin", create_metadata_plugin);
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ extern char const* session_set_max_connections_doc;
|
|||
extern char const* session_set_max_half_open_connections_doc;
|
||||
extern char const* session_set_settings_doc;
|
||||
extern char const* session_set_pe_settings_doc;
|
||||
extern char const* session_get_pe_settings_doc;
|
||||
extern char const* session_get_pe_settings_doc;
|
||||
extern char const* session_set_severity_level_doc;
|
||||
extern char const* session_pop_alert_doc;
|
||||
extern char const* session_start_upnp_doc;
|
||||
|
@ -86,11 +86,10 @@ namespace
|
|||
|
||||
torrent_handle add_torrent(session& s, torrent_info const& ti
|
||||
, boost::filesystem::path const& save, entry const& resume
|
||||
, bool compact, int block_size)
|
||||
, bool compact, bool paused)
|
||||
{
|
||||
allow_threading_guard guard;
|
||||
return s.add_torrent(ti, save, resume, compact, block_size
|
||||
, default_storage_constructor);
|
||||
return s.add_torrent(ti, save, resume, compact, paused, default_storage_constructor);
|
||||
}
|
||||
|
||||
} // namespace unnamed
|
||||
|
@ -175,7 +174,7 @@ void bind_session()
|
|||
"add_torrent", &add_torrent
|
||||
, (
|
||||
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
|
||||
)
|
||||
|
|
|
@ -47,7 +47,7 @@ void bind_session_settings()
|
|||
.value("http", proxy_settings::http)
|
||||
.value("http_pw", proxy_settings::http_pw)
|
||||
;
|
||||
class_<proxy_settings>("proxy_settings")
|
||||
class_<proxy_settings>("proxy_settings")
|
||||
.def_readwrite("hostname", &proxy_settings::hostname)
|
||||
.def_readwrite("port", &proxy_settings::port)
|
||||
.def_readwrite("password", &proxy_settings::password)
|
||||
|
@ -64,7 +64,7 @@ void bind_session_settings()
|
|||
enum_<pe_settings::enc_level>("enc_level")
|
||||
.value("rc4", pe_settings::rc4)
|
||||
.value("plaintext", pe_settings::plaintext)
|
||||
.value("both", pe_settings::both)
|
||||
.value("both", pe_settings::both)
|
||||
;
|
||||
|
||||
class_<pe_settings>("pe_settings")
|
||||
|
|
|
@ -16,7 +16,6 @@ namespace
|
|||
return i.trackers().begin();
|
||||
}
|
||||
|
||||
|
||||
std::vector<announce_entry>::const_iterator end_trackers(torrent_info& i)
|
||||
{
|
||||
return i.trackers().end();
|
||||
|
@ -41,6 +40,29 @@ namespace
|
|||
return result;
|
||||
}
|
||||
|
||||
std::vector<file_entry>::const_iterator begin_files(torrent_info& i, bool storage)
|
||||
{
|
||||
return i.begin_files(storage);
|
||||
}
|
||||
|
||||
std::vector<file_entry>::const_iterator end_files(torrent_info& i, bool storage)
|
||||
{
|
||||
return i.end_files(storage);
|
||||
}
|
||||
|
||||
//list files(torrent_info const& ti, bool storage) {
|
||||
list files(torrent_info const& ti, bool storage) {
|
||||
list result;
|
||||
|
||||
typedef std::vector<file_entry> list_type;
|
||||
|
||||
for (list_type::const_iterator i = ti.begin_files(storage); i != ti.end_files(storage); ++i)
|
||||
result.append(*i);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
} // namespace unnamed
|
||||
|
||||
void bind_torrent_info()
|
||||
|
@ -71,9 +93,9 @@ void bind_torrent_info()
|
|||
.def("hash_for_piece", &torrent_info::hash_for_piece, copy)
|
||||
.def("piece_size", &torrent_info::piece_size)
|
||||
|
||||
.def("num_files", &torrent_info::num_files)
|
||||
.def("num_files", &torrent_info::num_files, (arg("storage")=false))
|
||||
.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("set_priv", &torrent_info::set_priv)
|
||||
|
@ -84,9 +106,8 @@ void bind_torrent_info()
|
|||
.def("add_node", &add_node)
|
||||
.def("nodes", &nodes)
|
||||
;
|
||||
|
||||
class_<file_entry>("file_entry")
|
||||
.add_property(
|
||||
.add_property(
|
||||
"path"
|
||||
, make_getter(
|
||||
&file_entry::path, return_value_policy<copy_non_const_reference>()
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
* @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()
|
||||
{
|
||||
|
@ -265,6 +268,9 @@ public:
|
|||
* // An error occurred.
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* @note For portable behaviour with respect to graceful closure of a
|
||||
* connected socket, call shutdown() before closing the socket.
|
||||
*/
|
||||
asio::error_code close(asio::error_code& ec)
|
||||
{
|
||||
|
|
|
@ -542,9 +542,10 @@ inline const_buffers_1 buffer(const PodType (&data)[N],
|
|||
? 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 ...);
|
||||
//
|
||||
|
@ -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))
|
||||
// || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||
|
||||
/// Create a new modifiable buffer that represents the given POD array.
|
||||
template <typename PodType, std::size_t N>
|
||||
|
@ -650,6 +652,7 @@ inline const_buffers_1 buffer(boost::array<const PodType, N>& data,
|
|||
}
|
||||
|
||||
#endif // BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
|
||||
// || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
|
||||
|
||||
/// Create a new non-modifiable buffer that represents the given POD array.
|
||||
template <typename PodType, std::size_t N>
|
||||
|
|
|
@ -71,6 +71,28 @@ private:
|
|||
/// Return a completion condition function object that indicates that a read or
|
||||
/// write operation should continue until all of the data has been transferred,
|
||||
/// or until an error occurs.
|
||||
/**
|
||||
* This function is used to create an object, of unspecified type, that meets
|
||||
* CompletionCondition requirements.
|
||||
*
|
||||
* @par Example
|
||||
* Reading until a buffer is full:
|
||||
* @code
|
||||
* boost::array<char, 128> buf;
|
||||
* asio::error_code ec;
|
||||
* std::size_t n = asio::read(
|
||||
* sock, asio::buffer(buf),
|
||||
* asio::transfer_all(), ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // n == 128
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
unspecified transfer_all();
|
||||
#else
|
||||
|
@ -83,6 +105,28 @@ inline detail::transfer_all_t transfer_all()
|
|||
/// Return a completion condition function object that indicates that a read or
|
||||
/// write operation should continue until a minimum number of bytes has been
|
||||
/// transferred, or until an error occurs.
|
||||
/**
|
||||
* This function is used to create an object, of unspecified type, that meets
|
||||
* CompletionCondition requirements.
|
||||
*
|
||||
* @par Example
|
||||
* Reading until a buffer is full or contains at least 64 bytes:
|
||||
* @code
|
||||
* boost::array<char, 128> buf;
|
||||
* asio::error_code ec;
|
||||
* std::size_t n = asio::read(
|
||||
* sock, asio::buffer(buf),
|
||||
* asio::transfer_at_least(64), ec);
|
||||
* if (ec)
|
||||
* {
|
||||
* // An error occurred.
|
||||
* }
|
||||
* else
|
||||
* {
|
||||
* // n >= 64 && n <= 128
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
#if defined(GENERATING_DOCUMENTATION)
|
||||
unspecified transfer_at_least(std::size_t minimum);
|
||||
#else
|
||||
|
|
|
@ -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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +191,8 @@ public:
|
|||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -219,7 +221,8 @@ public:
|
|||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -250,7 +253,8 @@ public:
|
|||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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:
|
||||
|
@ -347,16 +354,13 @@ private:
|
|||
read_op_queue_.dispatch_cancellations();
|
||||
write_op_queue_.dispatch_cancellations();
|
||||
except_op_queue_.dispatch_cancellations();
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
timer_queues_[i]->dispatch_cancellations();
|
||||
|
||||
// Check if the thread is supposed to stop.
|
||||
if (stop_thread_)
|
||||
{
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
cleanup_operations_and_timers(lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -365,12 +369,7 @@ private:
|
|||
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
|
||||
&& except_op_queue_.empty() && all_timer_queues_are_empty())
|
||||
{
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
cleanup_operations_and_timers(lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -398,59 +397,45 @@ private:
|
|||
}
|
||||
else
|
||||
{
|
||||
if (events[i].events & (EPOLLERR | EPOLLHUP))
|
||||
bool more_reads = false;
|
||||
bool more_writes = false;
|
||||
bool more_except = false;
|
||||
asio::error_code ec;
|
||||
|
||||
// Exception operations must be processed first to ensure that any
|
||||
// out-of-band data is read before normal data.
|
||||
if (events[i].events & (EPOLLPRI | EPOLLERR | EPOLLHUP))
|
||||
more_except = except_op_queue_.dispatch_operation(descriptor, ec);
|
||||
else
|
||||
more_except = except_op_queue_.has_operation(descriptor);
|
||||
|
||||
if (events[i].events & (EPOLLIN | EPOLLERR | EPOLLHUP))
|
||||
more_reads = read_op_queue_.dispatch_operation(descriptor, ec);
|
||||
else
|
||||
more_reads = read_op_queue_.has_operation(descriptor);
|
||||
|
||||
if (events[i].events & (EPOLLOUT | EPOLLERR | EPOLLHUP))
|
||||
more_writes = write_op_queue_.dispatch_operation(descriptor, ec);
|
||||
else
|
||||
more_writes = write_op_queue_.has_operation(descriptor);
|
||||
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
ev.events = EPOLLERR | EPOLLHUP;
|
||||
if (more_reads)
|
||||
ev.events |= EPOLLIN;
|
||||
if (more_writes)
|
||||
ev.events |= EPOLLOUT;
|
||||
if (more_except)
|
||||
ev.events |= EPOLLPRI;
|
||||
ev.data.fd = descriptor;
|
||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
if (result != 0)
|
||||
{
|
||||
asio::error_code ec;
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
ec = asio::error_code(errno,
|
||||
asio::error::system_category);
|
||||
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_writes = false;
|
||||
bool more_except = false;
|
||||
asio::error_code ec;
|
||||
|
||||
// Exception operations must be processed first to ensure that any
|
||||
// out-of-band data is read before normal data.
|
||||
if (events[i].events & EPOLLPRI)
|
||||
more_except = except_op_queue_.dispatch_operation(descriptor, ec);
|
||||
else
|
||||
more_except = except_op_queue_.has_operation(descriptor);
|
||||
|
||||
if (events[i].events & EPOLLIN)
|
||||
more_reads = read_op_queue_.dispatch_operation(descriptor, ec);
|
||||
else
|
||||
more_reads = read_op_queue_.has_operation(descriptor);
|
||||
|
||||
if (events[i].events & EPOLLOUT)
|
||||
more_writes = write_op_queue_.dispatch_operation(descriptor, ec);
|
||||
else
|
||||
more_writes = write_op_queue_.has_operation(descriptor);
|
||||
|
||||
epoll_event ev = { 0, { 0 } };
|
||||
ev.events = EPOLLERR | EPOLLHUP;
|
||||
if (more_reads)
|
||||
ev.events |= EPOLLIN;
|
||||
if (more_writes)
|
||||
ev.events |= EPOLLOUT;
|
||||
if (more_except)
|
||||
ev.events |= EPOLLPRI;
|
||||
ev.data.fd = descriptor;
|
||||
int result = epoll_ctl(epoll_fd_, EPOLL_CTL_MOD, descriptor, &ev);
|
||||
if (result != 0)
|
||||
{
|
||||
ec = asio::error_code(errno, asio::native_ecat);
|
||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
except_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -458,19 +443,17 @@ private:
|
|||
write_op_queue_.dispatch_cancellations();
|
||||
except_op_queue_.dispatch_cancellations();
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
{
|
||||
timer_queues_[i]->dispatch_timers();
|
||||
timer_queues_[i]->dispatch_cancellations();
|
||||
}
|
||||
|
||||
// Issue any pending cancellations.
|
||||
for (size_t i = 0; i < pending_cancellations_.size(); ++i)
|
||||
cancel_ops_unlocked(pending_cancellations_[i]);
|
||||
pending_cancellations_.clear();
|
||||
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
cleanup_operations_and_timers(lock);
|
||||
}
|
||||
|
||||
// Run the select loop in the thread.
|
||||
|
@ -507,8 +490,10 @@ private:
|
|||
int fd = epoll_create(epoll_size);
|
||||
if (fd == -1)
|
||||
{
|
||||
boost::throw_exception(asio::system_error(
|
||||
asio::error_code(errno, asio::native_ecat),
|
||||
boost::throw_exception(
|
||||
asio::system_error(
|
||||
asio::error_code(errno,
|
||||
asio::error::system_category),
|
||||
"epoll"));
|
||||
}
|
||||
return fd;
|
||||
|
@ -566,6 +551,22 @@ private:
|
|||
interrupter_.interrupt();
|
||||
}
|
||||
|
||||
// Clean up operations and timers. We must not hold the lock since the
|
||||
// destructors may make calls back into this reactor. We make a copy of the
|
||||
// vector of timer queues since the original may be modified while the lock
|
||||
// is not held.
|
||||
void cleanup_operations_and_timers(
|
||||
asio::detail::mutex::scoped_lock& lock)
|
||||
{
|
||||
timer_queues_for_cleanup_ = timer_queues_;
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i)
|
||||
timer_queues_for_cleanup_[i]->cleanup_timers();
|
||||
}
|
||||
|
||||
// Mutex to protect access to internal data.
|
||||
asio::detail::mutex mutex_;
|
||||
|
||||
|
@ -590,6 +591,10 @@ private:
|
|||
// The timer queues.
|
||||
std::vector<timer_queue_base*> timer_queues_;
|
||||
|
||||
// A copy of the timer queues, used when cleaning up timers. The copy is
|
||||
// stored as a class data member to avoid unnecessary memory allocation.
|
||||
std::vector<timer_queue_base*> timer_queues_for_cleanup_;
|
||||
|
||||
// The descriptors that are pending cancellation.
|
||||
std::vector<socket_type> pending_cancellations_;
|
||||
|
||||
|
|
|
@ -150,7 +150,8 @@ public:
|
|||
EV_SET(&event, descriptor, EVFILT_READ, EV_ADD, 0, 0, 0);
|
||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code ec(errno, asio::native_ecat);
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
read_op_queue_.dispatch_all_operations(descriptor, ec);
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +177,8 @@ public:
|
|||
EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
|
||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code ec(errno, asio::native_ecat);
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -224,7 +227,8 @@ public:
|
|||
EV_SET(&event, descriptor, EVFILT_WRITE, EV_ADD, 0, 0, 0);
|
||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code ec(errno, asio::native_ecat);
|
||||
asio::error_code ec(errno,
|
||||
asio::error::system_category);
|
||||
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);
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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:
|
||||
|
@ -337,16 +345,13 @@ private:
|
|||
read_op_queue_.dispatch_cancellations();
|
||||
write_op_queue_.dispatch_cancellations();
|
||||
except_op_queue_.dispatch_cancellations();
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
timer_queues_[i]->dispatch_cancellations();
|
||||
|
||||
// Check if the thread is supposed to stop.
|
||||
if (stop_thread_)
|
||||
{
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
cleanup_operations_and_timers(lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -355,12 +360,7 @@ private:
|
|||
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
|
||||
&& except_op_queue_.empty() && all_timer_queues_are_empty())
|
||||
{
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
cleanup_operations_and_timers(lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -397,7 +397,7 @@ private:
|
|||
if (events[i].flags & EV_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);
|
||||
read_op_queue_.dispatch_all_operations(descriptor, error);
|
||||
}
|
||||
|
@ -427,7 +427,8 @@ private:
|
|||
EV_SET(&event, descriptor, EVFILT_READ, EV_DELETE, 0, 0, 0);
|
||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code error(errno, asio::native_ecat);
|
||||
asio::error_code error(errno,
|
||||
asio::error::system_category);
|
||||
except_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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
|
@ -456,7 +457,8 @@ private:
|
|||
EV_SET(&event, descriptor, EVFILT_WRITE, EV_DELETE, 0, 0, 0);
|
||||
if (::kevent(kqueue_fd_, &event, 1, 0, 0, 0) == -1)
|
||||
{
|
||||
asio::error_code error(errno, asio::native_ecat);
|
||||
asio::error_code error(errno,
|
||||
asio::error::system_category);
|
||||
write_op_queue_.dispatch_all_operations(descriptor, error);
|
||||
}
|
||||
}
|
||||
|
@ -466,19 +468,17 @@ private:
|
|||
write_op_queue_.dispatch_cancellations();
|
||||
except_op_queue_.dispatch_cancellations();
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
{
|
||||
timer_queues_[i]->dispatch_timers();
|
||||
timer_queues_[i]->dispatch_cancellations();
|
||||
}
|
||||
|
||||
// Issue any pending cancellations.
|
||||
for (std::size_t i = 0; i < pending_cancellations_.size(); ++i)
|
||||
cancel_ops_unlocked(pending_cancellations_[i]);
|
||||
pending_cancellations_.clear();
|
||||
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
cleanup_operations_and_timers(lock);
|
||||
}
|
||||
|
||||
// Run the select loop in the thread.
|
||||
|
@ -512,8 +512,10 @@ private:
|
|||
int fd = kqueue();
|
||||
if (fd == -1)
|
||||
{
|
||||
boost::throw_exception(asio::system_error(
|
||||
asio::error_code(errno, asio::native_ecat),
|
||||
boost::throw_exception(
|
||||
asio::system_error(
|
||||
asio::error_code(errno,
|
||||
asio::error::system_category),
|
||||
"kqueue"));
|
||||
}
|
||||
return fd;
|
||||
|
@ -573,6 +575,22 @@ private:
|
|||
interrupter_.interrupt();
|
||||
}
|
||||
|
||||
// Clean up operations and timers. We must not hold the lock since the
|
||||
// destructors may make calls back into this reactor. We make a copy of the
|
||||
// vector of timer queues since the original may be modified while the lock
|
||||
// is not held.
|
||||
void cleanup_operations_and_timers(
|
||||
asio::detail::mutex::scoped_lock& lock)
|
||||
{
|
||||
timer_queues_for_cleanup_ = timer_queues_;
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i)
|
||||
timer_queues_for_cleanup_[i]->cleanup_timers();
|
||||
}
|
||||
|
||||
// Mutex to protect access to internal data.
|
||||
asio::detail::mutex mutex_;
|
||||
|
||||
|
@ -597,6 +615,10 @@ private:
|
|||
// The timer queues.
|
||||
std::vector<timer_queue_base*> timer_queues_;
|
||||
|
||||
// A copy of the timer queues, used when cleaning up timers. The copy is
|
||||
// stored as a class data member to avoid unnecessary memory allocation.
|
||||
std::vector<timer_queue_base*> timer_queues_for_cleanup_;
|
||||
|
||||
// The descriptors that are pending cancellation.
|
||||
std::vector<socket_type> pending_cancellations_;
|
||||
|
||||
|
|
|
@ -43,17 +43,20 @@ public:
|
|||
}
|
||||
|
||||
// Signal the event.
|
||||
void signal()
|
||||
template <typename Lock>
|
||||
void signal(Lock&)
|
||||
{
|
||||
}
|
||||
|
||||
// Reset the event.
|
||||
void clear()
|
||||
template <typename Lock>
|
||||
void clear(Lock&)
|
||||
{
|
||||
}
|
||||
|
||||
// Wait for the event to become signalled.
|
||||
void wait()
|
||||
template <typename Lock>
|
||||
void wait(Lock&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
|
@ -24,10 +24,12 @@
|
|||
#if defined(BOOST_HAS_PTHREADS)
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <pthread.h>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
|
||||
|
@ -42,21 +44,11 @@ public:
|
|||
posix_event()
|
||||
: signalled_(false)
|
||||
{
|
||||
int error = ::pthread_mutex_init(&mutex_, 0);
|
||||
int error = ::pthread_cond_init(&cond_, 0);
|
||||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
"event");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
||||
error = ::pthread_cond_init(&cond_, 0);
|
||||
if (error != 0)
|
||||
{
|
||||
::pthread_mutex_destroy(&mutex_);
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
"event");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -66,37 +58,37 @@ public:
|
|||
~posix_event()
|
||||
{
|
||||
::pthread_cond_destroy(&cond_);
|
||||
::pthread_mutex_destroy(&mutex_);
|
||||
}
|
||||
|
||||
// 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;
|
||||
::pthread_cond_signal(&cond_); // Ignore EINVAL.
|
||||
::pthread_mutex_unlock(&mutex_); // Ignore EINVAL and EPERM.
|
||||
}
|
||||
|
||||
// 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;
|
||||
::pthread_mutex_unlock(&mutex_); // Ignore EINVAL and EPERM.
|
||||
}
|
||||
|
||||
// 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_)
|
||||
::pthread_cond_wait(&cond_, &mutex_); // Ignore EINVAL.
|
||||
::pthread_mutex_unlock(&mutex_); // Ignore EINVAL and EPERM.
|
||||
::pthread_cond_wait(&cond_, &lock.mutex().mutex_); // Ignore EINVAL.
|
||||
}
|
||||
|
||||
private:
|
||||
::pthread_mutex_t mutex_;
|
||||
::pthread_cond_t cond_;
|
||||
bool signalled_;
|
||||
};
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <pthread.h>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
#include "asio/detail/scoped_lock.hpp"
|
||||
|
@ -35,6 +36,8 @@
|
|||
namespace asio {
|
||||
namespace detail {
|
||||
|
||||
class posix_event;
|
||||
|
||||
class posix_mutex
|
||||
: private noncopyable
|
||||
{
|
||||
|
@ -48,7 +51,7 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
"mutex");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -67,7 +70,7 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
"mutex");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -80,13 +83,14 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
"mutex");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
friend class posix_event;
|
||||
::pthread_mutex_t mutex_;
|
||||
};
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include <pthread.h>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
|
||||
|
@ -52,7 +53,7 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
"thread");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <pthread.h>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
|
||||
|
@ -46,7 +47,7 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
"tss");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ public:
|
|||
};
|
||||
|
||||
// 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.
|
||||
reactive_socket_service(asio::io_service& io_service)
|
||||
|
@ -157,7 +157,7 @@ public:
|
|||
|
||||
if (int err = reactor_.register_descriptor(sock.get()))
|
||||
{
|
||||
ec = asio::error_code(err, asio::native_ecat);
|
||||
ec = asio::error_code(err, asio::error::system_category);
|
||||
return ec;
|
||||
}
|
||||
|
||||
|
@ -181,7 +181,7 @@ public:
|
|||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1124,7 +1124,7 @@ public:
|
|||
bool operator()(const asio::error_code& result)
|
||||
{
|
||||
// Check whether the operation was successful.
|
||||
if (result != 0)
|
||||
if (result)
|
||||
{
|
||||
io_service_.post(bind_handler(handler_, result, 0));
|
||||
return true;
|
||||
|
@ -1489,7 +1489,7 @@ public:
|
|||
if (connect_error)
|
||||
{
|
||||
ec = asio::error_code(connect_error,
|
||||
asio::native_ecat);
|
||||
asio::error::system_category);
|
||||
io_service_.post(bind_handler(handler_, ec));
|
||||
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:
|
||||
// The underlying mutex.
|
||||
Mutex& mutex_;
|
||||
|
|
|
@ -229,7 +229,10 @@ public:
|
|||
std::size_t cancel_timer(timer_queue<Time_Traits>& timer_queue, void* token)
|
||||
{
|
||||
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:
|
||||
|
@ -245,16 +248,13 @@ private:
|
|||
read_op_queue_.dispatch_cancellations();
|
||||
write_op_queue_.dispatch_cancellations();
|
||||
except_op_queue_.dispatch_cancellations();
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
timer_queues_[i]->dispatch_cancellations();
|
||||
|
||||
// Check if the thread is supposed to stop.
|
||||
if (stop_thread_)
|
||||
{
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
cleanup_operations_and_timers(lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -263,12 +263,7 @@ private:
|
|||
if (!block && read_op_queue_.empty() && write_op_queue_.empty()
|
||||
&& except_op_queue_.empty() && all_timer_queues_are_empty())
|
||||
{
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
cleanup_operations_and_timers(lock);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -321,19 +316,17 @@ private:
|
|||
write_op_queue_.dispatch_cancellations();
|
||||
}
|
||||
for (std::size_t i = 0; i < timer_queues_.size(); ++i)
|
||||
{
|
||||
timer_queues_[i]->dispatch_timers();
|
||||
timer_queues_[i]->dispatch_cancellations();
|
||||
}
|
||||
|
||||
// Issue any pending cancellations.
|
||||
for (size_t i = 0; i < pending_cancellations_.size(); ++i)
|
||||
cancel_ops_unlocked(pending_cancellations_[i]);
|
||||
pending_cancellations_.clear();
|
||||
|
||||
// Clean up operations. We must not hold the lock since the operations may
|
||||
// make calls back into this reactor.
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
cleanup_operations_and_timers(lock);
|
||||
}
|
||||
|
||||
// Run the select loop in the thread.
|
||||
|
@ -414,6 +407,22 @@ private:
|
|||
interrupter_.interrupt();
|
||||
}
|
||||
|
||||
// Clean up operations and timers. We must not hold the lock since the
|
||||
// destructors may make calls back into this reactor. We make a copy of the
|
||||
// vector of timer queues since the original may be modified while the lock
|
||||
// is not held.
|
||||
void cleanup_operations_and_timers(
|
||||
asio::detail::mutex::scoped_lock& lock)
|
||||
{
|
||||
timer_queues_for_cleanup_ = timer_queues_;
|
||||
lock.unlock();
|
||||
read_op_queue_.cleanup_operations();
|
||||
write_op_queue_.cleanup_operations();
|
||||
except_op_queue_.cleanup_operations();
|
||||
for (std::size_t i = 0; i < timer_queues_for_cleanup_.size(); ++i)
|
||||
timer_queues_for_cleanup_[i]->cleanup_timers();
|
||||
}
|
||||
|
||||
// Mutex to protect access to internal data.
|
||||
asio::detail::mutex mutex_;
|
||||
|
||||
|
@ -435,6 +444,10 @@ private:
|
|||
// The timer queues.
|
||||
std::vector<timer_queue_base*> timer_queues_;
|
||||
|
||||
// A copy of the timer queues, used when cleaning up timers. The copy is
|
||||
// stored as a class data member to avoid unnecessary memory allocation.
|
||||
std::vector<timer_queue_base*> timer_queues_for_cleanup_;
|
||||
|
||||
// The descriptors that are pending cancellation.
|
||||
std::vector<socket_type> pending_cancellations_;
|
||||
|
||||
|
|
|
@ -166,7 +166,8 @@ private:
|
|||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
return service.id_ == &id;
|
||||
|
@ -174,7 +175,8 @@ private:
|
|||
|
||||
// Check if a service matches the given id.
|
||||
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*/)
|
||||
{
|
||||
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)
|
||||
{
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
ec = asio::error_code(WSAGetLastError(), asio::native_ecat);
|
||||
ec = asio::error_code(WSAGetLastError(),
|
||||
asio::error::system_category);
|
||||
#else
|
||||
ec = asio::error_code(errno, asio::native_ecat);
|
||||
ec = asio::error_code(errno, asio::error::system_category);
|
||||
#endif
|
||||
return return_value;
|
||||
}
|
||||
|
@ -923,6 +924,13 @@ inline void gai_free(void* p)
|
|||
::operator delete(p);
|
||||
}
|
||||
|
||||
inline void gai_strcpy(char* target, const char* source, std::size_t max_size)
|
||||
{
|
||||
using namespace std;
|
||||
*target = 0;
|
||||
strncat(target, source, max_size);
|
||||
}
|
||||
|
||||
enum { gai_clone_flag = 1 << 30 };
|
||||
|
||||
inline int gai_aistruct(addrinfo_type*** next, const addrinfo_type* hints,
|
||||
|
@ -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]
|
||||
&& (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)
|
||||
{
|
||||
freeaddrinfo_emulation(aihead);
|
||||
socket_ops::freehostent(hptr);
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
strcpy(canon, hptr->h_name);
|
||||
gai_strcpy(canon, hptr->h_name, canon_len);
|
||||
}
|
||||
|
||||
// Create an addrinfo structure for each returned address.
|
||||
|
@ -1335,13 +1344,14 @@ inline int getaddrinfo_emulation(const char* host, const char* service,
|
|||
}
|
||||
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)
|
||||
{
|
||||
freeaddrinfo_emulation(aihead);
|
||||
return EAI_MEMORY;
|
||||
}
|
||||
strcpy(aihead->ai_canonname, search[0].host);
|
||||
gai_strcpy(aihead->ai_canonname, search[0].host, canonname_len);
|
||||
}
|
||||
}
|
||||
gai_free(canon);
|
||||
|
@ -1424,8 +1434,7 @@ inline asio::error_code getnameinfo_emulation(
|
|||
*dot = 0;
|
||||
}
|
||||
}
|
||||
*host = '\0';
|
||||
strncat(host, hptr->h_name, hostlen);
|
||||
gai_strcpy(host, hptr->h_name, hostlen);
|
||||
socket_ops::freehostent(hptr);
|
||||
}
|
||||
else
|
||||
|
@ -1463,8 +1472,7 @@ inline asio::error_code getnameinfo_emulation(
|
|||
servent* sptr = ::getservbyport(port, (flags & NI_DGRAM) ? "udp" : 0);
|
||||
if (sptr && sptr->s_name && sptr->s_name[0] != '\0')
|
||||
{
|
||||
*serv = '\0';
|
||||
strncat(serv, sptr->s_name, servlen);
|
||||
gai_strcpy(serv, sptr->s_name, servlen);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1504,6 +1512,12 @@ inline asio::error_code translate_addrinfo_error(int error)
|
|||
case EAI_MEMORY:
|
||||
return asio::error::no_memory;
|
||||
case EAI_NONAME:
|
||||
#if defined(EAI_ADDRFAMILY)
|
||||
case EAI_ADDRFAMILY:
|
||||
#endif
|
||||
#if defined(EAI_NODATA) && (EAI_NODATA != EAI_NONAME)
|
||||
case EAI_NODATA:
|
||||
#endif
|
||||
return asio::error::host_not_found;
|
||||
case EAI_SERVICE:
|
||||
return asio::error::service_not_found;
|
||||
|
@ -1512,10 +1526,10 @@ inline asio::error_code translate_addrinfo_error(int error)
|
|||
default: // Possibly the non-portable EAI_SYSTEM.
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
return asio::error_code(
|
||||
WSAGetLastError(), asio::native_ecat);
|
||||
WSAGetLastError(), asio::error::system_category);
|
||||
#else
|
||||
return asio::error_code(
|
||||
errno, asio::native_ecat);
|
||||
errno, asio::error::system_category);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,8 +110,19 @@ public:
|
|||
template <typename Protocol>
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -98,6 +98,7 @@
|
|||
# include <arpa/inet.h>
|
||||
# include <netdb.h>
|
||||
# include <net/if.h>
|
||||
# include <limits.h>
|
||||
# if defined(__sun)
|
||||
# include <sys/filio.h>
|
||||
# include <sys/sockio.h>
|
||||
|
@ -141,6 +142,11 @@ const int shutdown_both = SD_BOTH;
|
|||
const int message_peek = MSG_PEEK;
|
||||
const int message_out_of_band = MSG_OOB;
|
||||
const int message_do_not_route = MSG_DONTROUTE;
|
||||
# if defined (_WIN32_WINNT)
|
||||
const int max_iov_len = 64;
|
||||
# else
|
||||
const int max_iov_len = 16;
|
||||
# endif
|
||||
#else
|
||||
typedef int socket_type;
|
||||
const int invalid_socket = -1;
|
||||
|
@ -166,6 +172,7 @@ const int shutdown_both = SHUT_RDWR;
|
|||
const int message_peek = MSG_PEEK;
|
||||
const int message_out_of_band = MSG_OOB;
|
||||
const int message_do_not_route = MSG_DONTROUTE;
|
||||
const int max_iov_len = IOV_MAX;
|
||||
#endif
|
||||
const int custom_socket_option_level = 0xA5100000;
|
||||
const int enable_connection_aborted_option = 1;
|
||||
|
|
|
@ -239,6 +239,7 @@ public:
|
|||
#else
|
||||
BOOST_ASSERT(size <= strand_impl::handler_storage_type::size);
|
||||
#endif
|
||||
(void)size;
|
||||
return impl_->handler_storage_.address();
|
||||
}
|
||||
|
||||
|
@ -415,14 +416,14 @@ public:
|
|||
}
|
||||
else
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(impl->mutex_);
|
||||
|
||||
// Allocate and construct an object to wrap the handler.
|
||||
typedef handler_wrapper<Handler> value_type;
|
||||
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
|
||||
raw_handler_ptr<alloc_traits> raw_ptr(handler);
|
||||
handler_ptr<alloc_traits> ptr(raw_ptr, handler);
|
||||
|
||||
asio::detail::mutex::scoped_lock lock(impl->mutex_);
|
||||
|
||||
if (impl->current_handler_ == 0)
|
||||
{
|
||||
// This handler now has the lock, so can be dispatched immediately.
|
||||
|
@ -455,14 +456,14 @@ public:
|
|||
template <typename Handler>
|
||||
void post(implementation_type& impl, Handler handler)
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(impl->mutex_);
|
||||
|
||||
// Allocate and construct an object to wrap the handler.
|
||||
typedef handler_wrapper<Handler> value_type;
|
||||
typedef handler_alloc_traits<Handler, value_type> alloc_traits;
|
||||
raw_handler_ptr<alloc_traits> raw_ptr(handler);
|
||||
handler_ptr<alloc_traits> ptr(raw_ptr, handler);
|
||||
|
||||
asio::detail::mutex::scoped_lock lock(impl->mutex_);
|
||||
|
||||
if (impl->current_handler_ == 0)
|
||||
{
|
||||
// This handler now has the lock, so can be dispatched immediately.
|
||||
|
|
|
@ -40,6 +40,7 @@ public:
|
|||
: asio::detail::service_base<task_io_service<Task> >(io_service),
|
||||
mutex_(),
|
||||
task_(use_service<Task>(io_service)),
|
||||
task_interrupted_(true),
|
||||
outstanding_work_(0),
|
||||
handler_queue_(&task_handler_),
|
||||
handler_queue_end_(&task_handler_),
|
||||
|
@ -80,8 +81,7 @@ public:
|
|||
typename call_stack<task_io_service>::context ctx(this);
|
||||
|
||||
idle_thread_info this_idle_thread;
|
||||
this_idle_thread.prev = &this_idle_thread;
|
||||
this_idle_thread.next = &this_idle_thread;
|
||||
this_idle_thread.next = 0;
|
||||
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
|
@ -98,8 +98,7 @@ public:
|
|||
typename call_stack<task_io_service>::context ctx(this);
|
||||
|
||||
idle_thread_info this_idle_thread;
|
||||
this_idle_thread.prev = &this_idle_thread;
|
||||
this_idle_thread.next = &this_idle_thread;
|
||||
this_idle_thread.next = 0;
|
||||
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
|
||||
|
@ -134,7 +133,7 @@ public:
|
|||
void stop()
|
||||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
stop_all_threads();
|
||||
stop_all_threads(lock);
|
||||
}
|
||||
|
||||
// Reset in preparation for a subsequent run invocation.
|
||||
|
@ -156,7 +155,7 @@ public:
|
|||
{
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
if (--outstanding_work_ == 0)
|
||||
stop_all_threads();
|
||||
stop_all_threads(lock);
|
||||
}
|
||||
|
||||
// Request invocation of the given handler.
|
||||
|
@ -201,9 +200,14 @@ public:
|
|||
++outstanding_work_;
|
||||
|
||||
// Wake up a thread to execute the handler.
|
||||
if (!interrupt_one_idle_thread())
|
||||
if (task_handler_.next_ == 0 && handler_queue_end_ != &task_handler_)
|
||||
if (!interrupt_one_idle_thread(lock))
|
||||
{
|
||||
if (!task_interrupted_)
|
||||
{
|
||||
task_interrupted_ = true;
|
||||
task_.interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -214,7 +218,7 @@ private:
|
|||
{
|
||||
if (outstanding_work_ == 0 && !stopped_)
|
||||
{
|
||||
stop_all_threads();
|
||||
stop_all_threads(lock);
|
||||
ec = asio::error_code();
|
||||
return 0;
|
||||
}
|
||||
|
@ -230,11 +234,14 @@ private:
|
|||
handler_queue_ = h->next_;
|
||||
if (handler_queue_ == 0)
|
||||
handler_queue_end_ = 0;
|
||||
bool more_handlers = (handler_queue_ != 0);
|
||||
lock.unlock();
|
||||
h->next_ = 0;
|
||||
|
||||
if (h == &task_handler_)
|
||||
{
|
||||
bool more_handlers = (handler_queue_ != 0);
|
||||
task_interrupted_ = more_handlers || polling;
|
||||
lock.unlock();
|
||||
|
||||
// If the task has already run and we're polling then we're done.
|
||||
if (task_has_run && polling)
|
||||
{
|
||||
|
@ -252,6 +259,7 @@ private:
|
|||
}
|
||||
else
|
||||
{
|
||||
lock.unlock();
|
||||
handler_cleanup c(lock, *this);
|
||||
|
||||
// Invoke the handler. May throw an exception.
|
||||
|
@ -264,31 +272,10 @@ private:
|
|||
else if (this_idle_thread)
|
||||
{
|
||||
// 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->prev = first_idle_thread_->prev;
|
||||
first_idle_thread_->prev->next = this_idle_thread;
|
||||
first_idle_thread_->prev = this_idle_thread;
|
||||
}
|
||||
this_idle_thread->next = first_idle_thread_;
|
||||
first_idle_thread_ = this_idle_thread;
|
||||
this_idle_thread->wakeup_event.clear();
|
||||
lock.unlock();
|
||||
this_idle_thread->wakeup_event.wait();
|
||||
lock.lock();
|
||||
if (this_idle_thread->next == this_idle_thread)
|
||||
{
|
||||
first_idle_thread_ = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (first_idle_thread_ == this_idle_thread)
|
||||
first_idle_thread_ = this_idle_thread->next;
|
||||
this_idle_thread->next->prev = this_idle_thread->prev;
|
||||
this_idle_thread->prev->next = this_idle_thread->next;
|
||||
this_idle_thread->next = this_idle_thread;
|
||||
this_idle_thread->prev = this_idle_thread;
|
||||
}
|
||||
this_idle_thread->wakeup_event.clear(lock);
|
||||
this_idle_thread->wakeup_event.wait(lock);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -302,39 +289,44 @@ private:
|
|||
}
|
||||
|
||||
// Stop the task and all idle threads.
|
||||
void stop_all_threads()
|
||||
void stop_all_threads(
|
||||
asio::detail::mutex::scoped_lock& lock)
|
||||
{
|
||||
stopped_ = true;
|
||||
interrupt_all_idle_threads();
|
||||
if (task_handler_.next_ == 0 && handler_queue_end_ != &task_handler_)
|
||||
interrupt_all_idle_threads(lock);
|
||||
if (!task_interrupted_)
|
||||
{
|
||||
task_interrupted_ = true;
|
||||
task_.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
// Interrupt a single idle thread. Returns true if a thread was interrupted,
|
||||
// false if no running thread could be found to interrupt.
|
||||
bool interrupt_one_idle_thread()
|
||||
bool interrupt_one_idle_thread(
|
||||
asio::detail::mutex::scoped_lock& lock)
|
||||
{
|
||||
if (first_idle_thread_)
|
||||
{
|
||||
first_idle_thread_->wakeup_event.signal();
|
||||
first_idle_thread_ = first_idle_thread_->next;
|
||||
idle_thread_info* idle_thread = first_idle_thread_;
|
||||
first_idle_thread_ = idle_thread->next;
|
||||
idle_thread->next = 0;
|
||||
idle_thread->wakeup_event.signal(lock);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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* current_idle_thread = first_idle_thread_->next;
|
||||
while (current_idle_thread != first_idle_thread_)
|
||||
{
|
||||
current_idle_thread->wakeup_event.signal();
|
||||
current_idle_thread = current_idle_thread->next;
|
||||
}
|
||||
idle_thread_info* idle_thread = first_idle_thread_;
|
||||
first_idle_thread_ = idle_thread->next;
|
||||
idle_thread->next = 0;
|
||||
idle_thread->wakeup_event.signal(lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -440,6 +432,7 @@ private:
|
|||
{
|
||||
// Reinsert the task at the end of the handler queue.
|
||||
lock_.lock();
|
||||
task_io_service_.task_interrupted_ = true;
|
||||
task_io_service_.task_handler_.next_ = 0;
|
||||
if (task_io_service_.handler_queue_end_)
|
||||
{
|
||||
|
@ -478,7 +471,7 @@ private:
|
|||
{
|
||||
lock_.lock();
|
||||
if (--task_io_service_.outstanding_work_ == 0)
|
||||
task_io_service_.stop_all_threads();
|
||||
task_io_service_.stop_all_threads(lock_);
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -503,6 +496,9 @@ private:
|
|||
}
|
||||
} task_handler_;
|
||||
|
||||
// Whether the task has been interrupted.
|
||||
bool task_interrupted_;
|
||||
|
||||
// The count of unfinished work.
|
||||
int outstanding_work_;
|
||||
|
||||
|
@ -522,7 +518,6 @@ private:
|
|||
struct idle_thread_info
|
||||
{
|
||||
event wakeup_event;
|
||||
idle_thread_info* prev;
|
||||
idle_thread_info* next;
|
||||
};
|
||||
|
||||
|
|
|
@ -48,7 +48,9 @@ public:
|
|||
// Constructor.
|
||||
timer_queue()
|
||||
: timers_(),
|
||||
heap_()
|
||||
heap_(),
|
||||
cancelled_timers_(0),
|
||||
cleanup_timers_(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -111,12 +113,17 @@ public:
|
|||
{
|
||||
timer_base* t = heap_[0];
|
||||
remove_timer(t);
|
||||
t->prev_ = 0;
|
||||
t->next_ = cleanup_timers_;
|
||||
cleanup_timers_ = t;
|
||||
t->invoke(asio::error_code());
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel the timer with the given token. The handler will be invoked
|
||||
// immediately with the result operation_aborted.
|
||||
// Cancel the timers with the given token. Any timers pending for the token
|
||||
// will be notified that they have been cancelled next time
|
||||
// dispatch_cancellations is called. Returns the number of timers that were
|
||||
// cancelled.
|
||||
std::size_t cancel_timer(void* timer_token)
|
||||
{
|
||||
std::size_t num_cancelled = 0;
|
||||
|
@ -129,7 +136,9 @@ public:
|
|||
{
|
||||
timer_base* next = t->next_;
|
||||
remove_timer(t);
|
||||
t->invoke(asio::error::operation_aborted);
|
||||
t->prev_ = 0;
|
||||
t->next_ = cancelled_timers_;
|
||||
cancelled_timers_ = t;
|
||||
t = next;
|
||||
++num_cancelled;
|
||||
}
|
||||
|
@ -137,6 +146,31 @@ public:
|
|||
return num_cancelled;
|
||||
}
|
||||
|
||||
// Dispatch any pending cancels for timers.
|
||||
virtual void dispatch_cancellations()
|
||||
{
|
||||
while (cancelled_timers_)
|
||||
{
|
||||
timer_base* this_timer = cancelled_timers_;
|
||||
cancelled_timers_ = this_timer->next_;
|
||||
this_timer->next_ = cleanup_timers_;
|
||||
cleanup_timers_ = this_timer;
|
||||
this_timer->invoke(asio::error::operation_aborted);
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy timers that are waiting to be cleaned up.
|
||||
virtual void cleanup_timers()
|
||||
{
|
||||
while (cleanup_timers_)
|
||||
{
|
||||
timer_base* next_timer = cleanup_timers_->next_;
|
||||
cleanup_timers_->next_ = 0;
|
||||
cleanup_timers_->destroy();
|
||||
cleanup_timers_ = next_timer;
|
||||
}
|
||||
}
|
||||
|
||||
// Destroy all timers.
|
||||
virtual void destroy_timers()
|
||||
{
|
||||
|
@ -151,6 +185,7 @@ public:
|
|||
}
|
||||
heap_.clear();
|
||||
timers_.clear();
|
||||
cleanup_timers();
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -238,8 +273,7 @@ private:
|
|||
static void invoke_handler(timer_base* base,
|
||||
const asio::error_code& result)
|
||||
{
|
||||
std::auto_ptr<timer<Handler> > t(static_cast<timer<Handler>*>(base));
|
||||
t->handler_(result);
|
||||
static_cast<timer<Handler>*>(base)->handler_(result);
|
||||
}
|
||||
|
||||
// Destroy the handler.
|
||||
|
@ -338,6 +372,12 @@ private:
|
|||
|
||||
// The heap of timers, with the earliest timer at the front.
|
||||
std::vector<timer_base*> heap_;
|
||||
|
||||
// The list of timers to be cancelled.
|
||||
timer_base* cancelled_timers_;
|
||||
|
||||
// The list of timers to be destroyed.
|
||||
timer_base* cleanup_timers_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
|
|
@ -44,6 +44,12 @@ public:
|
|||
// Dispatch all ready timers.
|
||||
virtual void dispatch_timers() = 0;
|
||||
|
||||
// Dispatch any pending cancels for timers.
|
||||
virtual void dispatch_cancellations() = 0;
|
||||
|
||||
// Destroy timers that are waiting to be cleaned up.
|
||||
virtual void cleanup_timers() = 0;
|
||||
|
||||
// Destroy all timers.
|
||||
virtual void destroy_timers() = 0;
|
||||
};
|
||||
|
|
|
@ -23,11 +23,13 @@
|
|||
|
||||
#if defined(BOOST_WINDOWS)
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
|
@ -46,7 +48,8 @@ public:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error, asio::native_ecat),
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
"event");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -59,21 +62,31 @@ public:
|
|||
}
|
||||
|
||||
// Signal the event.
|
||||
void signal()
|
||||
template <typename Lock>
|
||||
void signal(Lock& lock)
|
||||
{
|
||||
BOOST_ASSERT(lock.locked());
|
||||
(void)lock;
|
||||
::SetEvent(event_);
|
||||
}
|
||||
|
||||
// Reset the event.
|
||||
void clear()
|
||||
template <typename Lock>
|
||||
void clear(Lock& lock)
|
||||
{
|
||||
BOOST_ASSERT(lock.locked());
|
||||
(void)lock;
|
||||
::ResetEvent(event_);
|
||||
}
|
||||
|
||||
// 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);
|
||||
lock.lock();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -63,7 +63,8 @@ public:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error, asio::native_ecat),
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
"iocp");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -173,7 +174,8 @@ public:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error, asio::native_ecat),
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
"pqcs");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -228,7 +230,8 @@ public:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error, asio::native_ecat),
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
"pqcs");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -247,7 +250,8 @@ public:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error, asio::native_ecat),
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
"pqcs");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -312,7 +316,7 @@ private:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
ec = asio::error_code(last_error,
|
||||
asio::native_ecat);
|
||||
asio::error::system_category);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include <boost/config.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
|
||||
// This service is only supported on Win32 (NT4 and later).
|
||||
#if !defined(ASIO_DISABLE_IOCP)
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
|
|
|
@ -137,7 +137,7 @@ public:
|
|||
enum
|
||||
{
|
||||
enable_connection_aborted = 1, // User wants connection_aborted errors.
|
||||
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.
|
||||
};
|
||||
|
||||
|
@ -170,7 +170,7 @@ public:
|
|||
typedef detail::select_reactor<true> reactor_type;
|
||||
|
||||
// The maximum number of buffers to support in a single operation.
|
||||
enum { max_buffers = 16 };
|
||||
enum { max_buffers = 64 < max_iov_len ? 64 : max_iov_len };
|
||||
|
||||
// Constructor.
|
||||
win_iocp_socket_service(asio::io_service& io_service)
|
||||
|
@ -192,7 +192,7 @@ public:
|
|||
while (impl)
|
||||
{
|
||||
asio::error_code ignored_ec;
|
||||
close(*impl, ignored_ec);
|
||||
close_for_destruction(*impl);
|
||||
impl = impl->next_;
|
||||
}
|
||||
}
|
||||
|
@ -217,34 +217,7 @@ public:
|
|||
// Destroy a socket implementation.
|
||||
void destroy(implementation_type& impl)
|
||||
{
|
||||
if (impl.socket_ != invalid_socket)
|
||||
{
|
||||
// Check if the reactor was created, in which case we need to close the
|
||||
// socket on the reactor as well to cancel any operations that might be
|
||||
// running there.
|
||||
reactor_type* reactor = static_cast<reactor_type*>(
|
||||
interlocked_compare_exchange_pointer(
|
||||
reinterpret_cast<void**>(&reactor_), 0, 0));
|
||||
if (reactor)
|
||||
reactor->close_descriptor(impl.socket_);
|
||||
|
||||
if (impl.flags_ & implementation_type::user_set_linger)
|
||||
{
|
||||
::linger opt;
|
||||
opt.l_onoff = 0;
|
||||
opt.l_linger = 0;
|
||||
asio::error_code ignored_ec;
|
||||
socket_ops::setsockopt(impl.socket_,
|
||||
SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec);
|
||||
}
|
||||
|
||||
asio::error_code ignored_ec;
|
||||
socket_ops::close(impl.socket_, ignored_ec);
|
||||
impl.socket_ = invalid_socket;
|
||||
impl.flags_ = 0;
|
||||
impl.cancel_token_.reset();
|
||||
impl.safe_cancellation_thread_id_ = 0;
|
||||
}
|
||||
close_for_destruction(impl);
|
||||
|
||||
// Remove implementation from linked list of all implementations.
|
||||
asio::detail::mutex::scoped_lock lock(mutex_);
|
||||
|
@ -353,6 +326,25 @@ public:
|
|||
{
|
||||
ec = asio::error::bad_descriptor;
|
||||
}
|
||||
else if (FARPROC cancel_io_ex_ptr = ::GetProcAddress(
|
||||
::GetModuleHandle("KERNEL32"), "CancelIoEx"))
|
||||
{
|
||||
// The version of Windows supports cancellation from any thread.
|
||||
typedef BOOL (WINAPI* cancel_io_ex_t)(HANDLE, LPOVERLAPPED);
|
||||
cancel_io_ex_t cancel_io_ex = (cancel_io_ex_t)cancel_io_ex_ptr;
|
||||
socket_type sock = impl.socket_;
|
||||
HANDLE sock_as_handle = reinterpret_cast<HANDLE>(sock);
|
||||
if (!cancel_io_ex(sock_as_handle, 0))
|
||||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
}
|
||||
else
|
||||
{
|
||||
ec = asio::error_code();
|
||||
}
|
||||
}
|
||||
else if (impl.safe_cancellation_thread_id_ == 0)
|
||||
{
|
||||
// No operations have been started, so there's nothing to cancel.
|
||||
|
@ -367,7 +359,8 @@ public:
|
|||
if (!::CancelIo(sock_as_handle))
|
||||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
ec = asio::error_code(last_error, asio::native_ecat);
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -475,7 +468,12 @@ public:
|
|||
if (option.level(impl.protocol_) == SOL_SOCKET
|
||||
&& 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_,
|
||||
|
@ -668,7 +666,8 @@ public:
|
|||
last_error = WSAECONNRESET;
|
||||
else if (last_error == ERROR_PORT_UNREACHABLE)
|
||||
last_error = WSAECONNREFUSED;
|
||||
ec = asio::error_code(last_error, asio::native_ecat);
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -719,7 +718,8 @@ public:
|
|||
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
|
||||
// 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 (handler_op->cancel_token_.expired())
|
||||
|
@ -821,7 +821,8 @@ public:
|
|||
{
|
||||
asio::io_service::work work(this->io_service());
|
||||
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));
|
||||
}
|
||||
else
|
||||
|
@ -865,7 +866,8 @@ public:
|
|||
DWORD last_error = ::WSAGetLastError();
|
||||
if (last_error == ERROR_PORT_UNREACHABLE)
|
||||
last_error = WSAECONNREFUSED;
|
||||
ec = asio::error_code(last_error, asio::native_ecat);
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -914,7 +916,8 @@ public:
|
|||
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
|
||||
// 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)
|
||||
{
|
||||
ec = asio::error::connection_refused;
|
||||
|
@ -997,7 +1000,8 @@ public:
|
|||
{
|
||||
asio::io_service::work work(this->io_service());
|
||||
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));
|
||||
}
|
||||
else
|
||||
|
@ -1051,7 +1055,8 @@ public:
|
|||
last_error = WSAECONNRESET;
|
||||
else if (last_error == ERROR_PORT_UNREACHABLE)
|
||||
last_error = WSAECONNREFUSED;
|
||||
ec = asio::error_code(last_error, asio::native_ecat);
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
return 0;
|
||||
}
|
||||
if (bytes_transferred == 0)
|
||||
|
@ -1109,7 +1114,8 @@ public:
|
|||
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
|
||||
// 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 (handler_op->cancel_token_.expired())
|
||||
|
@ -1216,7 +1222,8 @@ public:
|
|||
{
|
||||
asio::io_service::work work(this->io_service());
|
||||
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));
|
||||
}
|
||||
else
|
||||
|
@ -1262,7 +1269,8 @@ public:
|
|||
DWORD last_error = ::WSAGetLastError();
|
||||
if (last_error == ERROR_PORT_UNREACHABLE)
|
||||
last_error = WSAECONNREFUSED;
|
||||
ec = asio::error_code(last_error, asio::native_ecat);
|
||||
ec = asio::error_code(last_error,
|
||||
asio::error::system_category);
|
||||
return 0;
|
||||
}
|
||||
if (bytes_transferred == 0)
|
||||
|
@ -1328,7 +1336,8 @@ public:
|
|||
#endif // defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
|
||||
// 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)
|
||||
{
|
||||
ec = asio::error::connection_refused;
|
||||
|
@ -1422,7 +1431,8 @@ public:
|
|||
{
|
||||
asio::io_service::work work(this->io_service());
|
||||
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));
|
||||
}
|
||||
else
|
||||
|
@ -1659,7 +1669,8 @@ public:
|
|||
ptr.reset();
|
||||
|
||||
// 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(
|
||||
detail::bind_handler(handler, ec), &handler);
|
||||
}
|
||||
|
@ -1759,7 +1770,8 @@ public:
|
|||
{
|
||||
asio::io_service::work work(this->io_service());
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -1835,8 +1847,8 @@ public:
|
|||
// If connection failed then post the handler with the error code.
|
||||
if (connect_error)
|
||||
{
|
||||
ec = asio::error_code(
|
||||
connect_error, asio::native_ecat);
|
||||
ec = asio::error_code(connect_error,
|
||||
asio::error::system_category);
|
||||
io_service_.post(bind_handler(handler_, ec));
|
||||
return true;
|
||||
}
|
||||
|
@ -1950,26 +1962,66 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
// Helper function to provide InterlockedCompareExchangePointer functionality
|
||||
// on very old Platform SDKs.
|
||||
// Helper function to close a socket when the associated object is being
|
||||
// destroyed.
|
||||
void close_for_destruction(implementation_type& impl)
|
||||
{
|
||||
if (is_open(impl))
|
||||
{
|
||||
// Check if the reactor was created, in which case we need to close the
|
||||
// socket on the reactor as well to cancel any operations that might be
|
||||
// running there.
|
||||
reactor_type* reactor = static_cast<reactor_type*>(
|
||||
interlocked_compare_exchange_pointer(
|
||||
reinterpret_cast<void**>(&reactor_), 0, 0));
|
||||
if (reactor)
|
||||
reactor->close_descriptor(impl.socket_);
|
||||
|
||||
// The socket destructor must not block. If the user has changed the
|
||||
// linger option to block in the foreground, we will change it back to the
|
||||
// default so that the closure is performed in the background.
|
||||
if (impl.flags_ & implementation_type::close_might_block)
|
||||
{
|
||||
::linger opt;
|
||||
opt.l_onoff = 0;
|
||||
opt.l_linger = 0;
|
||||
asio::error_code ignored_ec;
|
||||
socket_ops::setsockopt(impl.socket_,
|
||||
SOL_SOCKET, SO_LINGER, &opt, sizeof(opt), ignored_ec);
|
||||
}
|
||||
|
||||
asio::error_code ignored_ec;
|
||||
socket_ops::close(impl.socket_, ignored_ec);
|
||||
impl.socket_ = invalid_socket;
|
||||
impl.flags_ = 0;
|
||||
impl.cancel_token_.reset();
|
||||
impl.safe_cancellation_thread_id_ = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to emulate InterlockedCompareExchangePointer functionality
|
||||
// for:
|
||||
// - very old Platform SDKs; and
|
||||
// - platform SDKs where MSVC's /Wp64 option causes spurious warnings.
|
||||
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(
|
||||
reinterpret_cast<LONG*>(dest), reinterpret_cast<LONG>(exch),
|
||||
reinterpret_cast<PLONG>(dest), reinterpret_cast<LONG>(exch),
|
||||
reinterpret_cast<LONG>(cmp)));
|
||||
#else
|
||||
return InterlockedCompareExchangePointer(dest, exch, cmp);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Helper function to provide InterlockedExchangePointer functionality on very
|
||||
// old Platform SDKs.
|
||||
// Helper function to emulate InterlockedExchangePointer functionality for:
|
||||
// - very old Platform SDKs; and
|
||||
// - platform SDKs where MSVC's /Wp64 option causes spurious warnings.
|
||||
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(
|
||||
reinterpret_cast<LONG*>(dest), reinterpret_cast<LONG>(val)));
|
||||
reinterpret_cast<PLONG>(dest), reinterpret_cast<LONG>(val)));
|
||||
#else
|
||||
return InterlockedExchangePointer(dest, val);
|
||||
#endif
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#if defined(BOOST_WINDOWS)
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
|
@ -48,7 +49,7 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
"mutex");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
@ -67,7 +68,7 @@ public:
|
|||
if (error != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(error, asio::native_ecat),
|
||||
asio::error_code(error, asio::error::system_category),
|
||||
"mutex");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#if defined(BOOST_WINDOWS)
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
|
@ -54,7 +55,8 @@ public:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error, asio::native_ecat),
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
"thread");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
|
||||
#if defined(BOOST_WINDOWS)
|
||||
|
||||
#include "asio/error.hpp"
|
||||
#include "asio/system_error.hpp"
|
||||
#include "asio/detail/noncopyable.hpp"
|
||||
#include "asio/detail/socket_types.hpp"
|
||||
|
@ -47,7 +48,8 @@ public:
|
|||
{
|
||||
DWORD last_error = ::GetLastError();
|
||||
asio::system_error e(
|
||||
asio::error_code(last_error, asio::native_ecat),
|
||||
asio::error_code(last_error,
|
||||
asio::error::system_category),
|
||||
"tss");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -85,7 +85,8 @@ public:
|
|||
if (this != &instance_ && ref_->result() != 0)
|
||||
{
|
||||
asio::system_error e(
|
||||
asio::error_code(ref_->result(), asio::native_ecat),
|
||||
asio::error_code(ref_->result(),
|
||||
asio::error::system_category),
|
||||
"winsock");
|
||||
boost::throw_exception(e);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,10 @@
|
|||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
|
||||
#include "asio/detail/push_options.hpp"
|
||||
#include <boost/type_traits.hpp>
|
||||
#include "asio/detail/pop_options.hpp"
|
||||
|
||||
#include "asio/detail/bind_handler.hpp"
|
||||
#include "asio/detail/handler_alloc_helpers.hpp"
|
||||
#include "asio/detail/handler_invoke_helpers.hpp"
|
||||
|
@ -30,7 +34,9 @@ class wrapped_handler
|
|||
public:
|
||||
typedef void result_type;
|
||||
|
||||
wrapped_handler(Dispatcher& dispatcher, Handler handler)
|
||||
wrapped_handler(
|
||||
typename boost::add_reference<Dispatcher>::type dispatcher,
|
||||
Handler handler)
|
||||
: dispatcher_(dispatcher),
|
||||
handler_(handler)
|
||||
{
|
||||
|
@ -117,7 +123,7 @@ public:
|
|||
}
|
||||
|
||||
//private:
|
||||
Dispatcher& dispatcher_;
|
||||
Dispatcher dispatcher_;
|
||||
Handler handler_;
|
||||
};
|
||||
|
||||
|
@ -171,9 +177,9 @@ inline void asio_handler_invoke(const Function& function,
|
|||
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,
|
||||
rewrapped_handler<Dispatcher, Handler>* this_handler)
|
||||
rewrapped_handler<Handler, Context>* this_handler)
|
||||
{
|
||||
asio_handler_invoke_helpers::invoke(
|
||||
function, &this_handler->context_);
|
||||
|
|
|
@ -37,327 +37,195 @@
|
|||
/// INTERNAL ONLY.
|
||||
# define ASIO_WIN_OR_POSIX(e_win, e_posix) implementation_defined
|
||||
#elif defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
# define ASIO_NATIVE_ERROR(e) \
|
||||
asio::error_code(e, \
|
||||
asio::native_ecat)
|
||||
# define ASIO_SOCKET_ERROR(e) \
|
||||
asio::error_code(WSA ## e, \
|
||||
asio::native_ecat)
|
||||
# define ASIO_NETDB_ERROR(e) \
|
||||
asio::error_code(WSA ## e, \
|
||||
asio::native_ecat)
|
||||
# define ASIO_GETADDRINFO_ERROR(e) \
|
||||
asio::error_code(WSA ## e, \
|
||||
asio::native_ecat)
|
||||
# define ASIO_MISC_ERROR(e) \
|
||||
asio::error_code(e, \
|
||||
asio::misc_ecat)
|
||||
# define ASIO_NATIVE_ERROR(e) e
|
||||
# define ASIO_SOCKET_ERROR(e) WSA ## e
|
||||
# define ASIO_NETDB_ERROR(e) WSA ## e
|
||||
# define ASIO_GETADDRINFO_ERROR(e) WSA ## e
|
||||
# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_win
|
||||
#else
|
||||
# define ASIO_NATIVE_ERROR(e) \
|
||||
asio::error_code(e, \
|
||||
asio::native_ecat)
|
||||
# define ASIO_SOCKET_ERROR(e) \
|
||||
asio::error_code(e, \
|
||||
asio::native_ecat)
|
||||
# define ASIO_NETDB_ERROR(e) \
|
||||
asio::error_code(e, \
|
||||
asio::netdb_ecat)
|
||||
# define ASIO_GETADDRINFO_ERROR(e) \
|
||||
asio::error_code(e, \
|
||||
asio::addrinfo_ecat)
|
||||
# define ASIO_MISC_ERROR(e) \
|
||||
asio::error_code(e, \
|
||||
asio::misc_ecat)
|
||||
# define ASIO_NATIVE_ERROR(e) e
|
||||
# define ASIO_SOCKET_ERROR(e) e
|
||||
# define ASIO_NETDB_ERROR(e) e
|
||||
# define ASIO_GETADDRINFO_ERROR(e) e
|
||||
# define ASIO_WIN_OR_POSIX(e_win, e_posix) e_posix
|
||||
#endif
|
||||
|
||||
namespace asio {
|
||||
namespace error {
|
||||
|
||||
namespace detail {
|
||||
|
||||
/// Hack to keep asio library header-file-only.
|
||||
template <typename T>
|
||||
class error_base
|
||||
enum basic_errors
|
||||
{
|
||||
public:
|
||||
// boostify: error category declarations go here.
|
||||
|
||||
/// Permission denied.
|
||||
static const asio::error_code access_denied;
|
||||
access_denied = ASIO_SOCKET_ERROR(EACCES),
|
||||
|
||||
/// 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.
|
||||
static const asio::error_code address_in_use;
|
||||
address_in_use = ASIO_SOCKET_ERROR(EADDRINUSE),
|
||||
|
||||
/// Transport endpoint is already connected.
|
||||
static const asio::error_code already_connected;
|
||||
|
||||
/// Already open.
|
||||
static const asio::error_code already_open;
|
||||
already_connected = ASIO_SOCKET_ERROR(EISCONN),
|
||||
|
||||
/// Operation already in progress.
|
||||
static const asio::error_code already_started;
|
||||
already_started = ASIO_SOCKET_ERROR(EALREADY),
|
||||
|
||||
/// A connection has been aborted.
|
||||
static const asio::error_code connection_aborted;
|
||||
connection_aborted = ASIO_SOCKET_ERROR(ECONNABORTED),
|
||||
|
||||
/// Connection refused.
|
||||
static const asio::error_code connection_refused;
|
||||
connection_refused = ASIO_SOCKET_ERROR(ECONNREFUSED),
|
||||
|
||||
/// Connection reset by peer.
|
||||
static const asio::error_code connection_reset;
|
||||
connection_reset = ASIO_SOCKET_ERROR(ECONNRESET),
|
||||
|
||||
/// Bad file descriptor.
|
||||
static const asio::error_code bad_descriptor;
|
||||
|
||||
/// End of file or stream.
|
||||
static const asio::error_code eof;
|
||||
bad_descriptor = ASIO_SOCKET_ERROR(EBADF),
|
||||
|
||||
/// Bad address.
|
||||
static const asio::error_code fault;
|
||||
|
||||
/// Host not found (authoritative).
|
||||
static const asio::error_code host_not_found;
|
||||
|
||||
/// Host not found (non-authoritative).
|
||||
static const asio::error_code host_not_found_try_again;
|
||||
fault = ASIO_SOCKET_ERROR(EFAULT),
|
||||
|
||||
/// No route to host.
|
||||
static const asio::error_code host_unreachable;
|
||||
host_unreachable = ASIO_SOCKET_ERROR(EHOSTUNREACH),
|
||||
|
||||
/// Operation now in progress.
|
||||
static const asio::error_code in_progress;
|
||||
in_progress = ASIO_SOCKET_ERROR(EINPROGRESS),
|
||||
|
||||
/// Interrupted system call.
|
||||
static const asio::error_code interrupted;
|
||||
interrupted = ASIO_SOCKET_ERROR(EINTR),
|
||||
|
||||
/// Invalid argument.
|
||||
static const asio::error_code invalid_argument;
|
||||
invalid_argument = ASIO_SOCKET_ERROR(EINVAL),
|
||||
|
||||
/// Message too long.
|
||||
static const asio::error_code message_size;
|
||||
message_size = ASIO_SOCKET_ERROR(EMSGSIZE),
|
||||
|
||||
/// Network is down.
|
||||
static const asio::error_code network_down;
|
||||
network_down = ASIO_SOCKET_ERROR(ENETDOWN),
|
||||
|
||||
/// Network dropped connection on reset.
|
||||
static const asio::error_code network_reset;
|
||||
network_reset = ASIO_SOCKET_ERROR(ENETRESET),
|
||||
|
||||
/// Network is unreachable.
|
||||
static const asio::error_code network_unreachable;
|
||||
network_unreachable = ASIO_SOCKET_ERROR(ENETUNREACH),
|
||||
|
||||
/// Too many open files.
|
||||
static const asio::error_code no_descriptors;
|
||||
no_descriptors = ASIO_SOCKET_ERROR(EMFILE),
|
||||
|
||||
/// No buffer space available.
|
||||
static const asio::error_code no_buffer_space;
|
||||
|
||||
/// The query is valid but does not have associated address data.
|
||||
static const asio::error_code no_data;
|
||||
no_buffer_space = ASIO_SOCKET_ERROR(ENOBUFS),
|
||||
|
||||
/// 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.
|
||||
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.
|
||||
static const asio::error_code no_protocol_option;
|
||||
|
||||
/// A non-recoverable error occurred.
|
||||
static const asio::error_code no_recovery;
|
||||
no_protocol_option = ASIO_SOCKET_ERROR(ENOPROTOOPT),
|
||||
|
||||
/// Transport endpoint is not connected.
|
||||
static const asio::error_code not_connected;
|
||||
|
||||
/// Element not found.
|
||||
static const asio::error_code not_found;
|
||||
not_connected = ASIO_SOCKET_ERROR(ENOTCONN),
|
||||
|
||||
/// Socket operation on non-socket.
|
||||
static const asio::error_code not_socket;
|
||||
not_socket = ASIO_SOCKET_ERROR(ENOTSOCK),
|
||||
|
||||
/// 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.
|
||||
static const asio::error_code operation_not_supported;
|
||||
|
||||
/// The service is not supported for the given socket type.
|
||||
static const asio::error_code service_not_found;
|
||||
|
||||
/// The socket type is not supported.
|
||||
static const asio::error_code socket_type_not_supported;
|
||||
operation_not_supported = ASIO_SOCKET_ERROR(EOPNOTSUPP),
|
||||
|
||||
/// Cannot send after transport endpoint shutdown.
|
||||
static const asio::error_code shut_down;
|
||||
shut_down = ASIO_SOCKET_ERROR(ESHUTDOWN),
|
||||
|
||||
/// Connection timed out.
|
||||
static const asio::error_code timed_out;
|
||||
timed_out = ASIO_SOCKET_ERROR(ETIMEDOUT),
|
||||
|
||||
/// 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.
|
||||
static const asio::error_code would_block;
|
||||
would_block = ASIO_SOCKET_ERROR(EWOULDBLOCK)
|
||||
};
|
||||
|
||||
private:
|
||||
error_base();
|
||||
enum netdb_errors
|
||||
{
|
||||
/// Host not found (authoritative).
|
||||
host_not_found = ASIO_NETDB_ERROR(HOST_NOT_FOUND),
|
||||
|
||||
/// Host not found (non-authoritative).
|
||||
host_not_found_try_again = ASIO_NETDB_ERROR(TRY_AGAIN),
|
||||
|
||||
/// The query is valid but does not have associated address data.
|
||||
no_data = ASIO_NETDB_ERROR(NO_DATA),
|
||||
|
||||
/// A non-recoverable error occurred.
|
||||
no_recovery = ASIO_NETDB_ERROR(NO_RECOVERY)
|
||||
};
|
||||
|
||||
enum addrinfo_errors
|
||||
{
|
||||
/// The service is not supported for the given socket type.
|
||||
service_not_found = ASIO_WIN_OR_POSIX(
|
||||
ASIO_NATIVE_ERROR(WSATYPE_NOT_FOUND),
|
||||
ASIO_GETADDRINFO_ERROR(EAI_SERVICE)),
|
||||
|
||||
/// The socket type is not supported.
|
||||
socket_type_not_supported = ASIO_WIN_OR_POSIX(
|
||||
ASIO_NATIVE_ERROR(WSAESOCKTNOSUPPORT),
|
||||
ASIO_GETADDRINFO_ERROR(EAI_SOCKTYPE))
|
||||
};
|
||||
|
||||
enum misc_errors
|
||||
{
|
||||
/// Already open.
|
||||
already_open = 1,
|
||||
|
||||
/// End of file or stream.
|
||||
eof,
|
||||
|
||||
/// Element not found.
|
||||
not_found
|
||||
};
|
||||
|
||||
// boostify: error category definitions go here.
|
||||
|
||||
template <typename T> const asio::error_code
|
||||
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>
|
||||
inline asio::error_code make_error_code(basic_errors e)
|
||||
{
|
||||
private:
|
||||
error();
|
||||
};
|
||||
return asio::error_code(static_cast<int>(e), system_category);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
#undef ASIO_NATIVE_ERROR
|
||||
#undef ASIO_SOCKET_ERROR
|
||||
#undef ASIO_NETDB_ERROR
|
||||
#undef ASIO_GETADDRINFO_ERROR
|
||||
#undef ASIO_MISC_ERROR
|
||||
#undef ASIO_WIN_OR_POSIX
|
||||
|
||||
#include "asio/impl/error_code.ipp"
|
||||
|
|
|
@ -32,24 +32,27 @@
|
|||
|
||||
namespace asio {
|
||||
|
||||
/// Available error code categories.
|
||||
enum error_category
|
||||
namespace error
|
||||
{
|
||||
/// Native error codes.
|
||||
native_ecat = ASIO_WIN_OR_POSIX(0, 0),
|
||||
/// Available error code categories.
|
||||
enum error_category
|
||||
{
|
||||
/// System error codes.
|
||||
system_category = ASIO_WIN_OR_POSIX(0, 0),
|
||||
|
||||
/// Error codes from NetDB functions.
|
||||
netdb_ecat = ASIO_WIN_OR_POSIX(native_ecat, 1),
|
||||
/// Error codes from NetDB functions.
|
||||
netdb_category = ASIO_WIN_OR_POSIX(system_category, 1),
|
||||
|
||||
/// Error codes from getaddrinfo.
|
||||
addrinfo_ecat = ASIO_WIN_OR_POSIX(native_ecat, 2),
|
||||
/// Error codes from getaddrinfo.
|
||||
addrinfo_category = ASIO_WIN_OR_POSIX(system_category, 2),
|
||||
|
||||
/// Miscellaneous error codes.
|
||||
misc_ecat = ASIO_WIN_OR_POSIX(3, 3),
|
||||
/// Miscellaneous error codes.
|
||||
misc_category = ASIO_WIN_OR_POSIX(3, 3),
|
||||
|
||||
/// SSL error codes.
|
||||
ssl_ecat = ASIO_WIN_OR_POSIX(4, 4)
|
||||
};
|
||||
/// SSL error codes.
|
||||
ssl_category = ASIO_WIN_OR_POSIX(4, 4)
|
||||
};
|
||||
} // namespace error
|
||||
|
||||
/// Class to represent an error code value.
|
||||
class error_code
|
||||
|
@ -61,17 +64,24 @@ public:
|
|||
/// Default constructor.
|
||||
error_code()
|
||||
: value_(0),
|
||||
category_(native_ecat)
|
||||
category_(error::system_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),
|
||||
category_(c)
|
||||
{
|
||||
}
|
||||
|
||||
/// Construct from an error code enum.
|
||||
template <typename ErrorEnum>
|
||||
error_code(ErrorEnum e)
|
||||
{
|
||||
*this = make_error_code(e);
|
||||
}
|
||||
|
||||
/// Get the error value.
|
||||
value_type value() const
|
||||
{
|
||||
|
@ -79,7 +89,7 @@ public:
|
|||
}
|
||||
|
||||
/// Get the error category.
|
||||
error_category category() const
|
||||
error::error_category category() const
|
||||
{
|
||||
return category_;
|
||||
}
|
||||
|
@ -125,7 +135,7 @@ private:
|
|||
value_type value_;
|
||||
|
||||
// The category associated with the error code.
|
||||
error_category category_;
|
||||
error::error_category category_;
|
||||
};
|
||||
|
||||
} // 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.";
|
||||
if (*this == error::not_found)
|
||||
return "Not found.";
|
||||
if (category_ == ssl_ecat)
|
||||
if (category_ == error::ssl_category)
|
||||
return "SSL error.";
|
||||
#if defined(BOOST_WINDOWS) || defined(__CYGWIN__)
|
||||
value_type value = value_;
|
||||
if (category() != error::system_category && *this != error::eof)
|
||||
return "asio error";
|
||||
if (*this == error::eof)
|
||||
value = ERROR_HANDLE_EOF;
|
||||
char* msg = 0;
|
||||
|
@ -76,6 +78,8 @@ inline std::string error_code::message() const
|
|||
return "Service not found.";
|
||||
if (*this == error::socket_type_not_supported)
|
||||
return "Socket type not supported.";
|
||||
if (category() != error::system_category)
|
||||
return "asio error";
|
||||
#if defined(__sun) || defined(__QNX__)
|
||||
return strerror(value_);
|
||||
#elif defined(__MACH__) && defined(__APPLE__) \
|
||||
|
|
|
@ -128,11 +128,11 @@ template <typename Handler>
|
|||
#if defined(GENERATING_DOCUMENTATION)
|
||||
unspecified
|
||||
#else
|
||||
inline detail::wrapped_handler<io_service, Handler>
|
||||
inline detail::wrapped_handler<io_service&, Handler>
|
||||
#endif
|
||||
io_service::wrap(Handler handler)
|
||||
{
|
||||
return detail::wrapped_handler<io_service, Handler>(*this, handler);
|
||||
return detail::wrapped_handler<io_service&, Handler>(*this, handler);
|
||||
}
|
||||
|
||||
inline io_service::work::work(asio::io_service& io_service)
|
||||
|
|
|
@ -311,7 +311,8 @@ namespace detail
|
|||
if (streambuf_.size() == streambuf_.max_size())
|
||||
{
|
||||
std::size_t bytes = 0;
|
||||
handler_(error::not_found, bytes);
|
||||
asio::error_code ec(error::not_found);
|
||||
handler_(ec, bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -388,7 +389,8 @@ void async_read_until(AsyncReadStream& s,
|
|||
// No match. Check if buffer is full.
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -469,7 +471,8 @@ namespace detail
|
|||
if (streambuf_.size() == streambuf_.max_size())
|
||||
{
|
||||
std::size_t bytes = 0;
|
||||
handler_(error::not_found, bytes);
|
||||
asio::error_code ec(error::not_found);
|
||||
handler_(ec, bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -559,7 +562,8 @@ void async_read_until(AsyncReadStream& s,
|
|||
// Check if buffer is full.
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -641,7 +645,8 @@ namespace detail
|
|||
if (streambuf_.size() == streambuf_.max_size())
|
||||
{
|
||||
std::size_t bytes = 0;
|
||||
handler_(error::not_found, bytes);
|
||||
asio::error_code ec(error::not_found);
|
||||
handler_(ec, bytes);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -731,7 +736,8 @@ void async_read_until(AsyncReadStream& s,
|
|||
// Check if buffer is full.
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -320,7 +320,7 @@ public:
|
|||
#if defined(GENERATING_DOCUMENTATION)
|
||||
unspecified
|
||||
#else
|
||||
detail::wrapped_handler<io_service, Handler>
|
||||
detail::wrapped_handler<io_service&, Handler>
|
||||
#endif
|
||||
wrap(Handler handler);
|
||||
|
||||
|
|
|
@ -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.
|
||||
protocol_type protocol() const
|
||||
{
|
||||
if (is_v4())
|
||||
if (is_v4(data_))
|
||||
return InternetProtocol::v4();
|
||||
return InternetProtocol::v6();
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ public:
|
|||
/// Get the underlying size of the endpoint in the native type.
|
||||
size_type size() const
|
||||
{
|
||||
if (is_v4())
|
||||
if (is_v4(data_))
|
||||
return sizeof(asio::detail::sockaddr_in4_type);
|
||||
else
|
||||
return sizeof(asio::detail::sockaddr_in6_type);
|
||||
|
@ -218,7 +218,7 @@ public:
|
|||
/// the host's byte order.
|
||||
unsigned short port() const
|
||||
{
|
||||
if (is_v4())
|
||||
if (is_v4(data_))
|
||||
{
|
||||
return asio::detail::socket_ops::network_to_host_short(
|
||||
reinterpret_cast<const asio::detail::sockaddr_in4_type&>(
|
||||
|
@ -236,7 +236,7 @@ public:
|
|||
/// the host's byte order.
|
||||
void port(unsigned short port_num)
|
||||
{
|
||||
if (is_v4())
|
||||
if (is_v4(data_))
|
||||
{
|
||||
reinterpret_cast<asio::detail::sockaddr_in4_type&>(data_).sin_port
|
||||
= asio::detail::socket_ops::host_to_network_short(port_num);
|
||||
|
@ -252,7 +252,7 @@ public:
|
|||
asio::ip::address address() const
|
||||
{
|
||||
using namespace std; // For memcpy.
|
||||
if (is_v4())
|
||||
if (is_v4(data_))
|
||||
{
|
||||
const asio::detail::sockaddr_in4_type& data
|
||||
= reinterpret_cast<const asio::detail::sockaddr_in4_type&>(
|
||||
|
@ -306,15 +306,27 @@ public:
|
|||
|
||||
private:
|
||||
// Helper function to determine whether the endpoint is IPv4.
|
||||
bool is_v4() const
|
||||
{
|
||||
#if defined(_AIX)
|
||||
return data_.__ss_family == AF_INET;
|
||||
#else
|
||||
return data_.ss_family == AF_INET;
|
||||
#endif
|
||||
template <typename T, unsigned char (T::*)> struct is_v4_helper {};
|
||||
|
||||
template <typename T>
|
||||
static bool is_v4(const T& ss, is_v4_helper<T, &T::ss_family>* = 0)
|
||||
{
|
||||
return ss.ss_family == AF_INET;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static bool is_v4(const T& ss, is_v4_helper<T, &T::__ss_family>* = 0)
|
||||
{
|
||||
return ss.__ss_family == AF_INET;
|
||||
}
|
||||
#else
|
||||
static bool is_v4(const asio::detail::sockaddr_storage_type& ss)
|
||||
{
|
||||
return ss.ss_family == AF_INET;
|
||||
}
|
||||
#endif
|
||||
|
||||
// The underlying IP socket address.
|
||||
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)
|
||||
{
|
||||
return handler_(asio::error_code(
|
||||
sys_error_code, asio::native_ecat), rc);
|
||||
sys_error_code, asio::error::system_category), rc);
|
||||
}
|
||||
else
|
||||
{
|
||||
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 <queue>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
#include <typeinfo>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -56,6 +55,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "libtorrent/time.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
#ifndef TORRENT_MAX_ALERT_TYPES
|
||||
#define TORRENT_MAX_ALERT_TYPES 15
|
||||
|
|
|
@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/peer_connection.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -223,7 +224,7 @@ namespace libtorrent
|
|||
{
|
||||
block_downloading_alert(
|
||||
const torrent_handle& h
|
||||
, std::string& speedmsg
|
||||
, char const* speedmsg
|
||||
, int block_num
|
||||
, int piece_num
|
||||
, const std::string& msg)
|
||||
|
@ -261,6 +262,17 @@ namespace libtorrent
|
|||
{ return std::auto_ptr<alert>(new torrent_paused_alert(*this)); }
|
||||
};
|
||||
|
||||
struct TORRENT_EXPORT torrent_checked_alert: torrent_alert
|
||||
{
|
||||
torrent_checked_alert(torrent_handle const& h, std::string const& msg)
|
||||
: torrent_alert(h, alert::info, msg)
|
||||
{}
|
||||
|
||||
virtual std::auto_ptr<alert> clone() const
|
||||
{ return std::auto_ptr<alert>(new torrent_checked_alert(*this)); }
|
||||
};
|
||||
|
||||
|
||||
struct TORRENT_EXPORT url_seed_alert: torrent_alert
|
||||
{
|
||||
url_seed_alert(
|
||||
|
|
|
@ -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/connection_queue.hpp"
|
||||
#include "libtorrent/disk_io_thread.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -240,12 +241,12 @@ namespace libtorrent
|
|||
bool is_listening() const;
|
||||
|
||||
torrent_handle add_torrent(
|
||||
torrent_info const& ti
|
||||
boost::intrusive_ptr<torrent_info> ti
|
||||
, fs::path const& save_path
|
||||
, entry const& resume_data
|
||||
, bool compact_mode
|
||||
, int block_size
|
||||
, storage_constructor_type sc);
|
||||
, storage_constructor_type sc
|
||||
, bool paused);
|
||||
|
||||
torrent_handle add_torrent(
|
||||
char const* tracker_url
|
||||
|
@ -254,8 +255,8 @@ namespace libtorrent
|
|||
, fs::path const& save_path
|
||||
, entry const& resume_data
|
||||
, bool compact_mode
|
||||
, int block_size
|
||||
, storage_constructor_type sc);
|
||||
, storage_constructor_type sc
|
||||
, bool paused);
|
||||
|
||||
void remove_torrent(torrent_handle const& h);
|
||||
|
||||
|
@ -273,8 +274,21 @@ namespace libtorrent
|
|||
void set_max_connections(int limit);
|
||||
void set_max_uploads(int limit);
|
||||
|
||||
int num_uploads() const;
|
||||
int num_connections() const;
|
||||
int max_connections() const { return m_max_connections; }
|
||||
int max_uploads() const { return m_max_uploads; }
|
||||
int max_half_open_connections() const { return m_half_open.limit(); }
|
||||
|
||||
int num_uploads() const { return m_num_unchoked; }
|
||||
int num_connections() const
|
||||
{ return m_connections.size(); }
|
||||
|
||||
void unchoke_peer(peer_connection& c)
|
||||
{
|
||||
torrent* t = c.associated_torrent().lock().get();
|
||||
assert(t);
|
||||
if (t->unchoke_peer(c))
|
||||
++m_num_unchoked;
|
||||
}
|
||||
|
||||
session_status status() const;
|
||||
void set_peer_id(peer_id const& id);
|
||||
|
@ -417,6 +431,28 @@ namespace libtorrent
|
|||
int m_max_uploads;
|
||||
int m_max_connections;
|
||||
|
||||
// the number of unchoked peers
|
||||
int m_num_unchoked;
|
||||
|
||||
// this is initialized to the unchoke_interval
|
||||
// session_setting and decreased every second.
|
||||
// when it reaches zero, it is reset to the
|
||||
// unchoke_interval and the unchoke set is
|
||||
// recomputed.
|
||||
int m_unchoke_time_scaler;
|
||||
|
||||
// works like unchoke_time_scaler but it
|
||||
// is only decresed when the unchoke set
|
||||
// is recomputed, and when it reaches zero,
|
||||
// the optimistic unchoke is moved to another peer.
|
||||
int m_optimistic_unchoke_time_scaler;
|
||||
|
||||
// works like unchoke_time_scaler. Each time
|
||||
// it reaches 0, and all the connections are
|
||||
// used, the worst connection will be disconnected
|
||||
// from the torrent with the most peers
|
||||
int m_disconnect_time_scaler;
|
||||
|
||||
// statistics gathered from all torrents.
|
||||
stat m_stat;
|
||||
|
||||
|
@ -459,7 +495,7 @@ namespace libtorrent
|
|||
// This implements a round robin.
|
||||
int m_next_connect_torrent;
|
||||
#ifndef NDEBUG
|
||||
void check_invariant(const char *place = 0);
|
||||
void check_invariant() const;
|
||||
#endif
|
||||
|
||||
#ifdef TORRENT_STATS
|
||||
|
|
|
@ -33,9 +33,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef TORRENT_BANDWIDTH_MANAGER_HPP_INCLUDED
|
||||
#define TORRENT_BANDWIDTH_MANAGER_HPP_INCLUDED
|
||||
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/invariant_check.hpp"
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
@ -44,11 +41,17 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <boost/thread/mutex.hpp>
|
||||
#include <deque>
|
||||
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/invariant_check.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
using boost::weak_ptr;
|
||||
using boost::shared_ptr;
|
||||
using boost::intrusive_ptr;
|
||||
using boost::bind;
|
||||
|
||||
//#define TORRENT_VERBOSE_BANDWIDTH_LIMIT
|
||||
|
||||
namespace libtorrent {
|
||||
|
||||
// the maximum block of bandwidth quota to
|
||||
|
@ -237,8 +240,10 @@ struct bandwidth_manager
|
|||
i = j;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_queue.size() == 1) hand_out_bandwidth();
|
||||
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
|
||||
std::cerr << " req_bandwidht. m_queue.size() = " << m_queue.size() << std::endl;
|
||||
#endif
|
||||
if (!m_queue.empty()) hand_out_bandwidth();
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
|
@ -337,10 +342,18 @@ private:
|
|||
// available bandwidth to hand out
|
||||
int amount = limit - m_current_quota;
|
||||
|
||||
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
|
||||
std::cerr << " hand_out_bandwidht. m_queue.size() = " << m_queue.size()
|
||||
<< " amount = " << amount
|
||||
<< " limit = " << limit
|
||||
<< " m_current_quota = " << m_current_quota << std::endl;
|
||||
#endif
|
||||
|
||||
while (!m_queue.empty() && amount > 0)
|
||||
{
|
||||
assert(amount == limit - m_current_quota);
|
||||
bw_queue_entry<PeerConnection> qe = m_queue.front();
|
||||
assert(qe.max_block_size > 0);
|
||||
m_queue.pop_front();
|
||||
|
||||
shared_ptr<Torrent> t = qe.peer->associated_torrent().lock();
|
||||
|
@ -374,13 +387,12 @@ private:
|
|||
// block size must be smaller for lower rates. This is because
|
||||
// the history window is one second, and the block will be forgotten
|
||||
// after one second.
|
||||
int block_size = (std::min)(qe.max_block_size
|
||||
, (std::min)(qe.peer->bandwidth_throttle(m_channel)
|
||||
, m_limit / 10));
|
||||
int block_size = (std::min)(qe.peer->bandwidth_throttle(m_channel)
|
||||
, m_limit / 10);
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -399,7 +411,11 @@ private:
|
|||
/ (m_limit / max_bandwidth_block_size);
|
||||
}
|
||||
}
|
||||
if (block_size > qe.max_block_size) block_size = qe.max_block_size;
|
||||
|
||||
#ifdef TORRENT_VERBOSE_BANDWIDTH_LIMIT
|
||||
std::cerr << " block_size = " << block_size << " amount = " << amount << std::endl;
|
||||
#endif
|
||||
if (amount < block_size / 2)
|
||||
{
|
||||
m_queue.push_front(qe);
|
||||
|
|
|
@ -79,6 +79,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/entry.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
namespace std
|
||||
{
|
||||
|
|
|
@ -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/torrent_handle.hpp"
|
||||
#include "libtorrent/torrent.hpp"
|
||||
#include "libtorrent/allocate_resources.hpp"
|
||||
#include "libtorrent/peer_request.hpp"
|
||||
#include "libtorrent/piece_block_progress.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
|
@ -122,8 +121,16 @@ namespace libtorrent
|
|||
msg_request,
|
||||
msg_piece,
|
||||
msg_cancel,
|
||||
// DHT extension
|
||||
msg_dht_port,
|
||||
// extension protocol message
|
||||
// FAST extension
|
||||
msg_suggest_piece = 0xd,
|
||||
msg_have_all,
|
||||
msg_have_none,
|
||||
msg_reject_request,
|
||||
msg_allowed_fast,
|
||||
|
||||
// extension protocol message
|
||||
msg_extended = 20,
|
||||
|
||||
num_supported_messages
|
||||
|
@ -174,8 +181,17 @@ namespace libtorrent
|
|||
void on_request(int received);
|
||||
void on_piece(int received);
|
||||
void on_cancel(int received);
|
||||
|
||||
// DHT extension
|
||||
void on_dht_port(int received);
|
||||
|
||||
// FAST extension
|
||||
void on_suggest_piece(int received);
|
||||
void on_have_all(int received);
|
||||
void on_have_none(int received);
|
||||
void on_reject_request(int received);
|
||||
void on_allowed_fast(int received);
|
||||
|
||||
void on_extended(int received);
|
||||
|
||||
void on_extended_handshake();
|
||||
|
@ -201,7 +217,16 @@ namespace libtorrent
|
|||
void write_metadata(std::pair<int, int> req);
|
||||
void write_metadata_request(std::pair<int, int> req);
|
||||
void write_keepalive();
|
||||
|
||||
// DHT extension
|
||||
void write_dht_port(int listen_port);
|
||||
|
||||
// FAST extension
|
||||
void write_have_all();
|
||||
void write_have_none();
|
||||
void write_reject_request(peer_request const&);
|
||||
void write_allow_fast(int piece);
|
||||
|
||||
void on_connected();
|
||||
void on_metadata();
|
||||
|
||||
|
@ -325,6 +350,7 @@ namespace libtorrent
|
|||
bool m_supports_extensions;
|
||||
#endif
|
||||
bool m_supports_dht_port;
|
||||
bool m_supports_fast;
|
||||
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
// this is set to true after the encryption method has been
|
||||
|
|
|
@ -34,8 +34,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
//#define TORRENT_BUFFER_DEBUG
|
||||
|
||||
#include "libtorrent/invariant_check.hpp"
|
||||
#include <memory>
|
||||
#include "libtorrent/invariant_check.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent {
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define TORRENT_CONFIG_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__ >= 4
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <list>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/thread/recursive_mutex.hpp>
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/time.hpp"
|
||||
|
||||
|
@ -88,6 +89,10 @@ private:
|
|||
int m_half_open_limit;
|
||||
|
||||
deadline_timer m_timer;
|
||||
|
||||
typedef boost::recursive_mutex mutex_t;
|
||||
mutable mutex_t m_mutex;
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool m_in_timeout_function;
|
||||
#endif
|
||||
|
|
|
@ -80,3 +80,4 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#endif // TORRENT_DEBUG_HPP_INCLUDED
|
||||
|
||||
|
|
|
@ -64,10 +64,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <list>
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <cassert>
|
||||
|
||||
#include "libtorrent/size_type.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
{ return false; }
|
||||
|
||||
virtual bool on_have_all()
|
||||
{ return false; }
|
||||
|
||||
virtual bool on_have_none()
|
||||
{ return false; }
|
||||
|
||||
virtual bool on_allowed_fast(int index)
|
||||
{ return false; }
|
||||
|
||||
virtual bool on_request(peer_request const& req)
|
||||
{ return false; }
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <sstream>
|
||||
|
||||
#include "libtorrent/peer_id.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -91,3 +92,4 @@ namespace libtorrent
|
|||
}
|
||||
|
||||
#endif // TORRENT_FINGERPRINT_HPP_INCLUDED
|
||||
|
||||
|
|
|
@ -33,11 +33,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef TORRENT_HASHER_HPP_INCLUDED
|
||||
#define TORRENT_HASHER_HPP_INCLUDED
|
||||
|
||||
#include <cassert>
|
||||
#include <boost/cstdint.hpp>
|
||||
|
||||
#include "libtorrent/peer_id.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
#include "zlib.h"
|
||||
|
||||
#ifdef TORRENT_USE_OPENSSL
|
||||
|
|
|
@ -44,13 +44,18 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/http_tracker_connection.hpp"
|
||||
#include "libtorrent/time.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
||||
struct http_connection;
|
||||
|
||||
typedef boost::function<void(asio::error_code const&
|
||||
, http_parser const&, char const* data, int size)> http_handler;
|
||||
|
||||
typedef boost::function<void(http_connection&)> http_connect_handler;
|
||||
|
||||
// TODO: add bind interface
|
||||
|
||||
// when bottled, the last two arguments to the handler
|
||||
|
@ -58,11 +63,13 @@ typedef boost::function<void(asio::error_code const&
|
|||
struct http_connection : boost::enable_shared_from_this<http_connection>, boost::noncopyable
|
||||
{
|
||||
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_read_pos(0)
|
||||
, m_resolver(ios)
|
||||
, m_handler(handler)
|
||||
, m_connect_handler(ch)
|
||||
, m_timer(ios)
|
||||
, m_last_receive(time_now())
|
||||
, 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);
|
||||
void close();
|
||||
|
||||
tcp::socket const& socket() const { return m_sock; }
|
||||
|
||||
private:
|
||||
|
||||
void on_resolve(asio::error_code const& e
|
||||
|
@ -112,6 +121,7 @@ private:
|
|||
tcp::resolver m_resolver;
|
||||
http_parser m_parser;
|
||||
http_handler m_handler;
|
||||
http_connect_handler m_connect_handler;
|
||||
deadline_timer m_timer;
|
||||
time_duration m_timeout;
|
||||
ptime m_last_receive;
|
||||
|
|
|
@ -73,6 +73,8 @@ namespace libtorrent
|
|||
T header(char const* key) const;
|
||||
std::string const& protocol() const { return m_protocol; }
|
||||
int status_code() const { return m_status_code; }
|
||||
std::string const& method() const { return m_method; }
|
||||
std::string const& path() const { return m_path; }
|
||||
std::string message() const { return m_server_message; }
|
||||
buffer::const_interval get_body() const;
|
||||
bool header_finished() const { return m_state == read_body; }
|
||||
|
@ -85,6 +87,8 @@ namespace libtorrent
|
|||
private:
|
||||
int m_recv_pos;
|
||||
int m_status_code;
|
||||
std::string m_method;
|
||||
std::string m_path;
|
||||
std::string m_protocol;
|
||||
std::string m_server_message;
|
||||
|
||||
|
@ -176,3 +180,4 @@ namespace libtorrent
|
|||
|
||||
#endif // TORRENT_HTTP_TRACKER_CONNECTION_HPP_INCLUDED
|
||||
|
||||
|
||||
|
|
|
@ -34,14 +34,17 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define TORRENT_INTRUSIVE_PTR_BASE
|
||||
|
||||
#include <boost/detail/atomic_count.hpp>
|
||||
#include <cassert>
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
template<class T>
|
||||
struct intrusive_ptr_base
|
||||
{
|
||||
intrusive_ptr_base(const intrusive_ptr_base<T>& b)
|
||||
: m_refs(0) {}
|
||||
|
||||
friend void intrusive_ptr_add_ref(intrusive_ptr_base<T> const* s)
|
||||
{
|
||||
assert(s->m_refs >= 0);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#ifndef TORRENT_INVARIANT_ACCESS_HPP_INCLUDED
|
||||
#define TORRENT_INVARIANT_ACCESS_HPP_INCLUDED
|
||||
|
||||
#include <cassert>
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
|
|
@ -33,6 +33,9 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef TORRENT_IP_FILTER_HPP
|
||||
#define TORRENT_IP_FILTER_HPP
|
||||
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push, 1)
|
||||
#endif
|
||||
|
@ -48,8 +51,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include <set>
|
||||
#include <iostream>
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
|
|
@ -34,7 +34,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define NODE_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
|
@ -45,6 +44,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <libtorrent/io.hpp>
|
||||
#include <libtorrent/session_settings.hpp>
|
||||
#include <libtorrent/assert.hpp>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
|
|
@ -33,10 +33,10 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define NODE_ID_HPP
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include "libtorrent/peer_id.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent { namespace dht
|
||||
{
|
||||
|
|
|
@ -50,6 +50,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <libtorrent/kademlia/node_entry.hpp>
|
||||
#include <libtorrent/session_settings.hpp>
|
||||
#include <libtorrent/size_type.hpp>
|
||||
#include <libtorrent/assert.hpp>
|
||||
|
||||
namespace libtorrent { namespace dht
|
||||
{
|
||||
|
|
|
@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/peer_id.hpp"
|
||||
#include "libtorrent/broadcast_socket.hpp"
|
||||
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
@ -58,35 +59,26 @@ public:
|
|||
, peer_callback_t const& cb);
|
||||
~lsd();
|
||||
|
||||
void rebind(address const& listen_interface);
|
||||
// void rebind(address const& listen_interface);
|
||||
|
||||
void announce(sha1_hash const& ih, int listen_port);
|
||||
void close();
|
||||
|
||||
private:
|
||||
|
||||
static address_v4 lsd_multicast_address;
|
||||
static udp::endpoint lsd_multicast_endpoint;
|
||||
|
||||
void resend_announce(asio::error_code const& e, std::string msg);
|
||||
void on_announce(asio::error_code const& e
|
||||
void on_announce(udp::endpoint const& from, char* buffer
|
||||
, std::size_t bytes_transferred);
|
||||
void setup_receive();
|
||||
// void setup_receive();
|
||||
|
||||
peer_callback_t m_callback;
|
||||
|
||||
// current retry count
|
||||
int m_retry_count;
|
||||
|
||||
// used to receive responses in
|
||||
char m_receive_buffer[1024];
|
||||
|
||||
// the endpoint we received the message from
|
||||
udp::endpoint m_remote;
|
||||
|
||||
// the udp socket used to send and receive
|
||||
// multicast messages on
|
||||
datagram_socket m_socket;
|
||||
broadcast_socket m_socket;
|
||||
|
||||
// used to resend udp packets in case
|
||||
// they time out
|
||||
|
|
|
@ -35,13 +35,12 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef TORRENT_PE_CRYPTO_HPP_INCLUDED
|
||||
#define TORRENT_PE_CRYPTO_HPP_INCLUDED
|
||||
|
||||
#include <cassert>
|
||||
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/engine.h>
|
||||
#include <openssl/rc4.h>
|
||||
|
||||
#include "peer_id.hpp" // For sha1_hash
|
||||
#include "libtorrent/peer_id.hpp" // For sha1_hash
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
|
|
@ -64,7 +64,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/alert.hpp"
|
||||
#include "libtorrent/torrent_handle.hpp"
|
||||
#include "libtorrent/torrent.hpp"
|
||||
#include "libtorrent/allocate_resources.hpp"
|
||||
#include "libtorrent/peer_request.hpp"
|
||||
#include "libtorrent/piece_block_progress.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
|
@ -73,6 +72,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/policy.hpp"
|
||||
#include "libtorrent/socket_type.hpp"
|
||||
#include "libtorrent/intrusive_ptr_base.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -131,6 +131,8 @@ namespace libtorrent
|
|||
enum peer_speed_t { slow, medium, fast };
|
||||
peer_speed_t peer_speed();
|
||||
|
||||
void send_allowed_set();
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
void add_extension(boost::shared_ptr<peer_plugin>);
|
||||
#endif
|
||||
|
@ -151,11 +153,17 @@ namespace libtorrent
|
|||
int upload_limit() const { return m_upload_limit; }
|
||||
int download_limit() const { return m_download_limit; }
|
||||
|
||||
bool prefer_whole_pieces() const
|
||||
{ return m_prefer_whole_pieces; }
|
||||
int prefer_whole_pieces() const
|
||||
{
|
||||
if (on_parole()) return 1;
|
||||
return m_prefer_whole_pieces;
|
||||
}
|
||||
|
||||
void prefer_whole_pieces(bool b)
|
||||
{ m_prefer_whole_pieces = b; }
|
||||
bool on_parole() const
|
||||
{ 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
|
||||
{ return m_request_large_blocks; }
|
||||
|
@ -186,9 +194,9 @@ namespace libtorrent
|
|||
void set_pid(const peer_id& pid) { m_peer_id = pid; }
|
||||
bool has_piece(int i) const;
|
||||
|
||||
const std::deque<piece_block>& download_queue() const;
|
||||
const std::deque<piece_block>& request_queue() const;
|
||||
const std::deque<peer_request>& upload_queue() const;
|
||||
std::deque<piece_block> const& download_queue() const;
|
||||
std::deque<piece_block> const& request_queue() const;
|
||||
std::deque<peer_request> const& upload_queue() const;
|
||||
|
||||
bool is_interesting() const { return m_interesting; }
|
||||
bool is_choked() const { return m_choked; }
|
||||
|
@ -211,12 +219,14 @@ namespace libtorrent
|
|||
void add_stat(size_type downloaded, size_type uploaded);
|
||||
|
||||
// is called once every second by the main loop
|
||||
void second_tick(float tick_interval);
|
||||
void second_tick(float tick_interval) throw();
|
||||
|
||||
boost::shared_ptr<socket_type> get_socket() const { return m_socket; }
|
||||
tcp::endpoint const& remote() const { return m_remote; }
|
||||
|
||||
std::vector<bool> const& get_bitfield() const;
|
||||
std::vector<int> const& allowed_fast();
|
||||
std::vector<int> const& suggested_pieces() const { return m_suggested_pieces; }
|
||||
|
||||
void timed_out();
|
||||
// this will cause this peer_connection to be disconnected.
|
||||
|
@ -294,7 +304,14 @@ namespace libtorrent
|
|||
void incoming_piece(peer_request const& p, char const* data);
|
||||
void incoming_piece_fragment();
|
||||
void incoming_cancel(peer_request const& r);
|
||||
|
||||
void incoming_dht_port(int listen_port);
|
||||
|
||||
void incoming_reject_request(peer_request const& r);
|
||||
void incoming_have_all();
|
||||
void incoming_have_none();
|
||||
void incoming_allowed_fast(int index);
|
||||
void incoming_suggest(int index);
|
||||
|
||||
// the following functions appends messages
|
||||
// to the send buffer
|
||||
|
@ -373,6 +390,9 @@ namespace libtorrent
|
|||
virtual void write_keepalive() = 0;
|
||||
virtual void write_piece(peer_request const& r, char const* buffer) = 0;
|
||||
|
||||
virtual void write_reject_request(peer_request const& r) = 0;
|
||||
virtual void write_allow_fast(int piece) = 0;
|
||||
|
||||
virtual void on_connected() = 0;
|
||||
virtual void on_tick() {}
|
||||
|
||||
|
@ -482,6 +502,11 @@ namespace libtorrent
|
|||
// the time we sent a request to
|
||||
// this peer the last time
|
||||
ptime m_last_request;
|
||||
// the time we received the last
|
||||
// piece request from the peer
|
||||
ptime m_last_incoming_request;
|
||||
// the time when we unchoked this peer
|
||||
ptime m_last_unchoke;
|
||||
|
||||
int m_packet_size;
|
||||
int m_recv_pos;
|
||||
|
@ -529,7 +554,7 @@ namespace libtorrent
|
|||
// set to the torrent it belongs to.
|
||||
boost::weak_ptr<torrent> m_torrent;
|
||||
// is true if it was we that connected to the peer
|
||||
// and false if we got an incomming connection
|
||||
// and false if we got an incoming connection
|
||||
// could be considered: true = local, false = remote
|
||||
bool m_active;
|
||||
|
||||
|
@ -563,6 +588,10 @@ namespace libtorrent
|
|||
|
||||
// the pieces the other end have
|
||||
std::vector<bool> m_have_piece;
|
||||
// this is set to true when a have_all
|
||||
// message is received. This information
|
||||
// is used to fill the bitmask in init()
|
||||
bool m_have_all;
|
||||
|
||||
// the number of pieces this peer
|
||||
// has. Must be the same as
|
||||
|
@ -575,7 +604,7 @@ namespace libtorrent
|
|||
std::deque<peer_request> m_requests;
|
||||
|
||||
// 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;
|
||||
|
||||
// the queue of blocks we have requested
|
||||
|
@ -643,12 +672,13 @@ namespace libtorrent
|
|||
bool m_writing;
|
||||
bool m_reading;
|
||||
|
||||
// if set to true, this peer will always prefer
|
||||
// to request entire pieces, rather than blocks.
|
||||
// if it is false, the download rate limit setting
|
||||
// if set to non-zero, this peer will always prefer
|
||||
// to request entire n pieces, rather than blocks.
|
||||
// where n is the value of this variable.
|
||||
// if it is 0, the download rate limit setting
|
||||
// will be used to determine if whole pieces
|
||||
// are preferred.
|
||||
bool m_prefer_whole_pieces;
|
||||
int m_prefer_whole_pieces;
|
||||
|
||||
// if this is true, the blocks picked by the piece
|
||||
// picker will be merged before passed to the
|
||||
|
@ -695,6 +725,18 @@ namespace libtorrent
|
|||
// was last updated
|
||||
ptime m_remote_dl_update;
|
||||
|
||||
// the pieces we will send to the peer
|
||||
// if requested (regardless of choke state)
|
||||
std::set<int> m_accept_fast;
|
||||
|
||||
// the pieces the peer will send us if
|
||||
// requested (regardless of choke state)
|
||||
std::vector<int> m_allowed_fast;
|
||||
|
||||
// pieces that has been suggested to be
|
||||
// downloaded from this peer
|
||||
std::vector<int> m_suggested_pieces;
|
||||
|
||||
// the number of bytes send to the disk-io
|
||||
// thread that hasn't yet been completely written.
|
||||
int m_outstanding_writing_bytes;
|
||||
|
|
|
@ -35,12 +35,12 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cassert>
|
||||
#include <cctype>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
|
|
@ -56,10 +56,11 @@ namespace libtorrent
|
|||
connecting = 0x80,
|
||||
queued = 0x100,
|
||||
on_parole = 0x200,
|
||||
seed = 0x400
|
||||
seed = 0x400,
|
||||
optimistic_unchoke = 0x800
|
||||
#ifndef TORRENT_DISABLE_ENCRYPTION
|
||||
, rc4_encrypted = 0x800,
|
||||
plaintext_encrypted = 0x1000
|
||||
, rc4_encrypted = 0x100000,
|
||||
plaintext_encrypted = 0x200000
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -116,6 +117,11 @@ namespace libtorrent
|
|||
// for yet
|
||||
int download_queue_length;
|
||||
|
||||
// the number of requests that is
|
||||
// tried to be maintained (this is
|
||||
// typically a function of download speed)
|
||||
int target_dl_queue_length;
|
||||
|
||||
// this is the number of requests
|
||||
// the peer has sent to us
|
||||
// that we haven't sent yet
|
||||
|
|
|
@ -35,7 +35,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <bitset>
|
||||
#include <cassert>
|
||||
#include <utility>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -52,6 +51,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/session_settings.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -191,11 +191,33 @@ namespace libtorrent
|
|||
// THIS IS DONE BY THE peer_connection::send_request() MEMBER FUNCTION!
|
||||
// The last argument is the policy::peer pointer for the peer that
|
||||
// we'll download from.
|
||||
void pick_pieces(const std::vector<bool>& pieces
|
||||
void pick_pieces(std::vector<bool> const& pieces
|
||||
, 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
|
||||
, 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
|
||||
// peer pointer
|
||||
|
@ -253,6 +275,8 @@ namespace libtorrent
|
|||
#ifndef NDEBUG
|
||||
// used in debug mode
|
||||
void check_invariant(const torrent* t = 0) const;
|
||||
void verify_pick(std::vector<piece_block> const& picked
|
||||
, std::vector<bool> const& bitfield) const;
|
||||
#endif
|
||||
|
||||
// functor that compares indices on downloading_pieces
|
||||
|
@ -271,6 +295,10 @@ namespace libtorrent
|
|||
|
||||
private:
|
||||
|
||||
bool can_pick(int piece, std::vector<bool> const& bitmask) const;
|
||||
std::pair<int, int> expand_piece(int piece, int whole_pieces
|
||||
, std::vector<bool> const& have) const;
|
||||
|
||||
struct piece_pos
|
||||
{
|
||||
piece_pos() {}
|
||||
|
@ -320,9 +348,9 @@ namespace libtorrent
|
|||
|
||||
int priority(int limit) const
|
||||
{
|
||||
if (filtered() || have()) return 0;
|
||||
if (downloading || filtered() || have()) return 0;
|
||||
// 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 (prio <= 1) return prio;
|
||||
if (prio >= limit * 2) prio = limit * 2;
|
||||
|
@ -358,14 +386,6 @@ namespace libtorrent
|
|||
void move(int vec_index, int elem_index);
|
||||
void sort_piece(std::vector<downloading_piece>::iterator dp);
|
||||
|
||||
int add_interesting_blocks(const std::vector<int>& piece_list
|
||||
, const std::vector<bool>& pieces
|
||||
, std::vector<piece_block>& interesting_blocks
|
||||
, std::vector<piece_block>& backup_blocks
|
||||
, int num_blocks, bool prefer_whole_pieces
|
||||
, void* peer, piece_state_t speed
|
||||
, bool ignore_downloading_pieces) const;
|
||||
|
||||
downloading_piece& add_download_piece();
|
||||
void erase_download_piece(std::vector<downloading_piece>::iterator i);
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ namespace libtorrent
|
|||
void new_connection(peer_connection& c);
|
||||
|
||||
// the given connection was just closed
|
||||
void connection_closed(const peer_connection& c);
|
||||
void connection_closed(const peer_connection& c) throw();
|
||||
|
||||
// the peer has got at least one interesting piece
|
||||
void peer_is_interesting(peer_connection& c);
|
||||
|
@ -155,6 +155,13 @@ namespace libtorrent
|
|||
// this is true if the peer is a seed
|
||||
bool seed;
|
||||
|
||||
// true if this peer currently is unchoked
|
||||
// because of an optimistic unchoke.
|
||||
// when the optimistic unchoke is moved to
|
||||
// another peer, this peer will be choked
|
||||
// if this is true
|
||||
bool optimistically_unchoked;
|
||||
|
||||
// the time when this peer was optimistically unchoked
|
||||
// the last time.
|
||||
libtorrent::ptime last_optimistically_unchoked;
|
||||
|
@ -203,25 +210,18 @@ namespace libtorrent
|
|||
peer_connection* connection;
|
||||
};
|
||||
|
||||
int num_peers() const
|
||||
{
|
||||
return m_peers.size();
|
||||
}
|
||||
int num_peers() const { return m_peers.size(); }
|
||||
|
||||
int num_uploads() const
|
||||
{
|
||||
return m_num_unchoked;
|
||||
}
|
||||
|
||||
typedef std::list<peer>::iterator iterator;
|
||||
typedef std::list<peer>::const_iterator const_iterator;
|
||||
iterator begin_peer() { return m_peers.begin(); }
|
||||
iterator end_peer() { return m_peers.end(); }
|
||||
|
||||
bool connect_one_peer();
|
||||
bool disconnect_one_peer();
|
||||
|
||||
private:
|
||||
|
||||
/*
|
||||
bool unchoke_one_peer();
|
||||
void choke_one_peer();
|
||||
iterator find_choke_candidate();
|
||||
|
@ -233,8 +233,7 @@ namespace libtorrent
|
|||
void seed_choke_one_peer();
|
||||
iterator find_seed_choke_candidate();
|
||||
iterator find_seed_unchoke_candidate();
|
||||
|
||||
bool disconnect_one_peer();
|
||||
*/
|
||||
iterator find_disconnect_candidate();
|
||||
iterator find_connect_candidate();
|
||||
|
||||
|
@ -242,10 +241,6 @@ namespace libtorrent
|
|||
|
||||
torrent* m_torrent;
|
||||
|
||||
// the number of unchoked peers
|
||||
// at any given time
|
||||
int m_num_unchoked;
|
||||
|
||||
// free download we have got that hasn't
|
||||
// been distributed yet.
|
||||
size_type m_available_free_upload;
|
||||
|
@ -253,7 +248,7 @@ namespace libtorrent
|
|||
// if there is a connection limit,
|
||||
// we disconnect one peer every minute in hope of
|
||||
// establishing a connection with a better peer
|
||||
ptime m_last_optimistic_disconnect;
|
||||
// ptime m_last_optimistic_disconnect;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/torrent_handle.hpp"
|
||||
#include "libtorrent/entry.hpp"
|
||||
#include "libtorrent/alert.hpp"
|
||||
|
@ -60,7 +61,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/version.hpp"
|
||||
#include "libtorrent/fingerprint.hpp"
|
||||
|
||||
#include "libtorrent/resource_request.hpp"
|
||||
#include "libtorrent/storage.hpp"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -141,22 +141,16 @@ namespace libtorrent
|
|||
, fs::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true
|
||||
, int block_size = 16 * 1024
|
||||
, storage_constructor_type sc = default_storage_constructor);
|
||||
, bool paused = false
|
||||
, 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(
|
||||
entry const& e
|
||||
boost::intrusive_ptr<torrent_info> ti
|
||||
, fs::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true
|
||||
, int block_size = 16 * 1024
|
||||
, storage_constructor_type sc = default_storage_constructor) TORRENT_DEPRECATED
|
||||
{
|
||||
return add_torrent(torrent_info(e), save_path, resume_data
|
||||
, compact_mode, block_size, sc);
|
||||
}
|
||||
, bool paused = false
|
||||
, storage_constructor_type sc = default_storage_constructor);
|
||||
|
||||
torrent_handle add_torrent(
|
||||
char const* tracker_url
|
||||
|
@ -165,7 +159,7 @@ namespace libtorrent
|
|||
, fs::path const& save_path
|
||||
, entry const& resume_data = entry()
|
||||
, bool compact_mode = true
|
||||
, int block_size = 16 * 1024
|
||||
, bool paused = false
|
||||
, storage_constructor_type sc = default_storage_constructor);
|
||||
|
||||
session_proxy abort() { return session_proxy(m_impl); }
|
||||
|
@ -243,6 +237,7 @@ namespace libtorrent
|
|||
|
||||
int upload_rate_limit() const;
|
||||
int download_rate_limit() const;
|
||||
int max_half_open_connections() const;
|
||||
|
||||
void set_upload_rate_limit(int bytes_per_second);
|
||||
void set_download_rate_limit(int bytes_per_second);
|
||||
|
@ -265,12 +260,6 @@ namespace libtorrent
|
|||
void stop_natpmp();
|
||||
void stop_upnp();
|
||||
|
||||
// Resource management used for global limits.
|
||||
resource_request m_ul_bandwidth_quota;
|
||||
resource_request m_dl_bandwidth_quota;
|
||||
resource_request m_uploads_quota;
|
||||
resource_request m_connections_quota;
|
||||
|
||||
private:
|
||||
|
||||
// just a way to initialize boost.filesystem
|
||||
|
|
|
@ -105,9 +105,11 @@ namespace libtorrent
|
|||
, send_redundant_have(false)
|
||||
, lazy_bitfields(true)
|
||||
, inactivity_timeout(600)
|
||||
, unchoke_interval(20)
|
||||
, unchoke_interval(15)
|
||||
, optimistic_unchoke_multiplier(4)
|
||||
, num_want(200)
|
||||
, initial_picker_threshold(4)
|
||||
, allowed_fast_set_size(10)
|
||||
, max_outstanding_disk_bytes_per_connection(64 * 1024)
|
||||
#ifndef TORRENT_DISABLE_DHT
|
||||
, use_dht_as_fallback(true)
|
||||
|
@ -241,6 +243,10 @@ namespace libtorrent
|
|||
// the number of seconds between chokes/unchokes
|
||||
int unchoke_interval;
|
||||
|
||||
// the number of unchoke intervals between
|
||||
// optimistic unchokes
|
||||
int optimistic_unchoke_multiplier;
|
||||
|
||||
// if this is set, this IP will be reported do the
|
||||
// tracker in the ip= parameter.
|
||||
address announce_ip;
|
||||
|
@ -252,6 +258,10 @@ namespace libtorrent
|
|||
// random pieces instead of rarest first.
|
||||
int initial_picker_threshold;
|
||||
|
||||
// the number of allowed pieces to send to peers
|
||||
// that supports the fast extensions
|
||||
int allowed_fast_set_size;
|
||||
|
||||
// the maximum number of bytes a connection may have
|
||||
// pending in the disk write queue before its download
|
||||
// rate is being throttled. This prevents fast downloads
|
||||
|
|
|
@ -40,6 +40,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/size_type.hpp"
|
||||
#include "libtorrent/invariant_check.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
|
|
@ -43,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <boost/limits.hpp>
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/intrusive_ptr.hpp>
|
||||
#include <boost/filesystem/path.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
@ -147,10 +148,11 @@ namespace libtorrent
|
|||
};
|
||||
|
||||
typedef storage_interface* (&storage_constructor_type)(
|
||||
torrent_info const&, fs::path const&
|
||||
boost::intrusive_ptr<torrent_info const>, fs::path const&
|
||||
, 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);
|
||||
|
||||
// returns true if the filesystem the path relies on supports
|
||||
|
@ -169,7 +171,7 @@ namespace libtorrent
|
|||
|
||||
piece_manager(
|
||||
boost::shared_ptr<void> const& torrent
|
||||
, torrent_info const& ti
|
||||
, boost::intrusive_ptr<torrent_info const> ti
|
||||
, fs::path const& path
|
||||
, file_pool& fp
|
||||
, disk_io_thread& io
|
||||
|
@ -199,7 +201,8 @@ namespace libtorrent
|
|||
|
||||
void async_read(
|
||||
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(
|
||||
peer_request const& r
|
||||
|
@ -227,7 +230,7 @@ namespace libtorrent
|
|||
{ return m_compact_mode; }
|
||||
|
||||
#ifndef NDEBUG
|
||||
std::string name() const { return m_info.name(); }
|
||||
std::string name() const { return m_info->name(); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
@ -283,7 +286,7 @@ namespace libtorrent
|
|||
// a bitmask representing the pieces we have
|
||||
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
|
||||
std::vector<int> m_unallocated_slots;
|
||||
|
@ -313,12 +316,6 @@ namespace libtorrent
|
|||
|
||||
mutable boost::recursive_mutex m_mutex;
|
||||
|
||||
bool m_allocating;
|
||||
boost::mutex m_allocating_monitor;
|
||||
boost::condition m_allocating_condition;
|
||||
|
||||
// these states are used while checking/allocating the torrent
|
||||
|
||||
enum {
|
||||
// the default initial state
|
||||
state_none,
|
||||
|
@ -333,6 +330,11 @@ namespace libtorrent
|
|||
} m_state;
|
||||
int m_current_slot;
|
||||
|
||||
// this is saved in case we need to instantiate a new
|
||||
// storage (osed when remapping files)
|
||||
storage_constructor_type m_storage_constructor;
|
||||
|
||||
// temporary buffer used while checking
|
||||
std::vector<char> m_piece_data;
|
||||
|
||||
// this maps a piece hash to piece index. It will be
|
||||
|
@ -340,6 +342,8 @@ namespace libtorrent
|
|||
// isn't needed)
|
||||
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;
|
||||
|
||||
disk_io_thread& m_io_thread;
|
||||
|
|
|
@ -55,6 +55,7 @@ namespace libtorrent
|
|||
|| _POSIX_MONOTONIC_CLOCK < 0)) || defined (TORRENT_USE_BOOST_DATE_TIME)
|
||||
|
||||
#include <boost/date_time/posix_time/posix_time_types.hpp>
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -85,6 +86,7 @@ namespace libtorrent
|
|||
|
||||
#include <asio/time_traits.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -170,6 +172,7 @@ namespace asio
|
|||
|
||||
#include <mach/mach_time.h>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
// high precision timer for darwin intel and ppc
|
||||
|
||||
|
@ -249,6 +252,7 @@ namespace libtorrent
|
|||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <Windows.h>
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -335,6 +339,7 @@ namespace libtorrent
|
|||
#elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
|
||||
|
||||
#include <time.h>
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -385,4 +390,4 @@ namespace libtorrent
|
|||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -62,13 +62,13 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/tracker_manager.hpp"
|
||||
#include "libtorrent/stat.hpp"
|
||||
#include "libtorrent/alert.hpp"
|
||||
#include "libtorrent/resource_request.hpp"
|
||||
#include "libtorrent/piece_picker.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/escape_string.hpp"
|
||||
#include "libtorrent/bandwidth_manager.hpp"
|
||||
#include "libtorrent/storage.hpp"
|
||||
#include "libtorrent/hasher.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -98,13 +98,13 @@ namespace libtorrent
|
|||
torrent(
|
||||
aux::session_impl& ses
|
||||
, aux::checker_impl& checker
|
||||
, torrent_info const& tf
|
||||
, boost::intrusive_ptr<torrent_info> tf
|
||||
, fs::path const& save_path
|
||||
, tcp::endpoint const& net_interface
|
||||
, bool compact_mode
|
||||
, int block_size
|
||||
, session_settings const& s
|
||||
, storage_constructor_type sc);
|
||||
, storage_constructor_type sc
|
||||
, bool paused);
|
||||
|
||||
// used with metadata-less torrents
|
||||
// (the metadata is downloaded from the peers)
|
||||
|
@ -118,8 +118,8 @@ namespace libtorrent
|
|||
, tcp::endpoint const& net_interface
|
||||
, bool compact_mode
|
||||
, int block_size
|
||||
, session_settings const& s
|
||||
, storage_constructor_type sc);
|
||||
, storage_constructor_type sc
|
||||
, bool paused);
|
||||
|
||||
~torrent();
|
||||
|
||||
|
@ -154,10 +154,6 @@ namespace libtorrent
|
|||
bool verify_resume_data(entry& rd, std::string& error)
|
||||
{ assert(m_storage); return m_storage->verify_resume_data(rd, error); }
|
||||
|
||||
// is called every second by session. This will
|
||||
// caclulate the upload/download and number
|
||||
// of connections this torrent needs. And prepare
|
||||
// it for being used by allocate_resources.
|
||||
void second_tick(stat& accumulator, float tick_interval);
|
||||
|
||||
// debug purpose only
|
||||
|
@ -254,6 +250,15 @@ namespace libtorrent
|
|||
void remove_url_seed(std::string const& url)
|
||||
{ m_web_seeds.erase(url); }
|
||||
|
||||
std::set<std::string> url_seeds() const
|
||||
{ return m_web_seeds; }
|
||||
|
||||
bool free_upload_slots() const
|
||||
{ return m_num_uploads < m_max_uploads; }
|
||||
|
||||
void choke_peer(peer_connection& c);
|
||||
bool unchoke_peer(peer_connection& c);
|
||||
|
||||
// used by peer_connection to attach itself to a torrent
|
||||
// since incoming connections don't know what torrent
|
||||
// they're a part of until they have received an info_hash.
|
||||
|
@ -465,14 +470,14 @@ namespace libtorrent
|
|||
bool is_seed() const
|
||||
{
|
||||
return valid_metadata()
|
||||
&& m_num_pieces == m_torrent_file.num_pieces();
|
||||
&& m_num_pieces == m_torrent_file->num_pieces();
|
||||
}
|
||||
|
||||
// this is true if we have all the pieces that we want
|
||||
bool is_finished() const
|
||||
{
|
||||
if (is_seed()) return true;
|
||||
return valid_metadata() && m_torrent_file.num_pieces()
|
||||
return valid_metadata() && m_torrent_file->num_pieces()
|
||||
- m_num_pieces - m_picker->num_filtered() == 0;
|
||||
}
|
||||
|
||||
|
@ -494,7 +499,7 @@ namespace libtorrent
|
|||
}
|
||||
piece_manager& filesystem();
|
||||
torrent_info const& torrent_file() const
|
||||
{ return m_torrent_file; }
|
||||
{ return *m_torrent_file; }
|
||||
|
||||
std::vector<announce_entry> const& trackers() const
|
||||
{ return m_trackers; }
|
||||
|
@ -516,11 +521,6 @@ namespace libtorrent
|
|||
// --------------------------------------------
|
||||
// RESOURCE MANAGEMENT
|
||||
|
||||
void distribute_resources(float tick_interval);
|
||||
|
||||
resource_request m_uploads_quota;
|
||||
resource_request m_connections_quota;
|
||||
|
||||
void set_peer_upload_limit(tcp::endpoint ip, int limit);
|
||||
void set_peer_download_limit(tcp::endpoint ip, int limit);
|
||||
|
||||
|
@ -530,7 +530,9 @@ namespace libtorrent
|
|||
int download_limit() const;
|
||||
|
||||
void set_max_uploads(int limit);
|
||||
int max_uploads() const { return m_max_uploads; }
|
||||
void set_max_connections(int limit);
|
||||
int max_connections() const { return m_max_connections; }
|
||||
void move_storage(fs::path const& save_path);
|
||||
|
||||
// unless this returns true, new connections must wait
|
||||
|
@ -538,7 +540,7 @@ namespace libtorrent
|
|||
bool ready_for_connections() const
|
||||
{ return m_connections_initialized; }
|
||||
bool valid_metadata() const
|
||||
{ return m_torrent_file.is_valid(); }
|
||||
{ return m_torrent_file->is_valid(); }
|
||||
|
||||
// parses the info section from the given
|
||||
// bencoded tree and moves the torrent
|
||||
|
@ -562,7 +564,7 @@ namespace libtorrent
|
|||
|
||||
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
|
||||
// been aborted.
|
||||
|
@ -705,9 +707,9 @@ namespace libtorrent
|
|||
// determine the timeout until next try.
|
||||
int m_failed_trackers;
|
||||
|
||||
// this is a counter that is increased every
|
||||
// second, and when it reaches 10, the policy::pulse()
|
||||
// is called and the time scaler is reset to 0.
|
||||
// this is a counter that is decreased every
|
||||
// second, and when it reaches 0, the policy::pulse()
|
||||
// is called and the time scaler is reset to 10.
|
||||
int m_time_scaler;
|
||||
|
||||
// the bitmask that says which pieces we have
|
||||
|
@ -774,6 +776,15 @@ namespace libtorrent
|
|||
session_settings const& m_settings;
|
||||
|
||||
storage_constructor_type m_storage_constructor;
|
||||
|
||||
// the maximum number of uploads for this torrent
|
||||
int m_max_uploads;
|
||||
|
||||
// the number of unchoked peers in this torrent
|
||||
int m_num_uploads;
|
||||
|
||||
// the maximum number of connections for this torrent
|
||||
int m_max_connections;
|
||||
|
||||
#ifndef TORRENT_DISABLE_EXTENSIONS
|
||||
typedef std::list<boost::shared_ptr<torrent_plugin> > extension_list_t;
|
||||
|
|
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define TORRENT_TORRENT_HANDLE_HPP_INCLUDED
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push, 1)
|
||||
|
@ -273,7 +274,9 @@ namespace libtorrent
|
|||
std::vector<announce_entry> const& trackers() const;
|
||||
void replace_trackers(std::vector<announce_entry> const&) const;
|
||||
|
||||
void add_url_seed(std::string const& url);
|
||||
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;
|
||||
const torrent_info& get_torrent_info() const;
|
||||
|
|
|
@ -57,6 +57,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include "libtorrent/peer_request.hpp"
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/time.hpp"
|
||||
#include "libtorrent/intrusive_ptr_base.hpp"
|
||||
#include "libtorrent/assert.hpp"
|
||||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
@ -71,7 +73,7 @@ namespace libtorrent
|
|||
size_type offset; // the offset of this file inside the torrent
|
||||
size_type size; // the size of this file
|
||||
// if the path was incorrectly encoded, this is
|
||||
// the origianal corrupt encoded string. It is
|
||||
// the original corrupt encoded string. It is
|
||||
// preserved in order to be able to reproduce
|
||||
// the correct info-hash
|
||||
boost::shared_ptr<const fs::path> orig_path;
|
||||
|
@ -96,7 +98,7 @@ namespace libtorrent
|
|||
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:
|
||||
|
||||
|
@ -115,8 +117,12 @@ namespace libtorrent
|
|||
void add_file(fs::path file, size_type size);
|
||||
void add_url_seed(std::string const& url);
|
||||
|
||||
std::vector<file_slice> map_block(int piece, size_type offset, int size) const;
|
||||
peer_request map_file(int file, size_type offset, int size) const;
|
||||
bool remap_files(std::vector<std::pair<std::string, libtorrent::size_type> > const& map);
|
||||
|
||||
std::vector<file_slice> map_block(int piece, size_type offset
|
||||
, int size, bool storage = false) const;
|
||||
peer_request map_file(int file, size_type offset, int size
|
||||
, bool storage = false) const;
|
||||
|
||||
std::vector<std::string> const& url_seeds() const
|
||||
{
|
||||
|
@ -128,15 +134,60 @@ namespace libtorrent
|
|||
typedef std::vector<file_entry>::const_reverse_iterator reverse_file_iterator;
|
||||
|
||||
// list the files in the torrent file
|
||||
file_iterator begin_files() const { return m_files.begin(); }
|
||||
file_iterator end_files() const { return m_files.end(); }
|
||||
reverse_file_iterator rbegin_files() const { return m_files.rbegin(); }
|
||||
reverse_file_iterator rend_files() const { return m_files.rend(); }
|
||||
file_iterator begin_files(bool storage = false) const
|
||||
{
|
||||
if (!storage || m_remapped_files.empty())
|
||||
return m_files.begin();
|
||||
else
|
||||
return m_remapped_files.begin();
|
||||
}
|
||||
|
||||
int num_files() const
|
||||
{ assert(m_piece_length > 0); return (int)m_files.size(); }
|
||||
const file_entry& file_at(int index) const
|
||||
{ assert(index >= 0 && index < (int)m_files.size()); return m_files[index]; }
|
||||
file_iterator end_files(bool storage = false) const
|
||||
{
|
||||
if (!storage || m_remapped_files.empty())
|
||||
return m_files.end();
|
||||
else
|
||||
return m_remapped_files.end();
|
||||
}
|
||||
|
||||
reverse_file_iterator rbegin_files(bool storage = false) const
|
||||
{
|
||||
if (!storage || m_remapped_files.empty())
|
||||
return m_files.rbegin();
|
||||
else
|
||||
return m_remapped_files.rbegin();
|
||||
}
|
||||
|
||||
reverse_file_iterator rend_files(bool storage = false) const
|
||||
{
|
||||
if (!storage || m_remapped_files.empty())
|
||||
return m_files.rend();
|
||||
else
|
||||
return m_remapped_files.rend();
|
||||
}
|
||||
|
||||
int num_files(bool storage = false) const
|
||||
{
|
||||
assert(m_piece_length > 0);
|
||||
if (!storage || m_remapped_files.empty())
|
||||
return (int)m_files.size();
|
||||
else
|
||||
return (int)m_remapped_files.size();
|
||||
}
|
||||
|
||||
const file_entry& file_at(int index, bool storage = false) const
|
||||
{
|
||||
if (!storage || m_remapped_files.empty())
|
||||
{
|
||||
assert(index >= 0 && index < (int)m_files.size());
|
||||
return m_files[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(index >= 0 && index < (int)m_remapped_files.size());
|
||||
return m_remapped_files[index];
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
std::vector<file_entry> m_files;
|
||||
|
||||
// this vector is typically empty. If it is not
|
||||
// empty, it means the user has re-mapped the
|
||||
// files in this torrent to diffefrent names
|
||||
// on disk. This is only used when reading and
|
||||
// writing the disk.
|
||||
std::vector<file_entry> m_remapped_files;
|
||||
|
||||
nodes_t m_nodes;
|
||||
|
||||
// the sum of all filesizes
|
||||
|
@ -264,8 +322,10 @@ namespace libtorrent
|
|||
entry m_extra_info;
|
||||
|
||||
#ifndef NDEBUG
|
||||
public:
|
||||
// this is set to true when seed_free() is called
|
||||
bool m_half_metadata;
|
||||
private:
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#define TORRENT_UPNP_HPP
|
||||
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/broadcast_socket.hpp"
|
||||
#include "libtorrent/http_connection.hpp"
|
||||
#include "libtorrent/connection_queue.hpp"
|
||||
|
||||
|
@ -56,9 +57,6 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
namespace libtorrent
|
||||
{
|
||||
|
||||
bool is_local(address const& a);
|
||||
address_v4 guess_local_address(asio::io_service&);
|
||||
|
||||
// int: external tcp port
|
||||
// int: external udp port
|
||||
// std::string: error message
|
||||
|
@ -72,8 +70,6 @@ public:
|
|||
, portmap_callback_t const& cb);
|
||||
~upnp();
|
||||
|
||||
void rebind(address const& listen_interface);
|
||||
|
||||
// maps the ports, if a port is set to 0
|
||||
// it will not be mapped
|
||||
void set_mappings(int tcp, int udp);
|
||||
|
@ -90,7 +86,7 @@ private:
|
|||
|
||||
void update_mapping(int i, int port);
|
||||
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);
|
||||
void discover_device();
|
||||
|
||||
|
@ -106,12 +102,15 @@ private:
|
|||
, int mapping);
|
||||
void on_expire(asio::error_code const& e);
|
||||
|
||||
void post(rootdevice& d, std::stringstream const& s
|
||||
, std::string const& soap_action);
|
||||
void map_port(rootdevice& d, int i);
|
||||
void unmap_port(rootdevice& d, int i);
|
||||
void disable();
|
||||
|
||||
void delete_port_mapping(rootdevice& d, int i);
|
||||
void create_port_mapping(http_connection& c, rootdevice& d, int i);
|
||||
void post(upnp::rootdevice const& d, std::string const& soap
|
||||
, std::string const& soap_action);
|
||||
|
||||
struct mapping_t
|
||||
{
|
||||
mapping_t()
|
||||
|
@ -198,18 +197,13 @@ private:
|
|||
// current retry count
|
||||
int m_retry_count;
|
||||
|
||||
// used to receive responses in
|
||||
char m_receive_buffer[1024];
|
||||
asio::io_service& m_io_service;
|
||||
|
||||
// the endpoint we received the message from
|
||||
udp::endpoint m_remote;
|
||||
asio::strand m_strand;
|
||||
|
||||
// the local address we're listening on
|
||||
address_v4 m_local_ip;
|
||||
|
||||
// the udp socket used to send and receive
|
||||
// multicast messages on the network
|
||||
datagram_socket m_socket;
|
||||
broadcast_socket m_socket;
|
||||
|
||||
// used to resend udp packets in case
|
||||
// they time out
|
||||
|
@ -217,8 +211,6 @@ private:
|
|||
|
||||
// timer used to refresh mappings
|
||||
deadline_timer m_refresh_timer;
|
||||
|
||||
asio::strand m_strand;
|
||||
|
||||
bool m_disabled;
|
||||
bool m_closing;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue