forked from premiere/premiere-libtorrent
fixed race condition in peer_connection, fixed assert in torrent destructor, updated tests
This commit is contained in:
parent
58698d6aea
commit
94628fa78d
6
Jamfile
6
Jamfile
|
@ -30,9 +30,9 @@ project torrent
|
|||
<define>BOOST_ALL_NO_LIB
|
||||
<define>_FILE_OFFSET_BITS=64
|
||||
<define>BOOST_THREAD_USE_LIB
|
||||
<library>/boost/thread//boost_thread/<link>static
|
||||
<library>/boost/filesystem//boost_filesystem/<link>static
|
||||
<library>/boost/date_time//boost_date_time/<link>static
|
||||
<library>/boost/thread//boost_thread #/<link>static
|
||||
<library>/boost/filesystem//boost_filesystem #/<link>static
|
||||
<library>/boost/date_time//boost_date_time #/<link>static
|
||||
<threading>multi
|
||||
<toolset>msvc:<define>_WIN32_WINNT=0x0500
|
||||
# WIN32 makes sure the win32 socket api is used
|
||||
|
|
16
Makefile.am
16
Makefile.am
|
@ -4,7 +4,21 @@ docs/extension_protocol.html docs/udp_tracker_protocol.rst \
|
|||
docs/udp_tracker_protocol.html docs/client_test.rst docs/client_test.html \
|
||||
docs/unicode_support.png docs/client_test.png docs/style.css Jamfile project-root.jam \
|
||||
m4/ac_cxx_namespaces.m4 m4/acx_pthread.m4 m4/ax_boost_date-time.m4 \
|
||||
m4/ax_boost_filesystem.m4 m4/ax_boost_thread.m4 src/file_win.cpp libtorrent.pc \
|
||||
m4/ax_boost_filesystem.m4 m4/ax_boost_thread.m4 src/file_win.cpp libtorrent.pc
|
||||
|
||||
pkginclude_HEADER = \
|
||||
debian/changelog \
|
||||
debian/compat \
|
||||
debian/control \
|
||||
debian/copyright \
|
||||
debian/files \
|
||||
debian/libtorrent0-dev.dirs \
|
||||
debian/libtorrent0-dev.docs \
|
||||
debian/libtorrent0-dev.install \
|
||||
debian/libtorrent0.dirs \
|
||||
debian/libtorrent0.docs \
|
||||
debian/libtorrent0.install \
|
||||
debian/rules \
|
||||
asio/aclocal.m4 \
|
||||
asio/autogen.sh \
|
||||
asio/boostify.pl \
|
||||
|
|
248
docs/manual.html
248
docs/manual.html
|
@ -142,148 +142,148 @@ div.warning, div.note, div.important {
|
|||
<div class="contents topic">
|
||||
<p class="topic-title first"><a id="table-of-contents" name="table-of-contents">Table of contents</a></p>
|
||||
<ul class="simple">
|
||||
<li><a class="reference" href="#introduction" id="id24" name="id24">introduction</a></li>
|
||||
<li><a class="reference" href="#downloading-and-building" id="id25" name="id25">downloading and building</a><ul>
|
||||
<li><a class="reference" href="#building-with-bbv2" id="id26" name="id26">building with BBv2</a></li>
|
||||
<li><a class="reference" href="#building-with-autotools" id="id27" name="id27">building with autotools</a></li>
|
||||
<li><a class="reference" href="#building-with-other-build-systems" id="id28" name="id28">building with other build systems</a></li>
|
||||
<li><a class="reference" href="#build-configurations" id="id29" name="id29">build configurations</a></li>
|
||||
<li><a class="reference" href="#introduction" id="id25" name="id25">introduction</a></li>
|
||||
<li><a class="reference" href="#downloading-and-building" id="id26" name="id26">downloading and building</a><ul>
|
||||
<li><a class="reference" href="#building-with-bbv2" id="id27" name="id27">building with BBv2</a></li>
|
||||
<li><a class="reference" href="#building-with-autotools" id="id28" name="id28">building with autotools</a></li>
|
||||
<li><a class="reference" href="#building-with-other-build-systems" id="id29" name="id29">building with other build systems</a></li>
|
||||
<li><a class="reference" href="#build-configurations" id="id30" name="id30">build configurations</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#overview" id="id30" name="id30">overview</a></li>
|
||||
<li><a class="reference" href="#session" id="id31" name="id31">session</a><ul>
|
||||
<li><a class="reference" href="#id8" id="id32" name="id32">session()</a></li>
|
||||
<li><a class="reference" href="#id9" id="id33" name="id33">~session()</a></li>
|
||||
<li><a class="reference" href="#add-torrent" id="id34" name="id34">add_torrent()</a></li>
|
||||
<li><a class="reference" href="#remove-torrent" id="id35" name="id35">remove_torrent()</a></li>
|
||||
<li><a class="reference" href="#disable-extensions-enable-extension" id="id36" name="id36">disable_extensions() enable_extension()</a></li>
|
||||
<li><a class="reference" href="#set-upload-rate-limit-set-download-rate-limit" id="id37" name="id37">set_upload_rate_limit() set_download_rate_limit()</a></li>
|
||||
<li><a class="reference" href="#set-max-uploads-set-max-connections" id="id38" name="id38">set_max_uploads() set_max_connections()</a></li>
|
||||
<li><a class="reference" href="#set-max-half-open-connections" id="id39" name="id39">set_max_half_open_connections()</a></li>
|
||||
<li><a class="reference" href="#set-ip-filter" id="id40" name="id40">set_ip_filter()</a></li>
|
||||
<li><a class="reference" href="#status" id="id41" name="id41">status()</a></li>
|
||||
<li><a class="reference" href="#is-listening-listen-port-listen-on" id="id42" name="id42">is_listening() listen_port() listen_on()</a></li>
|
||||
<li><a class="reference" href="#pop-alert-set-severity-level" id="id43" name="id43">pop_alert() set_severity_level()</a></li>
|
||||
<li><a class="reference" href="#overview" id="id31" name="id31">overview</a></li>
|
||||
<li><a class="reference" href="#session" id="id32" name="id32">session</a><ul>
|
||||
<li><a class="reference" href="#id9" id="id33" name="id33">session()</a></li>
|
||||
<li><a class="reference" href="#id10" id="id34" name="id34">~session()</a></li>
|
||||
<li><a class="reference" href="#add-torrent" id="id35" name="id35">add_torrent()</a></li>
|
||||
<li><a class="reference" href="#remove-torrent" id="id36" name="id36">remove_torrent()</a></li>
|
||||
<li><a class="reference" href="#disable-extensions-enable-extension" id="id37" name="id37">disable_extensions() enable_extension()</a></li>
|
||||
<li><a class="reference" href="#set-upload-rate-limit-set-download-rate-limit" id="id38" name="id38">set_upload_rate_limit() set_download_rate_limit()</a></li>
|
||||
<li><a class="reference" href="#set-max-uploads-set-max-connections" id="id39" name="id39">set_max_uploads() set_max_connections()</a></li>
|
||||
<li><a class="reference" href="#set-max-half-open-connections" id="id40" name="id40">set_max_half_open_connections()</a></li>
|
||||
<li><a class="reference" href="#set-ip-filter" id="id41" name="id41">set_ip_filter()</a></li>
|
||||
<li><a class="reference" href="#status" id="id42" name="id42">status()</a></li>
|
||||
<li><a class="reference" href="#is-listening-listen-port-listen-on" id="id43" name="id43">is_listening() listen_port() listen_on()</a></li>
|
||||
<li><a class="reference" href="#pop-alert-set-severity-level" id="id44" name="id44">pop_alert() set_severity_level()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#entry" id="id44" name="id44">entry</a><ul>
|
||||
<li><a class="reference" href="#integer-string-list-dict-type" id="id45" name="id45">integer() string() list() dict() type()</a></li>
|
||||
<li><a class="reference" href="#operator" id="id46" name="id46">operator[]</a></li>
|
||||
<li><a class="reference" href="#find-key" id="id47" name="id47">find_key()</a></li>
|
||||
<li><a class="reference" href="#entry" id="id45" name="id45">entry</a><ul>
|
||||
<li><a class="reference" href="#integer-string-list-dict-type" id="id46" name="id46">integer() string() list() dict() type()</a></li>
|
||||
<li><a class="reference" href="#operator" id="id47" name="id47">operator[]</a></li>
|
||||
<li><a class="reference" href="#find-key" id="id48" name="id48">find_key()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#torrent-info" id="id48" name="id48">torrent_info</a><ul>
|
||||
<li><a class="reference" href="#id10" id="id49" name="id49">torrent_info()</a></li>
|
||||
<li><a class="reference" href="#set-comment-set-piece-size-set-creator-set-hash-add-tracker-add-file" id="id50" name="id50">set_comment() set_piece_size() set_creator() set_hash() add_tracker() add_file()</a></li>
|
||||
<li><a class="reference" href="#create-torrent" id="id51" name="id51">create_torrent()</a></li>
|
||||
<li><a class="reference" href="#begin-files-end-files-rbegin-files-rend-files" id="id52" name="id52">begin_files() end_files() rbegin_files() rend_files()</a></li>
|
||||
<li><a class="reference" href="#num-files-file-at" id="id53" name="id53">num_files() file_at()</a></li>
|
||||
<li><a class="reference" href="#map-block" id="id54" name="id54">map_block()</a></li>
|
||||
<li><a class="reference" href="#map-file" id="id55" name="id55">map_file()</a></li>
|
||||
<li><a class="reference" href="#url-seeds" id="id56" name="id56">url_seeds()</a></li>
|
||||
<li><a class="reference" href="#print" id="id57" name="id57">print()</a></li>
|
||||
<li><a class="reference" href="#trackers" id="id58" name="id58">trackers()</a></li>
|
||||
<li><a class="reference" href="#total-size-piece-length-piece-size-num-pieces" id="id59" name="id59">total_size() piece_length() piece_size() num_pieces()</a></li>
|
||||
<li><a class="reference" href="#hash-for-piece-info-hash" id="id60" name="id60">hash_for_piece() info_hash()</a></li>
|
||||
<li><a class="reference" href="#name-comment-creation-date-creator" id="id61" name="id61">name() comment() creation_date() creator()</a></li>
|
||||
<li><a class="reference" href="#torrent-info" id="id49" name="id49">torrent_info</a><ul>
|
||||
<li><a class="reference" href="#id11" id="id50" name="id50">torrent_info()</a></li>
|
||||
<li><a class="reference" href="#set-comment-set-piece-size-set-creator-set-hash-add-tracker-add-file" id="id51" name="id51">set_comment() set_piece_size() set_creator() set_hash() add_tracker() add_file()</a></li>
|
||||
<li><a class="reference" href="#create-torrent" id="id52" name="id52">create_torrent()</a></li>
|
||||
<li><a class="reference" href="#begin-files-end-files-rbegin-files-rend-files" id="id53" name="id53">begin_files() end_files() rbegin_files() rend_files()</a></li>
|
||||
<li><a class="reference" href="#num-files-file-at" id="id54" name="id54">num_files() file_at()</a></li>
|
||||
<li><a class="reference" href="#map-block" id="id55" name="id55">map_block()</a></li>
|
||||
<li><a class="reference" href="#map-file" id="id56" name="id56">map_file()</a></li>
|
||||
<li><a class="reference" href="#url-seeds" id="id57" name="id57">url_seeds()</a></li>
|
||||
<li><a class="reference" href="#print" id="id58" name="id58">print()</a></li>
|
||||
<li><a class="reference" href="#trackers" id="id59" name="id59">trackers()</a></li>
|
||||
<li><a class="reference" href="#total-size-piece-length-piece-size-num-pieces" id="id60" name="id60">total_size() piece_length() piece_size() num_pieces()</a></li>
|
||||
<li><a class="reference" href="#hash-for-piece-info-hash" id="id61" name="id61">hash_for_piece() info_hash()</a></li>
|
||||
<li><a class="reference" href="#name-comment-creation-date-creator" id="id62" name="id62">name() comment() creation_date() creator()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#torrent-handle" id="id62" name="id62">torrent_handle</a><ul>
|
||||
<li><a class="reference" href="#save-path" id="id63" name="id63">save_path()</a></li>
|
||||
<li><a class="reference" href="#move-storage" id="id64" name="id64">move_storage()</a></li>
|
||||
<li><a class="reference" href="#force-reannounce" id="id65" name="id65">force_reannounce()</a></li>
|
||||
<li><a class="reference" href="#connect-peer" id="id66" name="id66">connect_peer()</a></li>
|
||||
<li><a class="reference" href="#set-ratio" id="id67" name="id67">set_ratio()</a></li>
|
||||
<li><a class="reference" href="#set-upload-limit-set-download-limit" id="id68" name="id68">set_upload_limit() set_download_limit()</a></li>
|
||||
<li><a class="reference" href="#set-peer-upload-limit-set-peer-download-limit" id="id69" name="id69">set_peer_upload_limit() set_peer_download_limit()</a></li>
|
||||
<li><a class="reference" href="#pause-resume-is-paused" id="id70" name="id70">pause() resume() is_paused()</a></li>
|
||||
<li><a class="reference" href="#is-seed" id="id71" name="id71">is_seed()</a></li>
|
||||
<li><a class="reference" href="#has-metadata" id="id72" name="id72">has_metadata()</a></li>
|
||||
<li><a class="reference" href="#set-tracker-login" id="id73" name="id73">set_tracker_login()</a></li>
|
||||
<li><a class="reference" href="#trackers-replace-trackers" id="id74" name="id74">trackers() replace_trackers()</a></li>
|
||||
<li><a class="reference" href="#add-url-seed" id="id75" name="id75">add_url_seed()</a></li>
|
||||
<li><a class="reference" href="#use-interface" id="id76" name="id76">use_interface()</a></li>
|
||||
<li><a class="reference" href="#info-hash" id="id77" name="id77">info_hash()</a></li>
|
||||
<li><a class="reference" href="#id12" id="id78" name="id78">set_max_uploads() set_max_connections()</a></li>
|
||||
<li><a class="reference" href="#write-resume-data" id="id79" name="id79">write_resume_data()</a></li>
|
||||
<li><a class="reference" href="#metadata" id="id80" name="id80">metadata()</a></li>
|
||||
<li><a class="reference" href="#id13" id="id81" name="id81">status()</a></li>
|
||||
<li><a class="reference" href="#get-download-queue" id="id82" name="id82">get_download_queue()</a></li>
|
||||
<li><a class="reference" href="#get-peer-info" id="id83" name="id83">get_peer_info()</a></li>
|
||||
<li><a class="reference" href="#get-torrent-info" id="id84" name="id84">get_torrent_info()</a></li>
|
||||
<li><a class="reference" href="#is-valid" id="id85" name="id85">is_valid()</a></li>
|
||||
<li><a class="reference" href="#torrent-handle" id="id63" name="id63">torrent_handle</a><ul>
|
||||
<li><a class="reference" href="#save-path" id="id64" name="id64">save_path()</a></li>
|
||||
<li><a class="reference" href="#move-storage" id="id65" name="id65">move_storage()</a></li>
|
||||
<li><a class="reference" href="#force-reannounce" id="id66" name="id66">force_reannounce()</a></li>
|
||||
<li><a class="reference" href="#connect-peer" id="id67" name="id67">connect_peer()</a></li>
|
||||
<li><a class="reference" href="#set-ratio" id="id68" name="id68">set_ratio()</a></li>
|
||||
<li><a class="reference" href="#set-upload-limit-set-download-limit" id="id69" name="id69">set_upload_limit() set_download_limit()</a></li>
|
||||
<li><a class="reference" href="#set-peer-upload-limit-set-peer-download-limit" id="id70" name="id70">set_peer_upload_limit() set_peer_download_limit()</a></li>
|
||||
<li><a class="reference" href="#pause-resume-is-paused" id="id71" name="id71">pause() resume() is_paused()</a></li>
|
||||
<li><a class="reference" href="#is-seed" id="id72" name="id72">is_seed()</a></li>
|
||||
<li><a class="reference" href="#has-metadata" id="id73" name="id73">has_metadata()</a></li>
|
||||
<li><a class="reference" href="#set-tracker-login" id="id74" name="id74">set_tracker_login()</a></li>
|
||||
<li><a class="reference" href="#trackers-replace-trackers" id="id75" name="id75">trackers() replace_trackers()</a></li>
|
||||
<li><a class="reference" href="#add-url-seed" id="id76" name="id76">add_url_seed()</a></li>
|
||||
<li><a class="reference" href="#use-interface" id="id77" name="id77">use_interface()</a></li>
|
||||
<li><a class="reference" href="#info-hash" id="id78" name="id78">info_hash()</a></li>
|
||||
<li><a class="reference" href="#id13" id="id79" name="id79">set_max_uploads() set_max_connections()</a></li>
|
||||
<li><a class="reference" href="#write-resume-data" id="id80" name="id80">write_resume_data()</a></li>
|
||||
<li><a class="reference" href="#metadata" id="id81" name="id81">metadata()</a></li>
|
||||
<li><a class="reference" href="#id14" id="id82" name="id82">status()</a></li>
|
||||
<li><a class="reference" href="#get-download-queue" id="id83" name="id83">get_download_queue()</a></li>
|
||||
<li><a class="reference" href="#get-peer-info" id="id84" name="id84">get_peer_info()</a></li>
|
||||
<li><a class="reference" href="#get-torrent-info" id="id85" name="id85">get_torrent_info()</a></li>
|
||||
<li><a class="reference" href="#is-valid" id="id86" name="id86">is_valid()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#torrent-status" id="id86" name="id86">torrent_status</a></li>
|
||||
<li><a class="reference" href="#peer-info" id="id87" name="id87">peer_info</a></li>
|
||||
<li><a class="reference" href="#session-settings" id="id88" name="id88">session_settings</a></li>
|
||||
<li><a class="reference" href="#ip-filter" id="id89" name="id89">ip_filter</a><ul>
|
||||
<li><a class="reference" href="#id16" id="id90" name="id90">ip_filter()</a></li>
|
||||
<li><a class="reference" href="#add-rule" id="id91" name="id91">add_rule()</a></li>
|
||||
<li><a class="reference" href="#access" id="id92" name="id92">access()</a></li>
|
||||
<li><a class="reference" href="#export-filter" id="id93" name="id93">export_filter()</a></li>
|
||||
<li><a class="reference" href="#torrent-status" id="id87" name="id87">torrent_status</a></li>
|
||||
<li><a class="reference" href="#peer-info" id="id88" name="id88">peer_info</a></li>
|
||||
<li><a class="reference" href="#session-settings" id="id89" name="id89">session_settings</a></li>
|
||||
<li><a class="reference" href="#ip-filter" id="id90" name="id90">ip_filter</a><ul>
|
||||
<li><a class="reference" href="#id17" id="id91" name="id91">ip_filter()</a></li>
|
||||
<li><a class="reference" href="#add-rule" id="id92" name="id92">add_rule()</a></li>
|
||||
<li><a class="reference" href="#access" id="id93" name="id93">access()</a></li>
|
||||
<li><a class="reference" href="#export-filter" id="id94" name="id94">export_filter()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#big-number" id="id94" name="id94">big_number</a></li>
|
||||
<li><a class="reference" href="#hasher" id="id95" name="id95">hasher</a></li>
|
||||
<li><a class="reference" href="#fingerprint" id="id96" name="id96">fingerprint</a></li>
|
||||
<li><a class="reference" href="#free-functions" id="id97" name="id97">free functions</a><ul>
|
||||
<li><a class="reference" href="#identify-client" id="id98" name="id98">identify_client()</a></li>
|
||||
<li><a class="reference" href="#client-fingerprint" id="id99" name="id99">client_fingerprint()</a></li>
|
||||
<li><a class="reference" href="#bdecode-bencode" id="id100" name="id100">bdecode() bencode()</a></li>
|
||||
<li><a class="reference" href="#big-number" id="id95" name="id95">big_number</a></li>
|
||||
<li><a class="reference" href="#hasher" id="id96" name="id96">hasher</a></li>
|
||||
<li><a class="reference" href="#fingerprint" id="id97" name="id97">fingerprint</a></li>
|
||||
<li><a class="reference" href="#free-functions" id="id98" name="id98">free functions</a><ul>
|
||||
<li><a class="reference" href="#identify-client" id="id99" name="id99">identify_client()</a></li>
|
||||
<li><a class="reference" href="#client-fingerprint" id="id100" name="id100">client_fingerprint()</a></li>
|
||||
<li><a class="reference" href="#bdecode-bencode" id="id101" name="id101">bdecode() bencode()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#alerts" id="id101" name="id101">alerts</a><ul>
|
||||
<li><a class="reference" href="#listen-failed-alert" id="id102" name="id102">listen_failed_alert</a></li>
|
||||
<li><a class="reference" href="#file-error-alert" id="id103" name="id103">file_error_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-announce-alert" id="id104" name="id104">tracker_announce_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-alert" id="id105" name="id105">tracker_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-reply-alert" id="id106" name="id106">tracker_reply_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-warning-alert" id="id107" name="id107">tracker_warning_alert</a></li>
|
||||
<li><a class="reference" href="#url-seed-alert" id="id108" name="id108">url_seed_alert</a></li>
|
||||
<li><a class="reference" href="#hash-failed-alert" id="id109" name="id109">hash_failed_alert</a></li>
|
||||
<li><a class="reference" href="#peer-ban-alert" id="id110" name="id110">peer_ban_alert</a></li>
|
||||
<li><a class="reference" href="#peer-error-alert" id="id111" name="id111">peer_error_alert</a></li>
|
||||
<li><a class="reference" href="#invalid-request-alert" id="id112" name="id112">invalid_request_alert</a></li>
|
||||
<li><a class="reference" href="#torrent-finished-alert" id="id113" name="id113">torrent_finished_alert</a></li>
|
||||
<li><a class="reference" href="#metadata-failed-alert" id="id114" name="id114">metadata_failed_alert</a></li>
|
||||
<li><a class="reference" href="#metadata-received-alert" id="id115" name="id115">metadata_received_alert</a></li>
|
||||
<li><a class="reference" href="#fastresume-rejected-alert" id="id116" name="id116">fastresume_rejected_alert</a></li>
|
||||
<li><a class="reference" href="#dispatcher" id="id117" name="id117">dispatcher</a></li>
|
||||
<li><a class="reference" href="#alerts" id="id102" name="id102">alerts</a><ul>
|
||||
<li><a class="reference" href="#listen-failed-alert" id="id103" name="id103">listen_failed_alert</a></li>
|
||||
<li><a class="reference" href="#file-error-alert" id="id104" name="id104">file_error_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-announce-alert" id="id105" name="id105">tracker_announce_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-alert" id="id106" name="id106">tracker_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-reply-alert" id="id107" name="id107">tracker_reply_alert</a></li>
|
||||
<li><a class="reference" href="#tracker-warning-alert" id="id108" name="id108">tracker_warning_alert</a></li>
|
||||
<li><a class="reference" href="#url-seed-alert" id="id109" name="id109">url_seed_alert</a></li>
|
||||
<li><a class="reference" href="#hash-failed-alert" id="id110" name="id110">hash_failed_alert</a></li>
|
||||
<li><a class="reference" href="#peer-ban-alert" id="id111" name="id111">peer_ban_alert</a></li>
|
||||
<li><a class="reference" href="#peer-error-alert" id="id112" name="id112">peer_error_alert</a></li>
|
||||
<li><a class="reference" href="#invalid-request-alert" id="id113" name="id113">invalid_request_alert</a></li>
|
||||
<li><a class="reference" href="#torrent-finished-alert" id="id114" name="id114">torrent_finished_alert</a></li>
|
||||
<li><a class="reference" href="#metadata-failed-alert" id="id115" name="id115">metadata_failed_alert</a></li>
|
||||
<li><a class="reference" href="#metadata-received-alert" id="id116" name="id116">metadata_received_alert</a></li>
|
||||
<li><a class="reference" href="#fastresume-rejected-alert" id="id117" name="id117">fastresume_rejected_alert</a></li>
|
||||
<li><a class="reference" href="#dispatcher" id="id118" name="id118">dispatcher</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#exceptions" id="id118" name="id118">exceptions</a><ul>
|
||||
<li><a class="reference" href="#invalid-handle" id="id119" name="id119">invalid_handle</a></li>
|
||||
<li><a class="reference" href="#duplicate-torrent" id="id120" name="id120">duplicate_torrent</a></li>
|
||||
<li><a class="reference" href="#invalid-encoding" id="id121" name="id121">invalid_encoding</a></li>
|
||||
<li><a class="reference" href="#type-error" id="id122" name="id122">type_error</a></li>
|
||||
<li><a class="reference" href="#invalid-torrent-file" id="id123" name="id123">invalid_torrent_file</a></li>
|
||||
<li><a class="reference" href="#exceptions" id="id119" name="id119">exceptions</a><ul>
|
||||
<li><a class="reference" href="#invalid-handle" id="id120" name="id120">invalid_handle</a></li>
|
||||
<li><a class="reference" href="#duplicate-torrent" id="id121" name="id121">duplicate_torrent</a></li>
|
||||
<li><a class="reference" href="#invalid-encoding" id="id122" name="id122">invalid_encoding</a></li>
|
||||
<li><a class="reference" href="#type-error" id="id123" name="id123">type_error</a></li>
|
||||
<li><a class="reference" href="#invalid-torrent-file" id="id124" name="id124">invalid_torrent_file</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#examples" id="id124" name="id124">examples</a><ul>
|
||||
<li><a class="reference" href="#dump-torrent" id="id125" name="id125">dump_torrent</a></li>
|
||||
<li><a class="reference" href="#simple-client" id="id126" name="id126">simple client</a></li>
|
||||
<li><a class="reference" href="#make-torrent" id="id127" name="id127">make_torrent</a></li>
|
||||
<li><a class="reference" href="#examples" id="id125" name="id125">examples</a><ul>
|
||||
<li><a class="reference" href="#dump-torrent" id="id126" name="id126">dump_torrent</a></li>
|
||||
<li><a class="reference" href="#simple-client" id="id127" name="id127">simple client</a></li>
|
||||
<li><a class="reference" href="#make-torrent" id="id128" name="id128">make_torrent</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#fast-resume" id="id128" name="id128">fast resume</a><ul>
|
||||
<li><a class="reference" href="#file-format" id="id129" name="id129">file format</a></li>
|
||||
<li><a class="reference" href="#fast-resume" id="id129" name="id129">fast resume</a><ul>
|
||||
<li><a class="reference" href="#file-format" id="id130" name="id130">file format</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#threads" id="id130" name="id130">threads</a></li>
|
||||
<li><a class="reference" href="#storage-allocation" id="id131" name="id131">storage allocation</a><ul>
|
||||
<li><a class="reference" href="#full-allocation" id="id132" name="id132">full allocation</a></li>
|
||||
<li><a class="reference" href="#compact-allocation" id="id133" name="id133">compact allocation</a></li>
|
||||
<li><a class="reference" href="#threads" id="id131" name="id131">threads</a></li>
|
||||
<li><a class="reference" href="#storage-allocation" id="id132" name="id132">storage allocation</a><ul>
|
||||
<li><a class="reference" href="#full-allocation" id="id133" name="id133">full allocation</a></li>
|
||||
<li><a class="reference" href="#compact-allocation" id="id134" name="id134">compact allocation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#extensions" id="id134" name="id134">extensions</a><ul>
|
||||
<li><a class="reference" href="#chat-messages" id="id135" name="id135">chat messages</a></li>
|
||||
<li><a class="reference" href="#metadata-from-peers" id="id136" name="id136">metadata from peers</a></li>
|
||||
<li><a class="reference" href="#http-seeding" id="id137" name="id137">HTTP seeding</a></li>
|
||||
<li><a class="reference" href="#extensions" id="id135" name="id135">extensions</a><ul>
|
||||
<li><a class="reference" href="#chat-messages" id="id136" name="id136">chat messages</a></li>
|
||||
<li><a class="reference" href="#metadata-from-peers" id="id137" name="id137">metadata from peers</a></li>
|
||||
<li><a class="reference" href="#http-seeding" id="id138" name="id138">HTTP seeding</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a class="reference" href="#filename-checks" id="id138" name="id138">filename checks</a></li>
|
||||
<li><a class="reference" href="#acknowledgments" id="id139" name="id139">acknowledgments</a></li>
|
||||
<li><a class="reference" href="#filename-checks" id="id139" name="id139">filename checks</a></li>
|
||||
<li><a class="reference" href="#acknowledgments" id="id140" name="id140">acknowledgments</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section">
|
||||
|
@ -356,7 +356,7 @@ epoll on linux and kqueue on MacOS X and BSD.</p>
|
|||
<ul class="simple">
|
||||
<li>Windows 2000 vc7.1</li>
|
||||
<li>Linux x86 GCC 3.3, GCC 3.4.2</li>
|
||||
<li>MacOS X (darwin), (Apple's) GCC 4.0</li>
|
||||
<li>MacOS X (darwin), (Apple's) GCC 3.3, (Apple's) GCC 4.0</li>
|
||||
<li>SunOS 5.8 GCC 3.1</li>
|
||||
<li>Cygwin GCC 3.3.3</li>
|
||||
</ul>
|
||||
|
@ -366,7 +366,6 @@ epoll on linux and kqueue on MacOS X and BSD.</p>
|
|||
<ul class="simple">
|
||||
<li>GCC 2.95.4</li>
|
||||
<li>msvc6</li>
|
||||
<li>(Apple's) GCC 3.3 (compiler crashes with the latest version of asio)</li>
|
||||
</ul>
|
||||
</blockquote>
|
||||
<p>libtorrent is released under the <a class="reference" href="http://www.opensource.org/licenses/bsd-license.php">BSD-license</a>.</p>
|
||||
|
@ -514,6 +513,7 @@ For more build configuration flags see <a class="reference" href="#build-configu
|
|||
<p>When building the example client on windows, you need to build with
|
||||
<tt class="docutils literal"><span class="pre">link=static</span></tt> otherwise you may get unresolved external symbols for some
|
||||
boost.program-options symbols.</p>
|
||||
<p>For more information, see the <a class="reference" href="http://www.boost.org/tools/build/v2/index.html">Boost build v2 documentation</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section">
|
||||
|
@ -793,7 +793,7 @@ class session: public boost::noncopyable
|
|||
<p>Once it's created, the session object will spawn the main thread that will do all the work.
|
||||
The main thread will be idle as long it doesn't have any torrents to participate in.</p>
|
||||
<div class="section">
|
||||
<h2><a id="id8" name="id8">session()</a></h2>
|
||||
<h2><a id="id9" name="id9">session()</a></h2>
|
||||
<blockquote>
|
||||
<pre class="literal-block">
|
||||
session(fingerprint const& print = libtorrent::fingerprint("LT", 0, 1, 0, 0));
|
||||
|
@ -812,7 +812,7 @@ will automatically try to listen on a port on the given interface. For more info
|
|||
the parameters, see <tt class="docutils literal"><span class="pre">listen_on()</span></tt> function.</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2><a id="id9" name="id9">~session()</a></h2>
|
||||
<h2><a id="id10" name="id10">~session()</a></h2>
|
||||
<p>The destructor of session will notify all trackers that our torrents have been shut down.
|
||||
If some trackers are down, they will time out. All this before the destructor of session
|
||||
returns. So, it's advised that any kind of interface (such as windows) are closed before
|
||||
|
@ -1252,7 +1252,7 @@ public:
|
|||
};
|
||||
</pre>
|
||||
<div class="section">
|
||||
<h2><a id="id10" name="id10">torrent_info()</a></h2>
|
||||
<h2><a id="id11" name="id11">torrent_info()</a></h2>
|
||||
<blockquote>
|
||||
<pre class="literal-block">
|
||||
torrent_info();
|
||||
|
@ -1760,7 +1760,7 @@ sha1_hash info_hash() const;
|
|||
<p><tt class="docutils literal"><span class="pre">info_hash()</span></tt> returns the info-hash for the torrent.</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2><a id="id12" name="id12">set_max_uploads() set_max_connections()</a></h2>
|
||||
<h2><a id="id13" name="id13">set_max_uploads() set_max_connections()</a></h2>
|
||||
<blockquote>
|
||||
<pre class="literal-block">
|
||||
void set_max_uploads(int max_uploads) const;
|
||||
|
@ -1809,7 +1809,7 @@ std::vector<char> const& metadata() const;
|
|||
it will produce the same hash as the info-hash.</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<h2><a id="id13" name="id13">status()</a></h2>
|
||||
<h2><a id="id14" name="id14">status()</a></h2>
|
||||
<blockquote>
|
||||
<pre class="literal-block">
|
||||
torrent_status status() const;
|
||||
|
@ -2325,7 +2325,7 @@ public:
|
|||
</pre>
|
||||
</blockquote>
|
||||
<div class="section">
|
||||
<h2><a id="id16" name="id16">ip_filter()</a></h2>
|
||||
<h2><a id="id17" name="id17">ip_filter()</a></h2>
|
||||
<blockquote>
|
||||
<pre class="literal-block">
|
||||
ip_filter()
|
||||
|
|
|
@ -86,7 +86,7 @@ libtorrent has been successfully compiled and tested on:
|
|||
|
||||
* Windows 2000 vc7.1
|
||||
* Linux x86 GCC 3.3, GCC 3.4.2
|
||||
* MacOS X (darwin), (Apple's) GCC 4.0
|
||||
* MacOS X (darwin), (Apple's) GCC 3.3, (Apple's) GCC 4.0
|
||||
* SunOS 5.8 GCC 3.1
|
||||
* Cygwin GCC 3.3.3
|
||||
|
||||
|
@ -94,7 +94,6 @@ Fails on:
|
|||
|
||||
* GCC 2.95.4
|
||||
* msvc6
|
||||
* (Apple's) GCC 3.3 (compiler crashes with the latest version of asio)
|
||||
|
||||
libtorrent is released under the BSD-license_.
|
||||
|
||||
|
@ -275,6 +274,9 @@ When building the example client on windows, you need to build with
|
|||
``link=static`` otherwise you may get unresolved external symbols for some
|
||||
boost.program-options symbols.
|
||||
|
||||
For more information, see the `Boost build v2 documentation`__.
|
||||
|
||||
__ http://www.boost.org/tools/build/v2/index.html
|
||||
|
||||
building with autotools
|
||||
-----------------------
|
||||
|
|
|
@ -689,14 +689,17 @@ int main(int ac, char* av[])
|
|||
{
|
||||
if (torrent_finished_alert* p = dynamic_cast<torrent_finished_alert*>(a.get()))
|
||||
{
|
||||
// limit the bandwidth for all seeding torrents
|
||||
p->handle.set_max_connections(60);
|
||||
//p->handle.set_max_uploads(5);
|
||||
//p->handle.set_upload_limit(10000);
|
||||
|
||||
// all finished downloades are
|
||||
// moved into this directory
|
||||
//p->handle.move_storage("finished");
|
||||
// write resume data for the finished torrent
|
||||
torrent_handle h = p->handle;
|
||||
entry data = h.write_resume_data();
|
||||
std::stringstream s;
|
||||
s << h.get_torrent_info().name() << ".fastresume";
|
||||
boost::filesystem::ofstream out(h.save_path() / s.str(), std::ios_base::binary);
|
||||
out.unsetf(std::ios_base::skipws);
|
||||
bencode(std::ostream_iterator<char>(out), data);
|
||||
|
||||
events.push_back(now + ": "
|
||||
+ p->handle.get_torrent_info().name() + ": " + a->msg());
|
||||
}
|
||||
|
@ -794,13 +797,8 @@ int main(int ac, char* av[])
|
|||
out << "tracker: " << s.current_tracker << "\n";
|
||||
}
|
||||
|
||||
out << "___________________________________\n";
|
||||
|
||||
if (print_peers && !peers.empty())
|
||||
{
|
||||
print_peer_info(out, peers);
|
||||
out << "___________________________________\n";
|
||||
}
|
||||
|
||||
if (print_downloads && s.state != torrent_status::seeding)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
pkginclude_HEADERS = libtorrent/alert.hpp \
|
||||
nobase_pkginclude_HEADERS = libtorrent/alert.hpp \
|
||||
libtorrent/alert_types.hpp \
|
||||
libtorrent/allocate_resources.hpp \
|
||||
libtorrent/bencode.hpp \
|
||||
|
|
|
@ -52,6 +52,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/detail/atomic_count.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
|
@ -540,7 +541,7 @@ namespace libtorrent
|
|||
bool m_reading;
|
||||
int m_last_read_size;
|
||||
// reference counter for intrusive_ptr
|
||||
mutable int m_refs;
|
||||
mutable boost::detail::atomic_count m_refs;
|
||||
|
||||
#ifndef NDEBUG
|
||||
public:
|
||||
|
|
|
@ -179,6 +179,10 @@ namespace libtorrent
|
|||
return m_num_unchoked;
|
||||
}
|
||||
|
||||
typedef std::vector<peer>::iterator iterator;
|
||||
iterator begin_peer() { return m_peers.begin(); }
|
||||
iterator end_peer() { return m_peers.end(); }
|
||||
|
||||
private:
|
||||
|
||||
bool unchoke_one_peer();
|
||||
|
@ -209,6 +213,7 @@ namespace libtorrent
|
|||
|
||||
ptime not_tried_yet(boost::gregorian::date(1970,boost::gregorian::Jan,1));
|
||||
|
||||
// this timeout has to be customizable!
|
||||
return p.connection == 0
|
||||
&& p.connected != not_tried_yet
|
||||
&& second_clock::universal_time() - p.connected > minutes(30);
|
||||
|
|
|
@ -360,9 +360,14 @@ namespace libtorrent
|
|||
assert(m_picker.get());
|
||||
return *m_picker;
|
||||
}
|
||||
policy& get_policy() { return *m_policy; }
|
||||
policy& get_policy()
|
||||
{
|
||||
assert(m_policy);
|
||||
return *m_policy;
|
||||
}
|
||||
piece_manager& filesystem();
|
||||
torrent_info const& torrent_file() const { return m_torrent_file; }
|
||||
torrent_info const& torrent_file() const
|
||||
{ return m_torrent_file; }
|
||||
|
||||
std::vector<announce_entry> const& trackers() const
|
||||
{ return m_trackers; }
|
||||
|
|
|
@ -375,7 +375,7 @@ namespace libtorrent
|
|||
}
|
||||
#endif
|
||||
|
||||
tcp::resolver::query q(*connect_to_host, "http");
|
||||
tcp::resolver::query q(*connect_to_host, "https");
|
||||
m_name_lookup.async_resolve(q
|
||||
, boost::bind(&http_tracker_connection::name_lookup, self(), _1, _2));
|
||||
set_timeout(m_settings.tracker_completion_timeout
|
||||
|
|
|
@ -65,8 +65,7 @@ namespace libtorrent
|
|||
{
|
||||
assert(c->m_refs > 0);
|
||||
assert(c != 0);
|
||||
--c->m_refs;
|
||||
if (c->m_refs == 0)
|
||||
if (--c->m_refs == 0)
|
||||
delete c;
|
||||
}
|
||||
|
||||
|
@ -467,7 +466,11 @@ namespace libtorrent
|
|||
|
||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||
|
||||
if (t && t->is_aborted()) { m_torrent.reset(); t.reset(); }
|
||||
if (t && t->is_aborted())
|
||||
{
|
||||
m_torrent.reset();
|
||||
t.reset();
|
||||
}
|
||||
|
||||
if (!t)
|
||||
{
|
||||
|
@ -1669,7 +1672,8 @@ namespace libtorrent
|
|||
assert(packet_size > 0);
|
||||
m_recv_pos = 0;
|
||||
m_packet_size = packet_size;
|
||||
m_recv_buffer.resize(m_packet_size);
|
||||
if (int(m_recv_buffer.size()) < m_packet_size)
|
||||
m_recv_buffer.resize(m_packet_size);
|
||||
}
|
||||
|
||||
void peer_connection::send_buffer(char const* begin, char const* end)
|
||||
|
@ -1830,6 +1834,11 @@ namespace libtorrent
|
|||
return;
|
||||
}
|
||||
|
||||
// the connection cannot time out while connecting
|
||||
// so we don't need to check m_disconnecting
|
||||
assert(m_disconnecting == false);
|
||||
m_last_receive = second_clock::universal_time();
|
||||
|
||||
// this means the connection just succeeded
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
|
@ -1914,7 +1923,17 @@ namespace libtorrent
|
|||
void peer_connection::check_invariant() const
|
||||
{
|
||||
boost::shared_ptr<torrent> t = m_torrent.lock();
|
||||
if (!t) return;
|
||||
if (!t)
|
||||
{
|
||||
typedef detail::session_impl::torrent_map torrent_map;
|
||||
torrent_map& m = m_ses.m_torrents;
|
||||
for (torrent_map::iterator i = m.begin(), end(m.end()); i != end; ++i)
|
||||
{
|
||||
torrent& t = *i->second;
|
||||
assert(t.connection_for(m_remote) != this);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_in_constructor && t->connection_for(remote()) != this)
|
||||
{
|
||||
|
|
|
@ -829,7 +829,7 @@ namespace libtorrent
|
|||
|
||||
if (i == m_peers.end())
|
||||
{
|
||||
// this is probably a http seed
|
||||
// this is probably an http seed
|
||||
if (web_peer_connection const* p = dynamic_cast<web_peer_connection const*>(&c))
|
||||
{
|
||||
m_torrent->remove_url_seed(p->url());
|
||||
|
|
224
src/session.cpp
224
src/session.cpp
|
@ -117,21 +117,39 @@ namespace libtorrent { namespace detail
|
|||
if (m_torrents.empty() && !m_abort && !processing)
|
||||
m_cond.wait(l);
|
||||
|
||||
if (m_abort) return;
|
||||
if (m_abort)
|
||||
{
|
||||
// no lock is needed here, because the main thread
|
||||
// has already been shut down by now
|
||||
processing.reset();
|
||||
t.reset();
|
||||
std::for_each(m_torrents.begin(), m_torrents.end()
|
||||
, boost::bind(&torrent::abort
|
||||
, boost::bind(&shared_ptr<torrent>::get
|
||||
, boost::bind(&piece_checker_data::torrent_ptr, _1))));
|
||||
m_torrents.clear();
|
||||
std::for_each(m_processing.begin(), m_processing.end()
|
||||
, boost::bind(&torrent::abort
|
||||
, boost::bind(&shared_ptr<torrent>::get
|
||||
, boost::bind(&piece_checker_data::torrent_ptr, _1))));
|
||||
m_processing.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_torrents.empty())
|
||||
{
|
||||
t = m_torrents.front();
|
||||
if (t->abort)
|
||||
{
|
||||
if (processing->torrent_ptr->num_peers())
|
||||
{
|
||||
m_ses.m_torrents.insert(std::make_pair(
|
||||
t->info_hash, t->torrent_ptr));
|
||||
t->torrent_ptr->abort();
|
||||
}
|
||||
|
||||
// make sure the locking order is
|
||||
// consistent to avoid dead locks
|
||||
// we need to lock the session because closing
|
||||
// torrents assume to have access to it
|
||||
l.unlock();
|
||||
session_impl::mutex_t::scoped_lock l2(m_ses.m_mutex);
|
||||
l.lock();
|
||||
|
||||
t->torrent_ptr->abort();
|
||||
m_torrents.pop_front();
|
||||
continue;
|
||||
}
|
||||
|
@ -145,12 +163,11 @@ namespace libtorrent { namespace detail
|
|||
|
||||
if (!error_msg.empty() && m_ses.m_alerts.should_post(alert::warning))
|
||||
{
|
||||
session_impl::mutex_t::scoped_lock l2(m_ses.m_mutex);
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
m_ses.m_alerts.post_alert(fastresume_rejected_alert(
|
||||
t->torrent_ptr->get_handle()
|
||||
, error_msg));
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
(*m_ses.m_logger) << "fastresume data for "
|
||||
<< t->torrent_ptr->torrent_file().name() << " rejected: "
|
||||
<< error_msg << "\n";
|
||||
|
@ -172,21 +189,31 @@ namespace libtorrent { namespace detail
|
|||
|
||||
t->torrent_ptr->files_checked(t->unfinished_pieces);
|
||||
m_torrents.pop_front();
|
||||
m_ses.m_torrents.insert(std::make_pair(t->info_hash, t->torrent_ptr));
|
||||
if (t->torrent_ptr->is_seed() && m_ses.m_alerts.should_post(alert::info))
|
||||
{
|
||||
m_ses.m_alerts.post_alert(torrent_finished_alert(
|
||||
t->torrent_ptr->get_handle()
|
||||
, "torrent is complete"));
|
||||
}
|
||||
|
||||
peer_id id;
|
||||
std::fill(id.begin(), id.end(), 0);
|
||||
for (std::vector<tcp::endpoint>::const_iterator i = t->peers.begin();
|
||||
i != t->peers.end(); ++i)
|
||||
// we cannot add the torrent if the session is aborted.
|
||||
if (!m_ses.m_abort)
|
||||
{
|
||||
t->torrent_ptr->get_policy().peer_from_tracker(*i, id);
|
||||
m_ses.m_torrents.insert(std::make_pair(t->info_hash, t->torrent_ptr));
|
||||
if (t->torrent_ptr->is_seed() && m_ses.m_alerts.should_post(alert::info))
|
||||
{
|
||||
m_ses.m_alerts.post_alert(torrent_finished_alert(
|
||||
t->torrent_ptr->get_handle()
|
||||
, "torrent is complete"));
|
||||
}
|
||||
|
||||
peer_id id;
|
||||
std::fill(id.begin(), id.end(), 0);
|
||||
for (std::vector<tcp::endpoint>::const_iterator i = t->peers.begin();
|
||||
i != t->peers.end(); ++i)
|
||||
{
|
||||
t->torrent_ptr->get_policy().peer_from_tracker(*i, id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
t->torrent_ptr->abort();
|
||||
}
|
||||
t.reset();
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -202,6 +229,7 @@ namespace libtorrent { namespace detail
|
|||
{
|
||||
processing = t;
|
||||
processing->processing = true;
|
||||
t.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -219,12 +247,7 @@ namespace libtorrent { namespace detail
|
|||
t->torrent_ptr->get_handle()
|
||||
, e.what()));
|
||||
}
|
||||
if (t->torrent_ptr->num_peers())
|
||||
{
|
||||
m_ses.m_torrents.insert(std::make_pair(
|
||||
t->info_hash, t->torrent_ptr));
|
||||
t->torrent_ptr->abort();
|
||||
}
|
||||
t->torrent_ptr->abort();
|
||||
|
||||
assert(!m_torrents.empty());
|
||||
m_torrents.pop_front();
|
||||
|
@ -258,12 +281,7 @@ namespace libtorrent { namespace detail
|
|||
assert(!m_processing.empty());
|
||||
assert(m_processing.front() == processing);
|
||||
|
||||
if (processing->torrent_ptr->num_peers())
|
||||
{
|
||||
m_ses.m_torrents.insert(std::make_pair(
|
||||
processing->info_hash, processing->torrent_ptr));
|
||||
processing->torrent_ptr->abort();
|
||||
}
|
||||
processing->torrent_ptr->abort();
|
||||
|
||||
processing.reset();
|
||||
m_processing.pop_front();
|
||||
|
@ -284,23 +302,33 @@ namespace libtorrent { namespace detail
|
|||
assert(!m_processing.empty());
|
||||
assert(m_processing.front() == processing);
|
||||
|
||||
processing->torrent_ptr->files_checked(processing->unfinished_pieces);
|
||||
m_ses.m_torrents.insert(std::make_pair(
|
||||
processing->info_hash, processing->torrent_ptr));
|
||||
if (processing->torrent_ptr->is_seed()
|
||||
&& m_ses.m_alerts.should_post(alert::info))
|
||||
// TODO: factor out the adding of torrents to the session
|
||||
// and to the checker thread to avoid duplicating the
|
||||
// check for abortion.
|
||||
if (!m_ses.m_abort)
|
||||
{
|
||||
m_ses.m_alerts.post_alert(torrent_finished_alert(
|
||||
processing->torrent_ptr->get_handle()
|
||||
, "torrent is complete"));
|
||||
}
|
||||
processing->torrent_ptr->files_checked(processing->unfinished_pieces);
|
||||
m_ses.m_torrents.insert(std::make_pair(
|
||||
processing->info_hash, processing->torrent_ptr));
|
||||
if (processing->torrent_ptr->is_seed()
|
||||
&& m_ses.m_alerts.should_post(alert::info))
|
||||
{
|
||||
m_ses.m_alerts.post_alert(torrent_finished_alert(
|
||||
processing->torrent_ptr->get_handle()
|
||||
, "torrent is complete"));
|
||||
}
|
||||
|
||||
peer_id id;
|
||||
std::fill(id.begin(), id.end(), 0);
|
||||
for (std::vector<tcp::endpoint>::const_iterator i = processing->peers.begin();
|
||||
peer_id id;
|
||||
std::fill(id.begin(), id.end(), 0);
|
||||
for (std::vector<tcp::endpoint>::const_iterator i = processing->peers.begin();
|
||||
i != processing->peers.end(); ++i)
|
||||
{
|
||||
processing->torrent_ptr->get_policy().peer_from_tracker(*i, id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
processing->torrent_ptr->get_policy().peer_from_tracker(*i, id);
|
||||
processing->torrent_ptr->abort();
|
||||
}
|
||||
processing.reset();
|
||||
m_processing.pop_front();
|
||||
|
@ -311,7 +339,7 @@ namespace libtorrent { namespace detail
|
|||
}
|
||||
}
|
||||
}
|
||||
catch(const std::exception& e)
|
||||
catch(std::exception const& e)
|
||||
{
|
||||
// This will happen if the storage fails to initialize
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
|
@ -326,12 +354,7 @@ namespace libtorrent { namespace detail
|
|||
}
|
||||
assert(!m_processing.empty());
|
||||
|
||||
if (processing->torrent_ptr->num_peers())
|
||||
{
|
||||
m_ses.m_torrents.insert(std::make_pair(
|
||||
processing->info_hash, processing->torrent_ptr));
|
||||
processing->torrent_ptr->abort();
|
||||
}
|
||||
processing->torrent_ptr->abort();
|
||||
|
||||
processing.reset();
|
||||
m_processing.pop_front();
|
||||
|
@ -604,6 +627,8 @@ namespace libtorrent { namespace detail
|
|||
mutex_t::scoped_lock l(m_mutex);
|
||||
assert(listen_socket.lock() == m_listen_socket);
|
||||
|
||||
if (m_abort) return;
|
||||
|
||||
async_accept();
|
||||
if (e)
|
||||
{
|
||||
|
@ -715,6 +740,7 @@ namespace libtorrent { namespace detail
|
|||
if (p->is_connecting())
|
||||
{
|
||||
assert(p->is_local());
|
||||
assert(m_connections.find(p->get_socket()) == m_connections.end());
|
||||
// Since this peer is still connecting, will not be
|
||||
// in the list of completed connections.
|
||||
connection_map::iterator i = m_half_open.find(p->get_socket());
|
||||
|
@ -725,6 +751,7 @@ namespace libtorrent { namespace detail
|
|||
connection_queue::iterator j = std::find(
|
||||
m_connection_queue.begin(), m_connection_queue.end(), p);
|
||||
|
||||
assert(j != m_connection_queue.end());
|
||||
if (j != m_connection_queue.end())
|
||||
m_connection_queue.erase(j);
|
||||
}
|
||||
|
@ -736,7 +763,11 @@ namespace libtorrent { namespace detail
|
|||
}
|
||||
else
|
||||
{
|
||||
assert(m_half_open.find(p->get_socket()) == m_half_open.end());
|
||||
assert(std::find(m_connection_queue.begin()
|
||||
, m_connection_queue.end(), p) == m_connection_queue.end());
|
||||
connection_map::iterator i = m_connections.find(p->get_socket());
|
||||
// assert (i != m_connections.end());
|
||||
if (i != m_connections.end())
|
||||
m_connections.erase(i);
|
||||
}
|
||||
|
@ -744,6 +775,8 @@ namespace libtorrent { namespace detail
|
|||
|
||||
void session_impl::second_tick(asio::error const& e) try
|
||||
{
|
||||
session_impl::mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
if (e)
|
||||
{
|
||||
#if defined(TORRENT_LOGGING)
|
||||
|
@ -754,8 +787,6 @@ namespace libtorrent { namespace detail
|
|||
return;
|
||||
}
|
||||
|
||||
session_impl::mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
if (m_abort) return;
|
||||
float tick_interval = (microsec_clock::universal_time()
|
||||
- m_last_tick).total_milliseconds() / 1000.f;
|
||||
|
@ -777,26 +808,27 @@ namespace libtorrent { namespace detail
|
|||
++i;
|
||||
// if this socket has timed out
|
||||
// close it.
|
||||
if (j->second->has_timed_out())
|
||||
peer_connection& c = *j->second;
|
||||
if (c.has_timed_out())
|
||||
{
|
||||
if (m_alerts.should_post(alert::debug))
|
||||
{
|
||||
m_alerts.post_alert(
|
||||
peer_error_alert(
|
||||
j->second->remote()
|
||||
, j->second->pid()
|
||||
c.remote()
|
||||
, c.pid()
|
||||
, "connection timed out"));
|
||||
}
|
||||
#if defined(TORRENT_VERBOSE_LOGGING)
|
||||
(*j->second->m_logger) << "*** CONNECTION TIMED OUT\n";
|
||||
(*c.m_logger) << "*** CONNECTION TIMED OUT\n";
|
||||
#endif
|
||||
|
||||
j->second->set_failed();
|
||||
j->second->disconnect();
|
||||
c.set_failed();
|
||||
c.disconnect();
|
||||
continue;
|
||||
}
|
||||
|
||||
j->second->keep_alive();
|
||||
c.keep_alive();
|
||||
}
|
||||
|
||||
// check each torrent for tracker updates
|
||||
|
@ -923,40 +955,55 @@ namespace libtorrent { namespace detail
|
|||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cerr << e.what() << "\n";
|
||||
#ifndef NDEBUG
|
||||
std::cerr << e.what() << "\n";
|
||||
std::string err = e.what();
|
||||
#endif
|
||||
assert(false);
|
||||
}
|
||||
|
||||
{
|
||||
session_impl::mutex_t::scoped_lock l(m_mutex);
|
||||
session_impl::mutex_t::scoped_lock l(m_mutex);
|
||||
|
||||
m_tracker_manager.abort_all_requests();
|
||||
for (std::map<sha1_hash, boost::shared_ptr<torrent> >::iterator i =
|
||||
m_torrents.begin(); i != m_torrents.end(); ++i)
|
||||
{
|
||||
i->second->abort();
|
||||
if (!i->second->is_paused() || i->second->should_request())
|
||||
m_tracker_manager.abort_all_requests();
|
||||
for (std::map<sha1_hash, boost::shared_ptr<torrent> >::iterator i =
|
||||
m_torrents.begin(); i != m_torrents.end(); ++i)
|
||||
{
|
||||
tracker_request req = i->second->generate_tracker_request();
|
||||
req.listen_port = m_listen_interface.port();
|
||||
req.key = m_key;
|
||||
std::string login = i->second->tracker_login();
|
||||
m_tracker_manager.queue_request(m_selector, req, login);
|
||||
i->second->abort();
|
||||
if (!i->second->is_paused() || i->second->should_request())
|
||||
{
|
||||
tracker_request req = i->second->generate_tracker_request();
|
||||
req.listen_port = m_listen_interface.port();
|
||||
req.key = m_key;
|
||||
std::string login = i->second->tracker_login();
|
||||
m_tracker_manager.queue_request(m_selector, req, login);
|
||||
}
|
||||
}
|
||||
}
|
||||
m_timer.expires_from_now(boost::posix_time::seconds(
|
||||
m_settings.stop_tracker_timeout));
|
||||
m_timer.async_wait(bind(&demuxer::interrupt, &m_selector));
|
||||
m_timer.expires_from_now(boost::posix_time::seconds(
|
||||
m_settings.stop_tracker_timeout));
|
||||
m_timer.async_wait(bind(&demuxer::interrupt, &m_selector));
|
||||
}
|
||||
|
||||
m_selector.reset();
|
||||
m_selector.run();
|
||||
|
||||
m_torrents.clear();
|
||||
session_impl::mutex_t::scoped_lock l(m_mutex);
|
||||
assert(m_abort);
|
||||
m_abort = true;
|
||||
|
||||
m_connections.clear();
|
||||
m_half_open.clear();
|
||||
m_connection_queue.clear();
|
||||
|
||||
#ifndef NDEBUG
|
||||
for (torrent_map::iterator i = m_torrents.begin();
|
||||
i != m_torrents.end(); ++i)
|
||||
{
|
||||
assert(i->second->num_peers() == 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
m_torrents.clear();
|
||||
|
||||
assert(m_torrents.empty());
|
||||
assert(m_connections.empty());
|
||||
|
@ -1263,6 +1310,9 @@ namespace libtorrent
|
|||
if (!m_impl.find_torrent(info_hash).expired())
|
||||
throw duplicate_torrent();
|
||||
|
||||
// you cannot add new torrents to a session that is closing down
|
||||
assert(!m_impl.m_abort);
|
||||
|
||||
// create the torrent and the data associated with
|
||||
// the checker thread and store it before starting
|
||||
// the thread
|
||||
|
@ -1407,6 +1457,14 @@ namespace libtorrent
|
|||
m_impl.m_abort = true;
|
||||
m_impl.m_selector.interrupt();
|
||||
}
|
||||
m_thread.join();
|
||||
|
||||
// it's important that the main thread is closed completely before
|
||||
// the checker thread is terminated. Because all the connections
|
||||
// have to be closed and removed from the torrents before they
|
||||
// can be destructed. (because the weak pointers in the
|
||||
// peer_connections will be invalidated when the torrents are
|
||||
// destructed and then the invariant will be broken).
|
||||
|
||||
{
|
||||
mutex::scoped_lock l(m_checker_impl.m_mutex);
|
||||
|
@ -1421,8 +1479,10 @@ namespace libtorrent
|
|||
m_checker_impl.m_cond.notify_one();
|
||||
}
|
||||
|
||||
m_thread.join();
|
||||
m_checker_thread.join();
|
||||
|
||||
assert(m_impl.m_torrents.empty());
|
||||
assert(m_impl.m_connections.empty());
|
||||
}
|
||||
|
||||
void session::set_max_uploads(int limit)
|
||||
|
|
|
@ -372,6 +372,17 @@ namespace libtorrent
|
|||
|
||||
torrent::~torrent()
|
||||
{
|
||||
// The invariant can't be maintained here, since the torrent
|
||||
// is being destructed, all weak references to it have been
|
||||
// reset, which means that all its peers already have an
|
||||
// invalidated torrent pointer (so it cannot be verified to be correct)
|
||||
|
||||
// i.e. the invariant can only be maintained if all connections have
|
||||
// been closed by the time the torrent is destructed. And they are
|
||||
// supposed to be closed. So we can still do the invariant check.
|
||||
|
||||
assert(m_connections.empty());
|
||||
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (m_ses.m_abort)
|
||||
|
@ -523,6 +534,8 @@ namespace libtorrent
|
|||
// been filtered as not wanted we have downloaded
|
||||
tuple<size_type, size_type> torrent::bytes_done() const
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
if (!valid_metadata()) return tuple<size_type, size_type>(0,0);
|
||||
|
||||
assert(m_picker.get());
|
||||
|
@ -796,6 +809,8 @@ namespace libtorrent
|
|||
|
||||
void torrent::filtered_pieces(std::vector<bool>& bitmask) const
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
// this call is only valid on torrents with metadata
|
||||
assert(m_picker.get());
|
||||
m_picker->filtered_pieces(bitmask);
|
||||
|
@ -803,6 +818,8 @@ namespace libtorrent
|
|||
|
||||
void torrent::filter_files(std::vector<bool> const& bitmask)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
// this call is only valid on torrents with metadata
|
||||
if (!valid_metadata()) return;
|
||||
|
||||
|
@ -970,6 +987,8 @@ namespace libtorrent
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_ses.m_abort) return;
|
||||
|
||||
tcp::endpoint a(host->endpoint().address(), port);
|
||||
|
||||
boost::shared_ptr<stream_socket> s(new stream_socket(m_ses.m_selector));
|
||||
|
@ -1073,6 +1092,10 @@ namespace libtorrent
|
|||
throw protocol_error("peer is not properly constructed");
|
||||
}
|
||||
|
||||
if (m_ses.m_abort)
|
||||
{
|
||||
throw protocol_error("session is closing");
|
||||
}
|
||||
|
||||
peer_iterator i = m_connections.insert(
|
||||
std::make_pair(p->remote(), p)).first;
|
||||
|
@ -1158,6 +1181,8 @@ namespace libtorrent
|
|||
// called when torrent is complete (all pieces downloaded)
|
||||
void torrent::completed()
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
/*
|
||||
if (alerts().should_post(alert::info))
|
||||
{
|
||||
|
@ -1177,6 +1202,8 @@ namespace libtorrent
|
|||
// the begining) and return the new index to the tracker.
|
||||
int torrent::prioritize_tracker(int index)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
assert(index >= 0);
|
||||
if (index >= (int)m_trackers.size()) return (int)m_trackers.size()-1;
|
||||
|
||||
|
@ -1294,6 +1321,8 @@ namespace libtorrent
|
|||
|
||||
bool torrent::move_storage(boost::filesystem::path const& save_path)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
bool ret = true;
|
||||
if (m_storage.get())
|
||||
{
|
||||
|
@ -1309,6 +1338,8 @@ namespace libtorrent
|
|||
|
||||
piece_manager& torrent::filesystem()
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
assert(m_storage.get());
|
||||
return *m_storage;
|
||||
}
|
||||
|
@ -1316,11 +1347,15 @@ namespace libtorrent
|
|||
|
||||
torrent_handle torrent::get_handle() const
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
return torrent_handle(&m_ses, 0, m_torrent_file.info_hash());
|
||||
}
|
||||
|
||||
session_settings const& torrent::settings() const
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
return m_ses.m_settings;
|
||||
}
|
||||
|
||||
|
@ -1331,7 +1366,12 @@ namespace libtorrent
|
|||
// size_type done = boost::get<0>(bytes_done());
|
||||
// assert(download >= done - m_initial_done);
|
||||
for (const_peer_iterator i = begin(); i != end(); ++i)
|
||||
assert(i->second->associated_torrent().lock().get() == this);
|
||||
{
|
||||
peer_connection const& p = *i->second;
|
||||
torrent* associated_torrent = p.associated_torrent().lock().get();
|
||||
if (associated_torrent != this)
|
||||
assert(false);
|
||||
}
|
||||
|
||||
// This check is very expensive.
|
||||
// assert(m_num_pieces
|
||||
|
@ -1857,6 +1897,8 @@ namespace libtorrent
|
|||
|
||||
std::pair<int, int> torrent::metadata_request()
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
// count the number of peers that supports the
|
||||
// extension and that has metadata
|
||||
int peers = 0;
|
||||
|
@ -1909,9 +1951,11 @@ namespace libtorrent
|
|||
|
||||
void torrent::cancel_metadata_request(std::pair<int, int> req)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
for (int i = req.first; i < req.first + req.second; ++i)
|
||||
{
|
||||
assert(m_requested_metadata[i] > 0);
|
||||
assert(m_requested_metadata[i] > 0);
|
||||
if (m_requested_metadata[i] > 0)
|
||||
--m_requested_metadata[i];
|
||||
}
|
||||
|
@ -1921,9 +1965,12 @@ namespace libtorrent
|
|||
tracker_request const&)
|
||||
{
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
INVARIANT_CHECK;
|
||||
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
debug_log("*** tracker timed out");
|
||||
#endif
|
||||
|
||||
if (m_ses.m_alerts.should_post(alert::warning))
|
||||
{
|
||||
std::stringstream s;
|
||||
|
@ -1942,6 +1989,8 @@ namespace libtorrent
|
|||
void torrent::tracker_request_error(tracker_request const&
|
||||
, int response_code, const std::string& str)
|
||||
{
|
||||
INVARIANT_CHECK;
|
||||
|
||||
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
|
||||
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||
debug_log(std::string("*** tracker error: ") + str);
|
||||
|
@ -1956,7 +2005,6 @@ namespace libtorrent
|
|||
, m_failed_trackers + 1, response_code, s.str()));
|
||||
}
|
||||
|
||||
|
||||
try_next_tracker();
|
||||
}
|
||||
|
||||
|
@ -1968,11 +2016,11 @@ namespace libtorrent
|
|||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void torrent::metadata_progress(int total_size, int received)
|
||||
{
|
||||
m_metadata_progress += received;
|
||||
m_metadata_size = total_size;
|
||||
void torrent::metadata_progress(int total_size, int received)
|
||||
{
|
||||
m_metadata_progress += received;
|
||||
m_metadata_size = total_size;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -460,17 +460,22 @@ namespace libtorrent
|
|||
ret["peers"] = entry::list_type();
|
||||
entry::list_type& peer_list = ret["peers"].list();
|
||||
|
||||
for (torrent::const_peer_iterator i = t->begin();
|
||||
i != t->end(); ++i)
|
||||
policy& pol = t->get_policy();
|
||||
|
||||
for (policy::iterator i = pol.begin_peer()
|
||||
, end(pol.end_peer()); i != end; ++i)
|
||||
{
|
||||
// we cannot save remote connection
|
||||
// since we don't know their listen port
|
||||
// TODO: iterate the peers in the policy
|
||||
// instead, since peers may be remote
|
||||
// but still connectable
|
||||
if (!i->second->is_local()) continue;
|
||||
// unless they gave us their listen port
|
||||
// through the extension handshake
|
||||
// so, if the peer is not connectable (i.e. we
|
||||
// don't know its listen port) or if it has
|
||||
// been banned, don't save it.
|
||||
if (i->type == policy::peer::not_connectable
|
||||
|| i->banned) continue;
|
||||
|
||||
tcp::endpoint ip = i->second->remote();
|
||||
tcp::endpoint ip = i->ip;
|
||||
entry peer(entry::dictionary_t);
|
||||
peer["ip"] = ip.address().to_string();
|
||||
peer["port"] = ip.port();
|
||||
|
@ -520,9 +525,18 @@ namespace libtorrent
|
|||
session_impl::mutex_t::scoped_lock l(m_ses->m_mutex);
|
||||
boost::shared_ptr<torrent> t = m_ses->find_torrent(m_info_hash).lock();
|
||||
|
||||
// TODO: if the torrent is being checked, put this peer in a queue and
|
||||
// connect it once the checking is done
|
||||
if (!t) throw_invalid_handle();
|
||||
if (!t)
|
||||
{
|
||||
// the torrent is being checked. Add the peer to its
|
||||
// peer list. The entries in there will be connected
|
||||
// once the checking is complete.
|
||||
mutex::scoped_lock l2(m_chk->m_mutex);
|
||||
|
||||
detail::piece_checker_data* d = m_chk->find_torrent(m_info_hash);
|
||||
if (d == 0) throw_invalid_handle();
|
||||
d->peers.push_back(adr);
|
||||
return;
|
||||
}
|
||||
|
||||
peer_id id;
|
||||
std::fill(id.begin(), id.end(), 0);
|
||||
|
|
|
@ -5,6 +5,7 @@ project
|
|||
requirements <threading>multi
|
||||
<library>/torrent
|
||||
<source>main.cpp
|
||||
<source>setup_transfer.cpp
|
||||
;
|
||||
|
||||
test-suite libtorrent :
|
||||
|
|
|
@ -19,10 +19,10 @@ test_storage_LDADD = $(top_builddir)/src/libtorrent.la
|
|||
test_buffer_SOURCES = main.cpp test_buffer.cpp
|
||||
test_buffer_LDADD = $(top_builddir)/src/libtorrent.la
|
||||
|
||||
test_metadata_extension_SOURCES = main.cpp test_metadata_extension.cpp
|
||||
test_metadata_extension_SOURCES = main.cpp setup_transfer.cpp test_metadata_extension.cpp
|
||||
test_metadata_extension_LDADD = $(top_builddir)/src/libtorrent.la
|
||||
|
||||
noinst_HEADERS = test.hpp
|
||||
noinst_HEADERS = test.hpp setup_transfer.hpp
|
||||
|
||||
AM_CXXFLAGS=-ftemplate-depth-50 -I$(top_srcdir)/include -I$(top_srcdir)/asio/include @DEBUGFLAGS@ @PTHREAD_CFLAGS@
|
||||
AM_LDFLAGS= -L./ -l@BOOST_DATE_TIME_LIB@ -l@BOOST_FILESYSTEM_LIB@ -l@BOOST_THREAD_LIB@ @PTHREAD_LIBS@
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
#include "libtorrent/session.hpp"
|
||||
#include "libtorrent/hasher.hpp"
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
#include "test.hpp"
|
||||
|
||||
void sleep(int msec)
|
||||
{
|
||||
boost::xtime xt;
|
||||
boost::xtime_get(&xt, boost::TIME_UTC);
|
||||
xt.nsec += msec * 1000000;
|
||||
boost::thread::sleep(xt);
|
||||
}
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
boost::tuple<torrent_handle, torrent_handle> setup_transfer(
|
||||
session& ses1, session& ses2, bool clear_files)
|
||||
{
|
||||
using namespace boost::filesystem;
|
||||
|
||||
char const* tracker_url = "http://non-existent-name.com/announce";
|
||||
|
||||
torrent_info t;
|
||||
t.add_file(path("temporary"), 42);
|
||||
t.set_piece_size(256 * 1024);
|
||||
t.add_tracker(tracker_url);
|
||||
|
||||
std::vector<char> piece(42);
|
||||
std::fill(piece.begin(), piece.end(), 0xfe);
|
||||
|
||||
// calculate the hash for all pieces
|
||||
int num = t.num_pieces();
|
||||
for (int i = 0; i < num; ++i)
|
||||
{
|
||||
t.set_hash(i, hasher(&piece[0], piece.size()).final());
|
||||
}
|
||||
|
||||
create_directory("./tmp1");
|
||||
std::ofstream file("./tmp1/temporary");
|
||||
file.write(&piece[0], piece.size());
|
||||
file.close();
|
||||
if (clear_files) remove_all("./tmp2/temporary");
|
||||
|
||||
t.create_torrent();
|
||||
|
||||
|
||||
ses1.set_severity_level(alert::debug);
|
||||
ses2.set_severity_level(alert::debug);
|
||||
|
||||
// they should not use the same save dir, because the
|
||||
// file pool will complain if two torrents are trying to
|
||||
// use the same files
|
||||
torrent_handle tor1 = ses1.add_torrent(t, "./tmp1");
|
||||
torrent_handle tor2 = ses2.add_torrent(tracker_url
|
||||
, t.info_hash(), "./tmp2");
|
||||
|
||||
std::cerr << "connecting peer\n";
|
||||
tor1.connect_peer(tcp::endpoint(address::from_string("127.0.0.1")
|
||||
, ses2.listen_port()));
|
||||
|
||||
return boost::make_tuple(tor1, tor2);
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef SETUP_TRANSFER_HPP
|
||||
#define SETUP_TRANSFER_HPP
|
||||
|
||||
#include "libtorrent/session.hpp"
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
|
||||
void sleep(int msec);
|
||||
boost::tuple<libtorrent::torrent_handle, libtorrent::torrent_handle>
|
||||
setup_transfer(libtorrent::session& ses1, libtorrent::session& ses2
|
||||
, bool clear_files);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,54 +1,27 @@
|
|||
#include "libtorrent/session.hpp"
|
||||
#include "libtorrent/hasher.hpp"
|
||||
#include <boost/thread.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
#include "test.hpp"
|
||||
#include "setup_transfer.hpp"
|
||||
|
||||
void sleep(int msec)
|
||||
{
|
||||
boost::xtime xt;
|
||||
boost::xtime_get(&xt, boost::TIME_UTC);
|
||||
xt.nsec += msec * 1000000;
|
||||
boost::thread::sleep(xt);
|
||||
}
|
||||
|
||||
void test_transfer(char const* tracker_url, libtorrent::torrent_info const& t)
|
||||
void test_transfer(bool clear_files = true, bool disconnect = false)
|
||||
{
|
||||
using namespace libtorrent;
|
||||
|
||||
session ses1;
|
||||
ses1.set_severity_level(alert::debug);
|
||||
session ses2(fingerprint("LT", 0, 1, 0, 0), std::make_pair(49000, 50000));
|
||||
ses2.set_severity_level(alert::debug);
|
||||
torrent_handle tor1;
|
||||
torrent_handle tor2;
|
||||
|
||||
// they should not use the same save dir, because the
|
||||
// file pool will complain if two torrents are trying to
|
||||
// use the same files
|
||||
torrent_handle tor1 = ses1.add_torrent(t, "./tmp1");
|
||||
torrent_handle tor2 = ses2.add_torrent(tracker_url
|
||||
, t.info_hash(), "./tmp2");
|
||||
|
||||
std::cerr << "waiting for file check to complete\n";
|
||||
|
||||
// wait for 5 seconds or until the torrent is in a state
|
||||
// were it can accept connections
|
||||
for (int i = 0; i < 50; ++i)
|
||||
{
|
||||
torrent_status st = tor1.status();
|
||||
if (st.state != torrent_status::queued_for_checking
|
||||
&&st.state != torrent_status::checking_files)
|
||||
break;
|
||||
sleep(100);
|
||||
}
|
||||
|
||||
std::cerr << "connecting peer\n";
|
||||
tor1.connect_peer(tcp::endpoint(address::from_string("127.0.0.1"), ses2.listen_port()));
|
||||
boost::tie(tor1, tor2) = setup_transfer(ses1, ses2, clear_files);
|
||||
|
||||
for (int i = 0; i < 50; ++i)
|
||||
{
|
||||
// make sure this function can be called on
|
||||
// torrents without metadata
|
||||
tor2.status();
|
||||
if (!disconnect) tor2.status();
|
||||
std::auto_ptr<alert> a;
|
||||
a = ses1.pop_alert();
|
||||
if (a.get())
|
||||
|
@ -58,12 +31,15 @@ void test_transfer(char const* tracker_url, libtorrent::torrent_info const& t)
|
|||
if (a.get())
|
||||
std::cerr << "ses2: " << a->msg() << "\n";
|
||||
|
||||
if (tor2.has_metadata()) break;
|
||||
if (disconnect && tor2.is_valid()) ses2.remove_torrent(tor2);
|
||||
if (!disconnect && tor2.has_metadata()) break;
|
||||
sleep(100);
|
||||
}
|
||||
|
||||
if (disconnect) return;
|
||||
|
||||
TEST_CHECK(tor2.has_metadata());
|
||||
std::cerr << "metadata received. waiting for transfer to complete\n";
|
||||
std::cerr << "waiting for transfer to complete\n";
|
||||
|
||||
for (int i = 0; i < 50; ++i)
|
||||
{
|
||||
|
@ -73,44 +49,21 @@ void test_transfer(char const* tracker_url, libtorrent::torrent_info const& t)
|
|||
}
|
||||
|
||||
TEST_CHECK(tor2.is_seed());
|
||||
std::cerr << "done\n";
|
||||
if (tor2.is_seed()) std::cerr << "done\n";
|
||||
}
|
||||
|
||||
int test_main()
|
||||
{
|
||||
using namespace libtorrent;
|
||||
using namespace boost::filesystem;
|
||||
|
||||
char const* tracker_url = "http://non-existant-name.com/announce";
|
||||
|
||||
torrent_info t;
|
||||
t.add_file(path("temporary"), 42);
|
||||
t.set_piece_size(256 * 1024);
|
||||
t.add_tracker(tracker_url);
|
||||
|
||||
std::vector<char> piece(42);
|
||||
std::fill(piece.begin(), piece.end(), 0xfe);
|
||||
|
||||
// calculate the hash for all pieces
|
||||
int num = t.num_pieces();
|
||||
for (int i = 0; i < num; ++i)
|
||||
{
|
||||
t.set_hash(i, hasher(&piece[0], piece.size()).final());
|
||||
}
|
||||
|
||||
create_directory("./tmp1");
|
||||
std::ofstream file("./tmp1/temporary");
|
||||
file.write(&piece[0], piece.size());
|
||||
file.close();
|
||||
remove_all("./tmp2/temporary");
|
||||
|
||||
t.create_torrent();
|
||||
// test to disconnect one client prematurely
|
||||
test_transfer(true, true);
|
||||
|
||||
// test where one has data and one doesn't
|
||||
test_transfer(tracker_url, t);
|
||||
test_transfer(true);
|
||||
|
||||
// test where both have data (to trigger the file check)
|
||||
test_transfer(tracker_url, t);
|
||||
test_transfer(false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue