fixed race condition in peer_connection, fixed assert in torrent destructor, updated tests

This commit is contained in:
Arvid Norberg 2006-05-28 19:03:54 +00:00
parent 58698d6aea
commit 94628fa78d
20 changed files with 521 additions and 322 deletions

View File

@ -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

View File

@ -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 \

View File

@ -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&amp; print = libtorrent::fingerprint(&quot;LT&quot;, 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&lt;char&gt; const&amp; 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()

View File

@ -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
-----------------------

View File

@ -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)
{

View File

@ -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 \

View File

@ -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:

View File

@ -178,6 +178,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:
@ -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);

View File

@ -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; }

View File

@ -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

View File

@ -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)
{

View File

@ -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());

View File

@ -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)
@ -753,9 +786,7 @@ namespace libtorrent { namespace detail
m_selector.interrupt();
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)

View File

@ -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;
@ -950,7 +967,7 @@ namespace libtorrent
detail::session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
INVARIANT_CHECK;
std::set<std::string>::iterator i = m_resolving_web_seeds.find(url);
if (i != m_resolving_web_seeds.end()) m_resolving_web_seeds.erase(i);
@ -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,7 +1092,11 @@ 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;
}
}

View File

@ -459,18 +459,23 @@ namespace libtorrent
ret["peers"] = entry::list_type();
entry::list_type& peer_list = ret["peers"].list();
policy& pol = t->get_policy();
for (torrent::const_peer_iterator i = t->begin();
i != t->end(); ++i)
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);

View File

@ -5,6 +5,7 @@ project
requirements <threading>multi
<library>/torrent
<source>main.cpp
<source>setup_transfer.cpp
;
test-suite libtorrent :

View File

@ -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@

65
test/setup_transfer.cpp Normal file
View File

@ -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);
}

14
test/setup_transfer.hpp Normal file
View File

@ -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

View File

@ -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);
// 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");
torrent_handle tor1;
torrent_handle tor2;
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;
}