From 55ed312b76421e1e8f17c21fcc4b7411a1079ace Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Tue, 6 Aug 2013 02:50:57 +0000 Subject: [PATCH] move torrent_handle documentation into header file --- docs/gen_reference_doc.py | 11 +- docs/makefile | 3 +- docs/manual.rst | 1176 ----------------------- include/libtorrent/session_settings.hpp | 2 +- include/libtorrent/torrent_handle.hpp | 620 +++++++++++- 5 files changed, 612 insertions(+), 1200 deletions(-) diff --git a/docs/gen_reference_doc.py b/docs/gen_reference_doc.py index 8c5195823..8e79108ac 100644 --- a/docs/gen_reference_doc.py +++ b/docs/gen_reference_doc.py @@ -63,6 +63,12 @@ category_mapping = { 'identify_client.hpp': 'Utility', 'thread.hpp': 'Utility', 'ip_filter.hpp': 'Filter', + 'session_settings.hpp': 'Settings', +} + +category_fun_mapping = { + 'min_memory_usage()': 'Settings', + 'high_performance_seed()': 'Settings', } def categorize_symbol(name, filename): @@ -75,6 +81,9 @@ def categorize_symbol(name, filename): or name.endswith('error_code_enum'): return 'Error Codes' + if name in category_fun_mapping: + return category_fun_mapping[name] + return 'Core' def first_item(itr): @@ -624,7 +633,7 @@ def linkify_symbols(string): w = w[:-1] if w in symbols: - words[i] = (leading_tabs * '\t') + print_link(words[i].strip(), symbols[w]) + trailing + words[i] = (leading_tabs * '\t') + print_link(w, symbols[w]) + trailing ret.append(' '.join(words)) return '\n'.join(ret) diff --git a/docs/makefile b/docs/makefile index d86384c7b..90ac29768 100644 --- a/docs/makefile +++ b/docs/makefile @@ -16,7 +16,8 @@ REFERENCE_TARGETS = \ reference-Bencoding \ reference-Alerts \ reference-RSS \ - reference-Filter + reference-Filter \ + reference-Settings TARGETS = index \ udp_tracker_protocol \ diff --git a/docs/manual.rst b/docs/manual.rst index 68cf927e0..595075f24 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -93,1182 +93,6 @@ For documentation on these types, please refer to the `asio documentation`_. .. _`asio documentation`: http://asio.sourceforge.net/asio-0.3.8/doc/asio/reference.html -torrent_handle -============== - -You will usually have to store your torrent handles somewhere, since it's the -object through which you retrieve information about the torrent and aborts the torrent. - -.. warning:: - Any member function that returns a value or fills in a value has to - be made synchronously. This means it has to wait for the main thread - to complete the query before it can return. This might potentially be - expensive if done from within a GUI thread that needs to stay responsive. - Try to avoid quering for information you don't need, and try to do it - in as few calls as possible. You can get most of the interesting information - about a torrent from the ``torrent_handle::status()`` call. - -Its declaration looks like this:: - - struct torrent_handle - { - torrent_handle(); - - enum status_flags_t - { - query_distributed_copies = 1, - query_accurate_download_counters = 2, - query_last_seen_complete = 4, - query_pieces = 8, - query_verified_pieces = 16, - query_torrent_file = 32, - query_name = 64, - query_save_path = 128, - }; - - torrent_status status(boost::uint32_t flags = 0xffffffff); - void file_progress(std::vector& fp, int flags = 0); - void get_download_queue(std::vector& queue) const; - void get_peer_info(std::vector& v) const; - boost::intrusive_ptr torrent_file() const; - bool is_valid() const; - - enum save_resume_flags_t { flush_disk_cache = 1, save_info_dict = 2 }; - void save_resume_data(int flags = 0) const; - bool need_save_resume_data() const; - void force_reannounce() const; - void force_dht_announce() const; - void force_reannounce(boost::posix_time::time_duration) const; - void scrape_tracker() const; - void connect_peer(asio::ip::tcp::endpoint const& adr, int source = 0) const; - - void set_tracker_login(std::string const& username - , std::string const& password) const; - - std::vector trackers() const; - void replace_trackers(std::vector const&); - void add_tracker(announce_entry const& url); - - void add_url_seed(std::string const& url); - void remove_url_seed(std::string const& url); - std::set url_seeds() const; - - void add_http_seed(std::string const& url); - void remove_http_seed(std::string const& url); - std::set http_seeds() const; - - int max_uploads() const; - void set_max_uploads(int max_uploads) const; - void set_max_connections(int max_connections) const; - int max_connections() const; - void set_upload_limit(int limit) const; - int upload_limit() const; - void set_download_limit(int limit) const; - int download_limit() const; - void set_sequential_download(bool sd) const; - bool is_sequential_download() const; - - int queue_position() const; - void queue_position_up() const; - void queue_position_down() const; - void queue_position_top() const; - void queue_position_bottom() const; - - void set_priority(int prio) const; - - void use_interface(char const* net_interface) const; - - enum pause_flags_t { graceful_pause = 1 }; - void pause(int flags = 0) const; - void resume() const; - bool is_seed() const; - void force_recheck() const; - void clear_error() const; - void set_upload_mode(bool m) const; - void set_share_mode(bool m) const; - - void apply_ip_filter(bool b) const; - - void flush_cache() const; - - void resolve_countries(bool r); - bool resolve_countries() const; - - enum deadline_flags { alert_when_available = 1 }; - void set_piece_deadline(int index, int deadline, int flags = 0) const; - void reset_piece_deadline(int index) const; - - void piece_availability(std::vector& avail) const; - void piece_priority(int index, int priority) const; - int piece_priority(int index) const; - void prioritize_pieces(std::vector const& pieces) const; - std::vector piece_priorities() const; - - void file_priority(int index, int priority) const; - int file_priority(int index) const; - void prioritize_files(std::vector const& files) const; - std::vector file_priorities() const; - - void auto_managed(bool m) const; - - bool set_metadata(char const* buf, int size) const; - - void move_storage(std::string const& save_path, int flags = 0) const; - void move_storage(std::wstring const& save_path, int flags = 0) const; - void rename_file(int index, std::string) const; - void rename_file(int index, std::wstring) const; - storage_interface* get_storage_impl() const; - - void super_seeding(bool on) const; - - enum flags_t { overwrite_existing = 1 }; - void add_piece(int piece, char const* data, int flags = 0) const; - void read_piece(int piece) const; - bool have_piece(int piece) const; - - sha1_hash info_hash() const; - - void set_ssl_certificate(std::string const& cert - , std::string const& private_key - , std::string const& dh_params - , std::string const& passphrase = ""); - - bool operator==(torrent_handle const&) const; - bool operator!=(torrent_handle const&) const; - bool operator<(torrent_handle const&) const; - - boost::shared_ptr native_handle() const; - }; - -The default constructor will initialize the handle to an invalid state. Which -means you cannot perform any operation on it, unless you first assign it a -valid handle. If you try to perform any operation on an uninitialized handle, -it will throw ``invalid_handle``. - -.. warning:: All operations on a ``torrent_handle`` may throw libtorrent_exception_ - exception, in case the handle is no longer refering to a torrent. There is - one exception ``is_valid()`` will never throw. - Since the torrents are processed by a background thread, there is no - guarantee that a handle will remain valid between two calls. - -set_piece_deadline() reset_piece_deadline() -------------------------------------------- - - :: - - enum deadline_flags { alert_when_available = 1 }; - void set_piece_deadline(int index, int deadline, int flags = 0) const; - void reset_piece_deadline(int index) const; - -This function sets or resets the deadline associated with a specific piece -index (``index``). libtorrent will attempt to download this entire piece before -the deadline expires. This is not necessarily possible, but pieces with a more -recent deadline will always be prioritized over pieces with a deadline further -ahead in time. The deadline (and flags) of a piece can be changed by calling this -function again. - -The ``flags`` parameter can be used to ask libtorrent to send an alert once the -piece has been downloaded, by passing ``alert_when_available``. When set, the -read_piece_alert_ alert will be delivered, with the piece data, when it's downloaded. - -If the piece is already downloaded when this call is made, nothing happens, unless -the ``alert_when_available`` flag is set, in which case it will do the same thing -as calling `read_piece()`_ for ``index``. - -``deadline`` is the number of milliseconds until this piece should be completed. - -``reset_piece_deadline`` removes the deadline from the piece. If it hasn't already -been downloaded, it will no longer be considered a priority. - -piece_availability() --------------------- - - :: - - void piece_availability(std::vector& avail) const; - -Fills the specified ``std::vector`` with the availability for each -piece in this torrent. libtorrent does not keep track of availability for -seeds, so if the torrent is seeding the availability for all pieces is -reported as 0. - -The piece availability is the number of peers that we are connected that has -advertized having a particular piece. This is the information that libtorrent -uses in order to prefer picking rare pieces. - - -piece_priority() prioritize_pieces() piece_priorities() -------------------------------------------------------- - - :: - - void piece_priority(int index, int priority) const; - int piece_priority(int index) const; - void prioritize_pieces(std::vector const& pieces) const; - std::vector piece_priorities() const; - -These functions are used to set and get the prioritiy of individual pieces. -By default all pieces have priority 1. That means that the random rarest -first algorithm is effectively active for all pieces. You may however -change the priority of individual pieces. There are 8 different priority -levels: - - 0. piece is not downloaded at all - 1. normal priority. Download order is dependent on availability - 2. higher than normal priority. Pieces are preferred over pieces with - the same availability, but not over pieces with lower availability - 3. pieces are as likely to be picked as partial pieces. - 4. pieces are preferred over partial pieces, but not over pieces with - lower availability - 5. *currently the same as 4* - 6. piece is as likely to be picked as any piece with availability 1 - 7. maximum priority, availability is disregarded, the piece is preferred - over any other piece with lower priority - -The exact definitions of these priorities are implementation details, and -subject to change. The interface guarantees that higher number means higher -priority, and that 0 means do not download. - -``piece_priority`` sets or gets the priority for an individual piece, -specified by ``index``. - -``prioritize_pieces`` takes a vector of integers, one integer per piece in -the torrent. All the piece priorities will be updated with the priorities -in the vector. - -``piece_priorities`` returns a vector with one element for each piece in the -torrent. Each element is the current priority of that piece. - - -file_priority() prioritize_files() file_priorities() ----------------------------------------------------- - - :: - - void file_priority(int index, int priority) const; - int file_priority(int index) const; - void prioritize_files(std::vector const& files) const; - std::vector file_priorities() const; - -``index`` must be in the range [0, number_of_files). - -``file_priority`` queries or sets the priority of file ``index``. - -``prioritize_files`` takes a vector that has at as many elements as there are -files in the torrent. Each entry is the priority of that file. The function -sets the priorities of all the pieces in the torrent based on the vector. - -``file_priorities`` returns a vector with the priorities of all files. - -The priority values are the same as for ``piece_priority``. - -Whenever a file priority is changed, all other piece priorities are reset -to match the file priorities. In order to maintain sepcial priorities for -particular pieces, ``piece_priority`` has to be called again for those pieces. - -You cannot set the file priorities on a torrent that does not yet -have metadata or a torrent that is a seed. ``file_priority(int, int)`` and -``prioritize_files()`` are both no-ops for such torrents. - -file_progress() ---------------- - - :: - - void file_progress(std::vector& fp, int flags = 0); - -This function fills in the supplied vector with the the number of bytes downloaded -of each file in this torrent. The progress values are ordered the same as the files -in the `torrent_info`_. This operation is not very cheap. Its complexity is *O(n + mj)*. -Where *n* is the number of files, *m* is the number of downloading pieces and *j* -is the number of blocks in a piece. - -The ``flags`` parameter can be used to specify the granularity of the file progress. If -left at the default value of 0, the progress will be as accurate as possible, but also -more expensive to calculate. If ``torrent_handle::piece_granularity`` is specified, -the progress will be specified in piece granularity. i.e. only pieces that have been -fully downloaded and passed the hash check count. When specifying piece granularity, -the operation is a lot cheaper, since libtorrent already keeps track of this internally -and no calculation is required. - - -move_storage() --------------- - - :: - - void move_storage(std::string const& save_path, int flags = 0) const; - void move_storage(std::wstring const& save_path, int flags = 0) const; - -Moves the file(s) that this torrent are currently seeding from or downloading to. If -the given ``save_path`` is not located on the same drive as the original save path, -the files will be copied to the new drive and removed from their original location. -This will block all other disk IO, and other torrents download and upload rates may -drop while copying the file. - -Since disk IO is performed in a separate thread, this operation is also asynchronous. -Once the operation completes, the ``storage_moved_alert`` is generated, with the new -path as the message. If the move fails for some reason, ``storage_moved_failed_alert`` -is generated instead, containing the error message. - -The ``flags`` argument determines the behavior of the copying/moving of the files -in the torrent. They are defined in ``include/libtorrent/storage.hpp``: - - * ``always_replace_files`` = 0 - * ``fail_if_exist`` = 1 - * ``dont_replace`` = 2 - -``always_replace_files`` is the default and replaces any file that exist in both the -source directory and the target directory. - -``fail_if_exist`` first check to see that none of the copy operations would cause an -overwrite. If it would, it will fail. Otherwise it will proceed as if it was in -``always_replace_files`` mode. Note that there is an inherent race condition here. -If the files in the target directory appear after the check but before the copy -or move completes, they will be overwritten. When failing because of files already -existing in the target path, the ``error`` of ``move_storage_failed_alert`` is set -to ``boost::system::errc::file_exists``. - -The intention is that a client may use this as a probe, and if it fails, ask the user -which mode to use. The client may then re-issue the ``move_storage`` call with one -of the other modes. - -``dont_replace`` always takes the existing file in the target directory, if there is -one. The source files will still be removed in that case. - -Files that have been renamed to have absolute pahts are not moved by this function. -Keep in mind that files that don't belong to the torrent but are stored in the torrent's -directory may be moved as well. This goes for files that have been renamed to -absolute paths that still end up inside the save path. - -rename_file() -------------- - - :: - - void rename_file(int index, std::string) const; - void rename_file(int index, std::wstring) const; - -Renames the file with the given index asynchronously. The rename operation is complete -when either a ``file_renamed_alert`` or ``file_rename_failed_alert`` is posted. - -get_storage_impl() ------------------- - - :: - - storage_interface* get_storage_impl() const; - -Returns the storage implementation for this torrent. This depends on the -storage contructor function that was passed to ``session::add_torrent``. - -super_seeding() ---------------- - - :: - - void super_seeding(bool on) const; - -Enables or disabled super seeding/initial seeding for this torrent. The torrent -needs to be a seed for this to take effect. - -add_piece() ------------ - - :: - - enum flags_t { overwrite_existing = 1 }; - void add_piece(int piece, char const* data, int flags = 0) const; - -This function will write ``data`` to the storage as piece ``piece``, as if it had -been downloaded from a peer. ``data`` is expected to point to a buffer of as many -bytes as the size of the specified piece. The data in the buffer is copied and -passed on to the disk IO thread to be written at a later point. - -By default, data that's already been downloaded is not overwritten by this buffer. If -you trust this data to be correct (and pass the piece hash check) you may pass the -``overwrite_existing`` flag. This will instruct libtorrent to overwrite any data that -may already have been downloaded with this data. - -Since the data is written asynchronously, you may know that is passed or failed the -hash check by waiting for ``piece_finished_alert`` or ``has_failed_alert``. - -read_piece() ------------- - - :: - - void read_piece(int piece) const; - -This function starts an asynchronous read operation of the specified piece from -this torrent. You must have completed the download of the specified piece before -calling this function. - -When the read operation is completed, it is passed back through an alert, -read_piece_alert_. Since this alert is a reponse to an explicit call, it will -always be posted, regardless of the alert mask. - -Note that if you read multiple pieces, the read operations are not guaranteed to -finish in the same order as you initiated them. - -have_piece() ------------- - - :: - - bool have_piece(int piece) const; - -Returns true if this piece has been completely downloaded, and false otherwise. - -force_reannounce() force_dht_announce() ---------------------------------------- - - :: - - void force_reannounce() const; - void force_reannounce(boost::posix_time::time_duration) const; - void force_dht_announce() const; - -``force_reannounce()`` will force this torrent to do another tracker request, to receive new -peers. The second overload of ``force_reannounce`` that takes a ``time_duration`` as -argument will schedule a reannounce in that amount of time from now. - -If the tracker's ``min_interval`` has not passed since the last announce, the forced -announce will be scheduled to happen immediately as the ``min_interval`` expires. This is -to honor trackers minimum re-announce interval settings. - -``force_dht_announce`` will announce the torrent to the DHT immediately. - -scrape_tracker() ----------------- - - :: - - void scrape_tracker() const; - -``scrape_tracker()`` will send a scrape request to the tracker. A scrape request queries the -tracker for statistics such as total number of incomplete peers, complete peers, number of -downloads etc. - -This request will specifically update the ``num_complete`` and ``num_incomplete`` fields in -the torrent_status_ struct once it completes. When it completes, it will generate a -scrape_reply_alert_. If it fails, it will generate a scrape_failed_alert_. - -connect_peer() --------------- - - :: - - void connect_peer(asio::ip::tcp::endpoint const& adr, int source = 0) const; - -``connect_peer()`` is a way to manually connect to peers that one believe is a part of the -torrent. If the peer does not respond, or is not a member of this torrent, it will simply -be disconnected. No harm can be done by using this other than an unnecessary connection -attempt is made. If the torrent is uninitialized or in queued or checking mode, this -will throw libtorrent_exception_. The second (optional) argument will be bitwised ORed into -the source mask of this peer. Typically this is one of the source flags in peer_info_. -i.e. ``tracker``, ``pex``, ``dht`` etc. - - - -set_upload_limit() set_download_limit() upload_limit() download_limit() ------------------------------------------------------------------------ - - :: - - void set_upload_limit(int limit) const; - void set_download_limit(int limit) const; - int upload_limit() const; - int download_limit() const; - -``set_upload_limit`` will limit the upload bandwidth used by this particular torrent to the -limit you set. It is given as the number of bytes per second the torrent is allowed to upload. -``set_download_limit`` works the same way but for download bandwidth instead of upload bandwidth. -Note that setting a higher limit on a torrent then the global limit (``session_settings::upload_rate_limit``) -will not override the global rate limit. The torrent can never upload more than the global rate -limit. - -``upload_limit`` and ``download_limit`` will return the current limit setting, for upload and -download, respectively. - - -set_sequential_download() -------------------------- - - :: - - void set_sequential_download(bool sd); - -``set_sequential_download()`` enables or disables *sequential download*. When enabled, the piece -picker will pick pieces in sequence instead of rarest first. - -Enabling sequential download will affect the piece distribution negatively in the swarm. It should be -used sparingly. - -pause() resume() ----------------- - - :: - - enum pause_flags_t { graceful_pause = 1 }; - void pause(int flags) const; - void resume() const; - -``pause()``, and ``resume()`` will disconnect all peers and reconnect all peers respectively. -When a torrent is paused, it will however remember all share ratios to all peers and remember -all potential (not connected) peers. Torrents may be paused automatically if there is a file -error (e.g. disk full) or something similar. See file_error_alert_. - -To know if a torrent is paused or not, call ``torrent_handle::status()`` and inspect -``torrent_status::paused``. - -The ``flags`` argument to pause can be set to ``torrent_handle::graceful_pause`` which will -delay the disconnect of peers that we're still downloading outstanding requests from. The torrent -will not accept any more requests and will disconnect all idle peers. As soon as a peer is -done transferring the blocks that were requested from it, it is disconnected. This is a graceful -shut down of the torrent in the sense that no downloaded bytes are wasted. - -torrents that are auto-managed may be automatically resumed again. It does not make sense to -pause an auto-managed torrent without making it not automanaged first. Torrents are auto-managed -by default when added to the session. For more information, see queuing_. - -flush_cache() -------------- - - :: - - void flush_cache() const; - -Instructs libtorrent to flush all the disk caches for this torrent and close all -file handles. This is done asynchronously and you will be notified that it's complete -through cache_flushed_alert_. - -Note that by the time you get the alert, libtorrent may have cached more data for the -torrent, but you are guaranteed that whatever cached data libtorrent had by the time -you called ``torrent_handle::flush_cache()`` has been written to disk. - -force_recheck() ---------------- - - :: - - void force_recheck() const; - -``force_recheck`` puts the torrent back in a state where it assumes to have no resume data. -All peers will be disconnected and the torrent will stop announcing to the tracker. The torrent -will be added to the checking queue, and will be checked (all the files will be read and -compared to the piece hashes). Once the check is complete, the torrent will start connecting -to peers again, as normal. - -clear_error() -------------- - - :: - - void clear_error() const; - -If the torrent is in an error state (i.e. ``torrent_status::error`` is non-empty), this -will clear the error and start the torrent again. - -set_upload_mode() ------------------ - -:: - - void set_upload_mode(bool m) const; - -Explicitly sets the upload mode of the torrent. In upload mode, the torrent will not -request any pieces. If the torrent is auto managed, it will automatically be taken out -of upload mode periodically (see ``session_settings::optimistic_disk_retry``). Torrents -are automatically put in upload mode whenever they encounter a disk write error. - -``m`` should be true to enter upload mode, and false to leave it. - -To test if a torrent is in upload mode, call ``torrent_handle::status()`` and inspect -``torrent_status::upload_mode``. - -set_share_mode() ----------------- - - :: - - void set_share_mode(bool m) const; - -Enable or disable share mode for this torrent. When in share mode, the torrent will -not necessarily be downloaded, especially not the whole of it. Only parts that are likely -to be distributed to more than 2 other peers are downloaded, and only if the previous -prediction was correct. - -apply_ip_filter() ------------------ - -:: - - void apply_ip_filter(bool b) const; - -Set to true to apply the session global IP filter to this torrent (which is the -default). Set to false to make this torrent ignore the IP filter. - -resolve_countries() -------------------- - - :: - - void resolve_countries(bool r); - bool resolve_countries() const; - -Sets or gets the flag that derermines if countries should be resolved for the peers of this -torrent. It defaults to false. If it is set to true, the peer_info_ structure for the peers -in this torrent will have their ``country`` member set. See peer_info_ for more information -on how to interpret this field. - -is_seed() ---------- - - :: - - bool is_seed() const; - -Returns true if the torrent is in seed mode (i.e. if it has finished downloading). - -auto_managed() --------------- - - :: - - void auto_managed(bool m) const; - -``auto_managed()`` changes whether the torrent is auto managed or not. For more info, -see queuing_. - -set_metadata() --------------- - - :: - - bool set_metadata(char const* buf, int size) const; - -``set_metadata`` expects the *info* section of metadata. i.e. The buffer passed in will be -hashed and verified against the info-hash. If it fails, a ``metadata_failed_alert`` will be -generated. If it passes, a ``metadata_received_alert`` is generated. The function returns -true if the metadata is successfully set on the torrent, and false otherwise. If the torrent -already has metadata, this function will not affect the torrent, and false will be returned. - - -set_tracker_login() -------------------- - - :: - - void set_tracker_login(std::string const& username - , std::string const& password) const; - -``set_tracker_login()`` sets a username and password that will be sent along in the HTTP-request -of the tracker announce. Set this if the tracker requires authorization. - - -trackers() replace_trackers() add_tracker() -------------------------------------------- - - :: - - std::vector trackers() const; - void replace_trackers(std::vector const&) const; - void add_tracker(announc_entry const& url); - -``trackers()`` will return the list of trackers for this torrent. The -announce entry contains both a string ``url`` which specify the announce url -for the tracker as well as an int ``tier``, which is specifies the order in -which this tracker is tried. If you want libtorrent to use another list of -trackers for this torrent, you can use ``replace_trackers()`` which takes -a list of the same form as the one returned from ``trackers()`` and will -replace it. If you want an immediate effect, you have to call -`force_reannounce() force_dht_announce()`_. See `trackers()`_ for the definition of ``announce_entry``. - -``add_tracker()`` will look if the specified tracker is already in the set. -If it is, it doesn't do anything. If it's not in the current set of trackers, -it will insert it in the tier specified in the announce_entry. - -The updated set of trackers will be saved in the resume data, and when a torrent -is started with resume data, the trackers from the resume data will replace the -original ones. - - -add_url_seed() remove_url_seed() url_seeds() --------------------------------------------- - - :: - - void add_url_seed(std::string const& url); - void remove_url_seed(std::string const& url); - std::set url_seeds() const; - -``add_url_seed()`` adds another url to the torrent's list of url seeds. If the -given url already exists in that list, the call has no effect. The torrent -will connect to the server and try to download pieces from it, unless it's -paused, queued, checking or seeding. ``remove_url_seed()`` removes the given -url if it exists already. ``url_seeds()`` return a set of the url seeds -currently in this torrent. Note that urls that fails may be removed -automatically from the list. - -See `HTTP seeding`_ for more information. - -add_http_seed() remove_http_seed() http_seeds() ------------------------------------------------ - - :: - - void add_http_seed(std::string const& url); - void remove_http_seed(std::string const& url); - std::set http_seeds() const; - -These functions are identical as the ``*_url_seed()`` variants, but they -operate on BEP 17 web seeds instead of BEP 19. - -See `HTTP seeding`_ for more information. - -queue_position() queue_position_up() queue_position_down() queue_position_top() queue_position_bottom() -------------------------------------------------------------------------------------------------------- - - :: - - int queue_position() const; - void queue_position_up() const; - void queue_position_down() const; - void queue_position_top() const; - void queue_position_bottom() const; - -Every torrent that is added is assigned a queue position exactly one greater than -the greatest queue position of all existing torrents. Torrents that are being -seeded have -1 as their queue position, since they're no longer in line to be downloaded. - -When a torrent is removed or turns into a seed, all torrents with greater queue positions -have their positions decreased to fill in the space in the sequence. - -``queue_position()`` returns the torrent's position in the download queue. The torrents -with the smallest numbers are the ones that are being downloaded. The smaller number, -the closer the torrent is to the front of the line to be started. - -The queue position is also available in the ``torrent_status``. - -The ``queue_position_*()`` functions adjust the torrents position in the queue. Up means -closer to the front and down means closer to the back of the queue. Top and bottom refers -to the front and the back of the queue respectively. - -set_priority() --------------- - - :: - - void set_priority(int prio) const; - -This sets the bandwidth priority of this torrent. The priority of a torrent determines -how much bandwidth its peers are assigned when distributing upload and download rate quotas. -A high number gives more bandwidth. The priority must be within the range [0, 255]. - -The default priority is 0, which is the lowest priority. - -To query the priority of a torrent, use the ``torrent_handle::status()`` call. - -Torrents with higher priority will not nececcarily get as much bandwidth as they can -consume, even if there's is more quota. Other peers will still be weighed in when -bandwidth is being distributed. With other words, bandwidth is not distributed strictly -in order of priority, but the priority is used as a weight. - -Peers whose Torrent has a higher priority will take precedence when distributing unchoke slots. -This is a strict prioritization where every interested peer on a high priority torrent will -be unchoked before any other, lower priority, torrents have any peers unchoked. - -use_interface() ---------------- - - :: - - void use_interface(char const* net_interface) const; - -``use_interface()`` sets the network interface this torrent will use when it opens outgoing -connections. By default, it uses the same interface as the session_ uses to listen on. The -parameter must be a string containing one or more, comma separated, ip-address (either an -IPv4 or IPv6 address). When specifying multiple interfaces, the torrent will round-robin -which interface to use for each outgoing conneciton. This is useful for clients that are -multi-homed. - - -info_hash() ------------ - - :: - - sha1_hash info_hash() const; - -``info_hash()`` returns the info-hash for the torrent. - - -set_max_uploads() max_uploads() -------------------------------- - - :: - - void set_max_uploads(int max_uploads) const; - int max_uploads() const; - -``set_max_uploads()`` sets the maximum number of peers that's unchoked at the same time on this -torrent. If you set this to -1, there will be no limit. This defaults to infinite. The primary -setting controlling this is the global unchoke slots limit, set by ``unchoke_slots_limit`` -in session_settings_. - -``max_uploads()`` returns the current settings. - - -set_max_connections() max_connections() ---------------------------------------- - - :: - - void set_max_connections(int max_connections) const; - int max_connections() const; - -``set_max_connections()`` sets the maximum number of connection this torrent will open. If all -connections are used up, incoming connections may be refused or poor connections may be closed. -This must be at least 2. The default is unlimited number of connections. If -1 is given to the -function, it means unlimited. There is also a global limit of the number of connections, set -by ``connections_limit`` in session_settings_. - -``max_connections()`` returns the current settings. - - -save_resume_data() ------------------- - - :: - - enum save_resume_flags_t { flush_disk_cache = 1, save_info_dict = 2 }; - void save_resume_data(int flags = 0) const; - -``save_resume_data()`` generates fast-resume data and returns it as an entry_. This entry_ -is suitable for being bencoded. For more information about how fast-resume works, see `fast resume`_. - -The ``flags`` argument is a bitmask of flags ORed together. If the flag ``torrent_handle::flush_cache`` -is set, the disk cache will be flushed before creating the resume data. This avoids a problem with -file timestamps in the resume data in case the cache hasn't been flushed yet. - -If the flag ``torrent_handle::save_info_dict`` is set, the resume data will contain the metadata -from the torrent file as well. This is default for any torrent that's added without a torrent -file (such as a magnet link or a URL). - -This operation is asynchronous, ``save_resume_data`` will return immediately. The resume data -is delivered when it's done through an `save_resume_data_alert`_. - -The fast resume data will be empty in the following cases: - - 1. The torrent handle is invalid. - 2. The torrent is checking (or is queued for checking) its storage, it will obviously - not be ready to write resume data. - 3. The torrent hasn't received valid metadata and was started without metadata - (see libtorrent's `metadata from peers`_ extension) - -Note that by the time you receive the fast resume data, it may already be invalid if the torrent -is still downloading! The recommended practice is to first pause the session, then generate the -fast resume data, and then close it down. Make sure to not `remove_torrent()`_ before you receive -the `save_resume_data_alert`_ though. There's no need to pause when saving intermittent resume data. - -.. warning:: If you pause every torrent individually instead of pausing the session, every torrent - will have its paused state saved in the resume data! - -.. warning:: The resume data contains the modification timestamps for all files. If one file has - been modified when the torrent is added again, the will be rechecked. When shutting down, make - sure to flush the disk cache before saving the resume data. This will make sure that the file - timestamps are up to date and won't be modified after saving the resume data. The recommended way - to do this is to pause the torrent, which will flush the cache and disconnect all peers. - -.. note:: It is typically a good idea to save resume data whenever a torrent is completed or paused. In those - cases you don't need to pause the torrent or the session, since the torrent will do no more writing - to its files. If you save resume data for torrents when they are paused, you can accelerate the - shutdown process by not saving resume data again for paused torrents. Completed torrents should - have their resume data saved when they complete and on exit, since their statistics might be updated. - - In full allocation mode the reume data is never invalidated by subsequent - writes to the files, since pieces won't move around. This means that you don't need to - pause before writing resume data in full or sparse mode. If you don't, however, any data written to - disk after you saved resume data and before the session_ closed is lost. - -It also means that if the resume data is out dated, libtorrent will not re-check the files, but assume -that it is fairly recent. The assumption is that it's better to loose a little bit than to re-check -the entire file. - -It is still a good idea to save resume data periodically during download as well as when -closing down. - -Example code to pause and save resume data for all torrents and wait for the alerts:: - - extern int outstanding_resume_data; // global counter of outstanding resume data - std::vector handles = ses.get_torrents(); - ses.pause(); - for (std::vector::iterator i = handles.begin(); - i != handles.end(); ++i) - { - torrent_handle& h = *i; - if (!h.is_valid()) continue; - torrent_status s = h.status(); - if (!s.has_metadata) continue; - if (!s.need_save_resume_data()) continue; - - h.save_resume_data(); - ++outstanding_resume_data; - } - - while (outstanding_resume_data > 0) - { - alert const* a = ses.wait_for_alert(seconds(10)); - - // if we don't get an alert within 10 seconds, abort - if (a == 0) break; - - std::auto_ptr holder = ses.pop_alert(); - - if (alert_cast(a)) - { - process_alert(a); - --outstanding_resume_data; - continue; - } - - save_resume_data_alert const* rd = alert_cast(a); - if (rd == 0) - { - process_alert(a); - continue; - } - - torrent_handle h = rd->handle; - torrent_status st = h.status(torrent_handle::query_save_path | torrent_handle::query_name); - std::ofstream out((st.save_path - + "/" + st.name + ".fastresume").c_str() - , std::ios_base::binary); - out.unsetf(std::ios_base::skipws); - bencode(std::ostream_iterator(out), *rd->resume_data); - --outstanding_resume_data; - } - -.. note:: Note how ``outstanding_resume_data`` is a global counter in this example. - This is deliberate, otherwise there is a race condition for torrents that - was just asked to save their resume data, they posted the alert, but it has - not been received yet. Those torrents would report that they don't need to - save resume data again, and skipped by the initial loop, and thwart the counter - otherwise. - - -need_save_resume_data() ------------------------ - - :: - - bool need_save_resume_data() const; - -This function returns true if any whole chunk has been downloaded since the -torrent was first loaded or since the last time the resume data was saved. When -saving resume data periodically, it makes sense to skip any torrent which hasn't -downloaded anything since the last time. - -.. note:: A torrent's resume data is considered saved as soon as the alert - is posted. It is important to make sure this alert is received and handled - in order for this function to be meaningful. - - -status() --------- - - :: - - torrent_status status(boost::uint32_t flags = 0xffffffff) const; - -``status()`` will return a structure with information about the status of this -torrent. If the torrent_handle_ is invalid, it will throw libtorrent_exception_ exception. -See torrent_status_. The ``flags`` argument filters what information is returned -in the torrent_status. Some information in there is relatively expensive to calculate, and -if you're not interested in it (and see performance issues), you can filter them out. - -By default everything is included. The flags you can use to decide what to *include* are: - -* ``query_distributed_copies`` - calculates ``distributed_copies``, ``distributed_full_copies`` and ``distributed_fraction``. - -* ``query_accurate_download_counters`` - includes partial downloaded blocks in ``total_done`` and ``total_wanted_done``. - -* ``query_last_seen_complete`` - includes ``last_seen_complete``. - -* ``query_pieces`` - includes ``pieces``. - -* ``query_verified_pieces`` - includes ``verified_pieces`` (only applies to torrents in *seed mode*). - -* ``query_torrent_file`` - includes ``torrent_file``, which is all the static information from the .torrent file. - -* ``query_name`` - includes ``name``, the name of the torrent. This is either derived from the .torrent - file, or from the ``&dn=`` magnet link argument or possibly some other source. If the - name of the torrent is not known, this is an empty string. - -* ``query_save_path`` - includes ``save_path``, the path to the directory the files of the torrent are saved to. - -get_download_queue() --------------------- - - :: - - void get_download_queue(std::vector& queue) const; - -``get_download_queue()`` takes a non-const reference to a vector which it will fill with -information about pieces that are partially downloaded or not downloaded at all but partially -requested. The entry in the vector (``partial_piece_info``) looks like this:: - - struct partial_piece_info - { - int piece_index; - int blocks_in_piece; - enum state_t { none, slow, medium, fast }; - state_t piece_state; - block_info* blocks; - }; - -``piece_index`` is the index of the piece in question. ``blocks_in_piece`` is the -number of blocks in this particular piece. This number will be the same for most pieces, but -the last piece may have fewer blocks than the standard pieces. - -``piece_state`` is set to either ``fast``, ``medium``, ``slow`` or ``none``. It tells which -download rate category the peers downloading this piece falls into. ``none`` means that no -peer is currently downloading any part of the piece. Peers prefer picking pieces from -the same category as themselves. The reason for this is to keep the number of partially -downloaded pieces down. Pieces set to ``none`` can be converted into any of ``fast``, -``medium`` or ``slow`` as soon as a peer want to download from it. - -:: - - struct block_info - { - enum block_state_t - { none, requested, writing, finished }; - - void set_peer(tcp::endpoint const& ep); - tcp::endpoint peer() const; - - unsigned bytes_progress:15; - unsigned block_size:15; - unsigned state:2; - unsigned num_peers:14; - }; - - -The ``blocks`` field points to an array of ``blocks_in_piece`` elements. This pointer is -only valid until the next call to ``get_download_queue()`` for any torrent in the same session. -They all share the storaga for the block arrays in their session object. - -The ``block_info`` array contains data for each individual block in the piece. Each block has -a state (``state``) which is any of: - -* ``none`` - This block has not been downloaded or requested form any peer. -* ``requested`` - The block has been requested, but not completely downloaded yet. -* ``writing`` - The block has been downloaded and is currently queued for being written to disk. -* ``finished`` - The block has been written to disk. - -The ``peer`` field is the ip address of the peer this block was downloaded from. -``num_peers`` is the number of peers that is currently requesting this block. Typically this -is 0 or 1, but at the end of the torrent blocks may be requested by more peers in parallel to -speed things up. -``bytes_progress`` is the number of bytes that have been received for this block, and -``block_size`` is the total number of bytes in this block. - -get_peer_info() ---------------- - - :: - - void get_peer_info(std::vector&) const; - -``get_peer_info()`` takes a reference to a vector that will be cleared and filled -with one entry for each peer connected to this torrent, given the handle is valid. If the -torrent_handle_ is invalid, it will throw libtorrent_exception_ exception. Each entry in -the vector contains information about that particular peer. See peer_info_. - - -torrent_file() --------------- - - :: - - boost::intrusive_ptr torrent_file() const; - -Returns a pointer to the torrent_info_ object associated with this torrent. The -``torrent_info`` object is a copy of the internal object. If the torrent doesn't -have metadata, the object being returned will not be fully filled in. -The torrent may be in a state without metadata only if -it was started without a .torrent file, e.g. by using the libtorrent extension of -just supplying a tracker and info-hash. - - -is_valid() ----------- - - :: - - bool is_valid() const; - -Returns true if this handle refers to a valid torrent and false if it hasn't been initialized -or if the torrent it refers to has been aborted. Note that a handle may become invalid after -it has been added to the session. Usually this is because the storage for the torrent is -somehow invalid or if the filenames are not allowed (and hence cannot be opened/created) on -your filesystem. If such an error occurs, a file_error_alert_ is generated and all handles -that refers to that torrent will become invalid. - -set_ssl_certificate() ---------------------- - - :: - - void set_ssl_certificate(std::string const& cert, std::string const& private_key - , std::string const& dh_params, std::string const& passphrase = ""); - -For SSL torrents, use this to specify a path to a .pem file to use as this client's certificate. -The certificate must be signed by the certificate in the .torrent file to be valid. - -``cert`` is a path to the (signed) certificate in .pem format corresponding to this torrent. - -``private_key`` is a path to the private key for the specified certificate. This must be in .pem -format. - -``dh_params`` is a path to the Diffie-Hellman parameter file, which needs to be in .pem format. -You can generate this file using the openssl command like this: -``openssl dhparam -outform PEM -out dhparams.pem 512``. - -``passphrase`` may be specified if the private key is encrypted and requires a passphrase to -be decrypted. - -Note that when a torrent first starts up, and it needs a certificate, it will suspend connecting -to any peers until it has one. It's typically desirable to resume the torrent after setting the -ssl certificate. - -If you receive a torrent_need_cert_alert_, you need to call this to provide a valid cert. If you -don't have a cert you won't be allowed to connect to any peers. - -native_handle() ---------------- - - :: - - boost::shared_ptr native_handle() const; - -This function is intended only for use by plugins and the alert dispatch function. Any code -that runs in libtorrent's network thread may not use the public API of ``torrent_handle``. -Doing so results in a dead-lock. For such routines, the ``native_handle`` gives access to the -underlying type representing the torrent. This type does not have a stable API and should -be relied on as little as possible. - - torrent_status ============== diff --git a/include/libtorrent/session_settings.hpp b/include/libtorrent/session_settings.hpp index ad8778868..95aea987d 100644 --- a/include/libtorrent/session_settings.hpp +++ b/include/libtorrent/session_settings.hpp @@ -94,7 +94,7 @@ namespace libtorrent struct TORRENT_EXPORT session_settings { - session_settings(std::string const& user_agent_ = "libtorrent/" + session_settings(std::string const& user_agent = "libtorrent/" LIBTORRENT_VERSION); ~session_settings(); diff --git a/include/libtorrent/torrent_handle.hpp b/include/libtorrent/torrent_handle.hpp index 0c917d1fb..969136377 100644 --- a/include/libtorrent/torrent_handle.hpp +++ b/include/libtorrent/torrent_handle.hpp @@ -81,10 +81,21 @@ namespace libtorrent void throw_invalid_handle(); #endif + // holds the state of a block in a piece. Who we requested + // it from and how far along we are at downloading it. struct TORRENT_EXPORT block_info { enum block_state_t - { none, requested, writing, finished }; + { + // This block has not been downloaded or requested form any peer. + none, + // The block has been requested, but not completely downloaded yet. + requested, + // The block has been downloaded and is currently queued for being written to disk. + writing, + // The block has been written to disk. + finished + }; private: TORRENT_UNION addr_t @@ -98,6 +109,7 @@ namespace libtorrent boost::uint16_t port; public: + // The peer is the ip address of the peer this block was downloaded from. void set_peer(tcp::endpoint const& ep) { #if TORRENT_USE_IPV6 @@ -109,7 +121,6 @@ namespace libtorrent addr.v4 = ep.address().to_v4().to_bytes(); port = ep.port(); } - tcp::endpoint peer() const { #if TORRENT_USE_IPV6 @@ -120,18 +131,18 @@ namespace libtorrent return tcp::endpoint(address_v4(addr.v4), port); } - // number of bytes downloaded in this block + // the number of bytes that have been received for this block unsigned bytes_progress:15; - // the total number of bytes in this block + // the total number of bytes in this block. unsigned block_size:15; // the state this block is in (see block_state_t) unsigned state:2; - // the number of peers that has requested this block - // typically 0 or 1. If > 1, this block is in - // end game mode + // the number of peers that is currently requesting this block. Typically this + // is 0 or 1, but at the end of the torrent blocks may be requested by more peers in parallel to + // speed things up. unsigned num_peers:14; private: #if TORRENT_USE_IPV6 @@ -142,7 +153,11 @@ namespace libtorrent struct TORRENT_EXPORT partial_piece_info { + // the index of the piece in question. ``blocks_in_piece`` is the + // number of blocks in this particular piece. This number will be the same for most pieces, but + // the last piece may have fewer blocks than the standard pieces. int piece_index; + int blocks_in_piece; // the number of blocks in the finished state int finished; @@ -150,11 +165,53 @@ namespace libtorrent int writing; // the number of blocks in the requested state int requested; + + // this is an array of ``blocks_in_piece`` number of + // items. One for each block in the piece. + // + // .. warning:: This is a pointer that points to an array + // that's owned by the session object. The next time + // get_download_queue() is called, it will be invalidated. block_info* blocks; + enum state_t { none, slow, medium, fast }; + + // the download speed class this piece falls into. + // this is used internally to cluster peers of the same + // speed class together when requesting blocks. + // + // set to either ``fast``, ``medium``, ``slow`` or ``none``. It tells which + // download rate category the peers downloading this piece falls into. ``none`` means that no + // peer is currently downloading any part of the piece. Peers prefer picking pieces from + // the same category as themselves. The reason for this is to keep the number of partially + // downloaded pieces down. Pieces set to ``none`` can be converted into any of ``fast``, + // ``medium`` or ``slow`` as soon as a peer want to download from it. state_t piece_state; }; + // You will usually have to store your torrent handles somewhere, since it's the + // object through which you retrieve information about the torrent and aborts the torrent. + // + // .. warning:: + // Any member function that returns a value or fills in a value has to + // be made synchronously. This means it has to wait for the main thread + // to complete the query before it can return. This might potentially be + // expensive if done from within a GUI thread that needs to stay responsive. + // Try to avoid quering for information you don't need, and try to do it + // in as few calls as possible. You can get most of the interesting information + // about a torrent from the ``torrent_handle::status()`` call. + // + // The default constructor will initialize the handle to an invalid state. Which + // means you cannot perform any operation on it, unless you first assign it a + // valid handle. If you try to perform any operation on an uninitialized handle, + // it will throw ``invalid_handle``. + // + // .. warning:: All operations on a torrent_handle may throw libtorrent_exception + // exception, in case the handle is no longer refering to a torrent. There is + // one exception is_valid() will never throw. + // Since the torrents are processed by a background thread, there is no + // guarantee that a handle will remain valid between two calls. + // struct TORRENT_EXPORT torrent_handle { friend class invariant_access; @@ -165,35 +222,125 @@ namespace libtorrent torrent_handle() {} + // flags for add_piece(). enum flags_t { overwrite_existing = 1 }; + + // This function will write ``data`` to the storage as piece ``piece``, as if it had + // been downloaded from a peer. ``data`` is expected to point to a buffer of as many + // bytes as the size of the specified piece. The data in the buffer is copied and + // passed on to the disk IO thread to be written at a later point. + // + // By default, data that's already been downloaded is not overwritten by this buffer. If + // you trust this data to be correct (and pass the piece hash check) you may pass the + // overwrite_existing flag. This will instruct libtorrent to overwrite any data that + // may already have been downloaded with this data. + // + // Since the data is written asynchronously, you may know that is passed or failed the + // hash check by waiting for piece_finished_alert or hash_failed_alert. void add_piece(int piece, char const* data, int flags = 0) const; + + // This function starts an asynchronous read operation of the specified piece from + // this torrent. You must have completed the download of the specified piece before + // calling this function. + // + // When the read operation is completed, it is passed back through an alert, + // read_piece_alert_. Since this alert is a reponse to an explicit call, it will + // always be posted, regardless of the alert mask. + // + // Note that if you read multiple pieces, the read operations are not guaranteed to + // finish in the same order as you initiated them. void read_piece(int piece) const; + + // Returns true if this piece has been completely downloaded, and false otherwise. bool have_piece(int piece) const; void get_full_peer_list(std::vector& v) const; + + // takes a reference to a vector that will be cleared and filled + // with one entry for each peer connected to this torrent, given the handle is valid. If the + // torrent_handle_ is invalid, it will throw libtorrent_exception exception. Each entry in + // the vector contains information about that particular peer. See peer_info. void get_peer_info(std::vector& v) const; enum status_flags_t { + // calculates ``distributed_copies``, ``distributed_full_copies`` and ``distributed_fraction``. query_distributed_copies = 1, + // includes partial downloaded blocks in ``total_done`` and ``total_wanted_done``. query_accurate_download_counters = 2, + // includes ``last_seen_complete``. query_last_seen_complete = 4, + // includes ``pieces``. query_pieces = 8, + // includes ``verified_pieces`` (only applies to torrents in *seed mode*). query_verified_pieces = 16, + // includes ``torrent_file``, which is all the static information from the .torrent file. query_torrent_file = 32, + // includes ``name``, the name of the torrent. This is either derived from the .torrent + // file, or from the ``&dn=`` magnet link argument or possibly some other source. If the + // name of the torrent is not known, this is an empty string. query_name = 64, + // includes ``save_path``, the path to the directory the files of the torrent are saved to. query_save_path = 128, }; - // the flags specify which fields are calculated. By default everything - // is included, you may save CPU by not querying fields you don't need + // ``status()`` will return a structure with information about the status of this + // torrent. If the torrent_handle_ is invalid, it will throw libtorrent_exception_ exception. + // See torrent_status_. The ``flags`` argument filters what information is returned + // in the torrent_status. Some information in there is relatively expensive to calculate, and + // if you're not interested in it (and see performance issues), you can filter them out. + // + // By default everything is included. The flags you can use to decide what to *include* are + // defined in the status_flags_t enum. torrent_status status(boost::uint32_t flags = 0xffffffff) const; + + // ``get_download_queue()`` takes a non-const reference to a vector which it will fill with + // information about pieces that are partially downloaded or not downloaded at all but partially + // requested. See partial_piece_info for the fields in the returned vector. void get_download_queue(std::vector& queue) const; + // flags for set_piece_deadline(). enum deadline_flags { alert_when_available = 1 }; + + // This function sets or resets the deadline associated with a specific piece + // index (``index``). libtorrent will attempt to download this entire piece before + // the deadline expires. This is not necessarily possible, but pieces with a more + // recent deadline will always be prioritized over pieces with a deadline further + // ahead in time. The deadline (and flags) of a piece can be changed by calling this + // function again. + // + // The ``flags`` parameter can be used to ask libtorrent to send an alert once the + // piece has been downloaded, by passing alert_when_available. When set, the + // read_piece_alert_ alert will be delivered, with the piece data, when it's downloaded. + // + // If the piece is already downloaded when this call is made, nothing happens, unless + // the alert_when_available flag is set, in which case it will do the same thing + // as calling read_piece() for ``index``. + // + // ``deadline`` is the number of milliseconds until this piece should be completed. + // + // ``reset_piece_deadline`` removes the deadline from the piece. If it hasn't already + // been downloaded, it will no longer be considered a priority. + // void set_piece_deadline(int index, int deadline, int flags = 0) const; void reset_piece_deadline(int index) const; + // This sets the bandwidth priority of this torrent. The priority of a torrent determines + // how much bandwidth its peers are assigned when distributing upload and download rate quotas. + // A high number gives more bandwidth. The priority must be within the range [0, 255]. + // + // The default priority is 0, which is the lowest priority. + // + // To query the priority of a torrent, use the ``torrent_handle::status()`` call. + // + // Torrents with higher priority will not nececcarily get as much bandwidth as they can + // consume, even if there's is more quota. Other peers will still be weighed in when + // bandwidth is being distributed. With other words, bandwidth is not distributed strictly + // in order of priority, but the priority is used as a weight. + // + // Peers whose Torrent has a higher priority will take precedence when distributing unchoke slots. + // This is a strict prioritization where every interested peer on a high priority torrent will + // be unchoked before any other, lower priority, torrents have any peers unchoked. void set_priority(int prio) const; #ifndef TORRENT_NO_DEPRECATE @@ -210,18 +357,62 @@ namespace libtorrent piece_granularity = 1 }; + // This function fills in the supplied vector with the the number of bytes downloaded + // of each file in this torrent. The progress values are ordered the same as the files + // in the `torrent_info`_. This operation is not very cheap. Its complexity is *O(n + mj)*. + // Where *n* is the number of files, *m* is the number of downloading pieces and *j* + // is the number of blocks in a piece. + // + // The ``flags`` parameter can be used to specify the granularity of the file progress. If + // left at the default value of 0, the progress will be as accurate as possible, but also + // more expensive to calculate. If ``torrent_handle::piece_granularity`` is specified, + // the progress will be specified in piece granularity. i.e. only pieces that have been + // fully downloaded and passed the hash check count. When specifying piece granularity, + // the operation is a lot cheaper, since libtorrent already keeps track of this internally + // and no calculation is required. void file_progress(std::vector& progress, int flags = 0) const; + // If the torrent is in an error state (i.e. ``torrent_status::error`` is non-empty), this + // will clear the error and start the torrent again. void clear_error() const; + // ``trackers()`` will return the list of trackers for this torrent. The + // announce entry contains both a string ``url`` which specify the announce url + // for the tracker as well as an int ``tier``, which is specifies the order in + // which this tracker is tried. If you want libtorrent to use another list of + // trackers for this torrent, you can use ``replace_trackers()`` which takes + // a list of the same form as the one returned from ``trackers()`` and will + // replace it. If you want an immediate effect, you have to call + // force_reannounce(). See announce_entry. + // + // ``add_tracker()`` will look if the specified tracker is already in the set. + // If it is, it doesn't do anything. If it's not in the current set of trackers, + // it will insert it in the tier specified in the announce_entry. + // + // The updated set of trackers will be saved in the resume data, and when a torrent + // is started with resume data, the trackers from the resume data will replace the + // original ones. std::vector trackers() const; void replace_trackers(std::vector const&) const; void add_tracker(announce_entry const&) const; + // ``add_url_seed()`` adds another url to the torrent's list of url seeds. If the + // given url already exists in that list, the call has no effect. The torrent + // will connect to the server and try to download pieces from it, unless it's + // paused, queued, checking or seeding. ``remove_url_seed()`` removes the given + // url if it exists already. ``url_seeds()`` return a set of the url seeds + // currently in this torrent. Note that urls that fails may be removed + // automatically from the list. + // + // See `HTTP seeding`_ for more information. void add_url_seed(std::string const& url) const; void remove_url_seed(std::string const& url) const; std::set url_seeds() const; + // These functions are identical as the ``*_url_seed()`` variants, but they + // operate on BEP 17 web seeds instead of BEP 19. + // + // See `HTTP seeding`_ for more information. void add_http_seed(std::string const& url) const; void remove_http_seed(std::string const& url) const; std::set http_seeds() const; @@ -229,43 +420,275 @@ namespace libtorrent void add_extension(boost::function(torrent*, void*)> const& ext , void* userdata = 0); + // ``set_metadata`` expects the *info* section of metadata. i.e. The buffer passed in will be + // hashed and verified against the info-hash. If it fails, a ``metadata_failed_alert`` will be + // generated. If it passes, a ``metadata_received_alert`` is generated. The function returns + // true if the metadata is successfully set on the torrent, and false otherwise. If the torrent + // already has metadata, this function will not affect the torrent, and false will be returned. bool set_metadata(char const* metadata, int size) const; + // Returns true if this handle refers to a valid torrent and false if it hasn't been initialized + // or if the torrent it refers to has been aborted. Note that a handle may become invalid after + // it has been added to the session. Usually this is because the storage for the torrent is + // somehow invalid or if the filenames are not allowed (and hence cannot be opened/created) on + // your filesystem. If such an error occurs, a file_error_alert_ is generated and all handles + // that refers to that torrent will become invalid. bool is_valid() const; + // flags for pause() enum pause_flags_t { graceful_pause = 1 }; + + // ``pause()``, and ``resume()`` will disconnect all peers and reconnect all peers respectively. + // When a torrent is paused, it will however remember all share ratios to all peers and remember + // all potential (not connected) peers. Torrents may be paused automatically if there is a file + // error (e.g. disk full) or something similar. See file_error_alert_. + // + // To know if a torrent is paused or not, call ``torrent_handle::status()`` and inspect + // ``torrent_status::paused``. + // + // The ``flags`` argument to pause can be set to ``torrent_handle::graceful_pause`` which will + // delay the disconnect of peers that we're still downloading outstanding requests from. The torrent + // will not accept any more requests and will disconnect all idle peers. As soon as a peer is + // done transferring the blocks that were requested from it, it is disconnected. This is a graceful + // shut down of the torrent in the sense that no downloaded bytes are wasted. + // + // torrents that are auto-managed may be automatically resumed again. It does not make sense to + // pause an auto-managed torrent without making it not automanaged first. Torrents are auto-managed + // by default when added to the session. For more information, see queuing_. void pause(int flags = 0) const; void resume() const; + + // Explicitly sets the upload mode of the torrent. In upload mode, the torrent will not + // request any pieces. If the torrent is auto managed, it will automatically be taken out + // of upload mode periodically (see ``session_settings::optimistic_disk_retry``). Torrents + // are automatically put in upload mode whenever they encounter a disk write error. + // + // ``m`` should be true to enter upload mode, and false to leave it. + // + // To test if a torrent is in upload mode, call ``torrent_handle::status()`` and inspect + // ``torrent_status::upload_mode``. void set_upload_mode(bool b) const; + + // Enable or disable share mode for this torrent. When in share mode, the torrent will + // not necessarily be downloaded, especially not the whole of it. Only parts that are likely + // to be distributed to more than 2 other peers are downloaded, and only if the previous + // prediction was correct. void set_share_mode(bool b) const; + + // Instructs libtorrent to flush all the disk caches for this torrent and close all + // file handles. This is done asynchronously and you will be notified that it's complete + // through cache_flushed_alert_. + // + // Note that by the time you get the alert, libtorrent may have cached more data for the + // torrent, but you are guaranteed that whatever cached data libtorrent had by the time + // you called ``torrent_handle::flush_cache()`` has been written to disk. void flush_cache() const; + // Set to true to apply the session global IP filter to this torrent (which is the + // default). Set to false to make this torrent ignore the IP filter. void apply_ip_filter(bool b) const; + // ``force_recheck`` puts the torrent back in a state where it assumes to have no resume data. + // All peers will be disconnected and the torrent will stop announcing to the tracker. The torrent + // will be added to the checking queue, and will be checked (all the files will be read and + // compared to the piece hashes). Once the check is complete, the torrent will start connecting + // to peers again, as normal. void force_recheck() const; enum save_resume_flags_t { flush_disk_cache = 1, save_info_dict = 2 }; + + // ``save_resume_data()`` generates fast-resume data and returns it as an entry_. This entry_ + // is suitable for being bencoded. For more information about how fast-resume works, see `fast resume`_. + // + // The ``flags`` argument is a bitmask of flags ORed together. If the flag ``torrent_handle::flush_cache`` + // is set, the disk cache will be flushed before creating the resume data. This avoids a problem with + // file timestamps in the resume data in case the cache hasn't been flushed yet. + // + // If the flag ``torrent_handle::save_info_dict`` is set, the resume data will contain the metadata + // from the torrent file as well. This is default for any torrent that's added without a torrent + // file (such as a magnet link or a URL). + // + // This operation is asynchronous, ``save_resume_data`` will return immediately. The resume data + // is delivered when it's done through an save_resume_data_alert. + // + // The fast resume data will be empty in the following cases: + // + // 1. The torrent handle is invalid. + // 2. The torrent is checking (or is queued for checking) its storage, it will obviously + // not be ready to write resume data. + // 3. The torrent hasn't received valid metadata and was started without metadata + // (see libtorrent's `metadata from peers`_ extension) + // + // Note that by the time you receive the fast resume data, it may already be invalid if the torrent + // is still downloading! The recommended practice is to first pause the session, then generate the + // fast resume data, and then close it down. Make sure to not remove_torrent() before you receive + // the save_resume_data_alert though. There's no need to pause when saving intermittent resume data. + // + //.. warning:: If you pause every torrent individually instead of pausing the session, every torrent + // will have its paused state saved in the resume data! + // + //.. warning:: The resume data contains the modification timestamps for all files. If one file has + // been modified when the torrent is added again, the will be rechecked. When shutting down, make + // sure to flush the disk cache before saving the resume data. This will make sure that the file + // timestamps are up to date and won't be modified after saving the resume data. The recommended way + // to do this is to pause the torrent, which will flush the cache and disconnect all peers. + // + //.. note:: It is typically a good idea to save resume data whenever a torrent is completed or paused. In those + // cases you don't need to pause the torrent or the session, since the torrent will do no more writing + // to its files. If you save resume data for torrents when they are paused, you can accelerate the + // shutdown process by not saving resume data again for paused torrents. Completed torrents should + // have their resume data saved when they complete and on exit, since their statistics might be updated. + // + // In full allocation mode the reume data is never invalidated by subsequent + // writes to the files, since pieces won't move around. This means that you don't need to + // pause before writing resume data in full or sparse mode. If you don't, however, any data written to + // disk after you saved resume data and before the session_ closed is lost. + // + // It also means that if the resume data is out dated, libtorrent will not re-check the files, but assume + // that it is fairly recent. The assumption is that it's better to loose a little bit than to re-check + // the entire file. + // + // It is still a good idea to save resume data periodically during download as well as when + // closing down. + // + // Example code to pause and save resume data for all torrents and wait for the alerts:: + // + // extern int outstanding_resume_data; // global counter of outstanding resume data + // std::vector handles = ses.get_torrents(); + // ses.pause(); + // for (std::vector::iterator i = handles.begin(); + // i != handles.end(); ++i) + // { + // torrent_handle& h = *i; + // if (!h.is_valid()) continue; + // torrent_status s = h.status(); + // if (!s.has_metadata) continue; + // if (!s.need_save_resume_data()) continue; + // + // h.save_resume_data(); + // ++outstanding_resume_data; + // } + // + // while (outstanding_resume_data > 0) + // { + // alert const* a = ses.wait_for_alert(seconds(10)); + // + // // if we don't get an alert within 10 seconds, abort + // if (a == 0) break; + // + // std::auto_ptr holder = ses.pop_alert(); + // + // if (alert_cast(a)) + // { + // process_alert(a); + // --outstanding_resume_data; + // continue; + // } + // + // save_resume_data_alert const* rd = alert_cast(a); + // if (rd == 0) + // { + // process_alert(a); + // continue; + // } + // + // torrent_handle h = rd->handle; + // torrent_status st = h.status(torrent_handle::query_save_path | torrent_handle::query_name); + // std::ofstream out((st.save_path + // + "/" + st.name + ".fastresume").c_str() + // , std::ios_base::binary); + // out.unsetf(std::ios_base::skipws); + // bencode(std::ostream_iterator(out), *rd->resume_data); + // --outstanding_resume_data; + // } + // + //.. note:: Note how ``outstanding_resume_data`` is a global counter in this example. + // This is deliberate, otherwise there is a race condition for torrents that + // was just asked to save their resume data, they posted the alert, but it has + // not been received yet. Those torrents would report that they don't need to + // save resume data again, and skipped by the initial loop, and thwart the counter + // otherwise. void save_resume_data(int flags = 0) const; + + // This function returns true if any whole chunk has been downloaded since the + // torrent was first loaded or since the last time the resume data was saved. When + // saving resume data periodically, it makes sense to skip any torrent which hasn't + // downloaded anything since the last time. + // + //.. note:: A torrent's resume data is considered saved as soon as the alert + // is posted. It is important to make sure this alert is received and handled + // in order for this function to be meaningful. bool need_save_resume_data() const; + // changes whether the torrent is auto managed or not. For more info, + // see queuing_. void auto_managed(bool m) const; + // Every torrent that is added is assigned a queue position exactly one greater than + // the greatest queue position of all existing torrents. Torrents that are being + // seeded have -1 as their queue position, since they're no longer in line to be downloaded. + // + // When a torrent is removed or turns into a seed, all torrents with greater queue positions + // have their positions decreased to fill in the space in the sequence. + // + // ``queue_position()`` returns the torrent's position in the download queue. The torrents + // with the smallest numbers are the ones that are being downloaded. The smaller number, + // the closer the torrent is to the front of the line to be started. + // + // The queue position is also available in the torrent_status. + // + // The ``queue_position_*()`` functions adjust the torrents position in the queue. Up means + // closer to the front and down means closer to the back of the queue. Top and bottom refers + // to the front and the back of the queue respectively. int queue_position() const; void queue_position_up() const; void queue_position_down() const; void queue_position_top() const; void queue_position_bottom() const; + // Sets or gets the flag that derermines if countries should be resolved for the peers of this + // torrent. It defaults to false. If it is set to true, the peer_info_ structure for the peers + // in this torrent will have their ``country`` member set. See peer_info_ for more information + // on how to interpret this field. void resolve_countries(bool r); bool resolve_countries() const; + // For SSL torrents, use this to specify a path to a .pem file to use as this client's certificate. + // The certificate must be signed by the certificate in the .torrent file to be valid. + // + // ``cert`` is a path to the (signed) certificate in .pem format corresponding to this torrent. + // + // ``private_key`` is a path to the private key for the specified certificate. This must be in .pem + // format. + // + // ``dh_params`` is a path to the Diffie-Hellman parameter file, which needs to be in .pem format. + // You can generate this file using the openssl command like this: + // ``openssl dhparam -outform PEM -out dhparams.pem 512``. + // + // ``passphrase`` may be specified if the private key is encrypted and requires a passphrase to + // be decrypted. + // + // Note that when a torrent first starts up, and it needs a certificate, it will suspend connecting + // to any peers until it has one. It's typically desirable to resume the torrent after setting the + // ssl certificate. + // + // If you receive a torrent_need_cert_alert_, you need to call this to provide a valid cert. If you + // don't have a cert you won't be allowed to connect to any peers. void set_ssl_certificate(std::string const& certificate , std::string const& private_key , std::string const& dh_params , std::string const& passphrase = ""); + // Returns the storage implementation for this torrent. This depends on the + // storage contructor function that was passed to add_torrent. storage_interface* get_storage_impl() const; + // Returns a pointer to the torrent_info object associated with this torrent. The + // torrent_info object is a copy of the internal object. If the torrent doesn't + // have metadata, the object being returned will not be fully filled in. + // The torrent may be in a state without metadata only if + // it was started without a .torrent file, e.g. by using the libtorrent extension of + // just supplying a tracker and info-hash. boost::intrusive_ptr torrent_file() const; #ifndef TORRENT_NO_DEPRECATE @@ -337,6 +760,12 @@ namespace libtorrent TORRENT_DEPRECATED_PREFIX void filter_files(std::vector const& files) const TORRENT_DEPRECATED; + // ``use_interface()`` sets the network interface this torrent will use when it opens outgoing + // connections. By default, it uses the same interface as the session_ uses to listen on. The + // parameter must be a string containing one or more, comma separated, ip-address (either an + // IPv4 or IPv6 address). When specifying multiple interfaces, the torrent will round-robin + // which interface to use for each outgoing conneciton. This is useful for clients that are + // multi-homed. TORRENT_DEPRECATED_PREFIX void use_interface(const char* net_interface) const TORRENT_DEPRECATED; @@ -348,26 +777,86 @@ namespace libtorrent // ================ end deprecation ============ #endif + // Fills the specified ``std::vector`` with the availability for each + // piece in this torrent. libtorrent does not keep track of availability for + // seeds, so if the torrent is seeding the availability for all pieces is + // reported as 0. + // + // The piece availability is the number of peers that we are connected that has + // advertized having a particular piece. This is the information that libtorrent + // uses in order to prefer picking rare pieces. void piece_availability(std::vector& avail) const; - // priority must be within the range [0, 7] + // These functions are used to set and get the prioritiy of individual pieces. + // By default all pieces have priority 1. That means that the random rarest + // first algorithm is effectively active for all pieces. You may however + // change the priority of individual pieces. There are 8 different priority + // levels: + // + // 0. piece is not downloaded at all + // 1. normal priority. Download order is dependent on availability + // 2. higher than normal priority. Pieces are preferred over pieces with + // the same availability, but not over pieces with lower availability + // 3. pieces are as likely to be picked as partial pieces. + // 4. pieces are preferred over partial pieces, but not over pieces with + // lower availability + // 5. *currently the same as 4* + // 6. piece is as likely to be picked as any piece with availability 1 + // 7. maximum priority, availability is disregarded, the piece is preferred + // over any other piece with lower priority + // + // The exact definitions of these priorities are implementation details, and + // subject to change. The interface guarantees that higher number means higher + // priority, and that 0 means do not download. + // + // ``piece_priority`` sets or gets the priority for an individual piece, + // specified by ``index``. + // + // ``prioritize_pieces`` takes a vector of integers, one integer per piece in + // the torrent. All the piece priorities will be updated with the priorities + // in the vector. + // + // ``piece_priorities`` returns a vector with one element for each piece in the + // torrent. Each element is the current priority of that piece. void piece_priority(int index, int priority) const; int piece_priority(int index) const; - void prioritize_pieces(std::vector const& pieces) const; std::vector piece_priorities() const; - // priority must be within the range [0, 7] + // ``index`` must be in the range [0, number_of_files). + // + // ``file_priority()`` queries or sets the priority of file ``index``. + // + // ``prioritize_files()`` takes a vector that has at as many elements as there are + // files in the torrent. Each entry is the priority of that file. The function + // sets the priorities of all the pieces in the torrent based on the vector. + // + // ``file_priorities()`` returns a vector with the priorities of all files. + // + // The priority values are the same as for piece_priority(). + // + // Whenever a file priority is changed, all other piece priorities are reset + // to match the file priorities. In order to maintain sepcial priorities for + // particular pieces, piece_priority() has to be called again for those pieces. + // + // You cannot set the file priorities on a torrent that does not yet + // have metadata or a torrent that is a seed. ``file_priority(int, int)`` and + // prioritize_files() are both no-ops for such torrents. void file_priority(int index, int priority) const; int file_priority(int index) const; - void prioritize_files(std::vector const& files) const; std::vector file_priorities() const; - // forces this torrent to reannounce - // (make a rerequest from the tracker) + // ``force_reannounce()`` will force this torrent to do another tracker request, to receive new + // peers. The second overload of ``force_reannounce`` that takes a ``time_duration`` as + // argument will schedule a reannounce in that amount of time from now. + // + // If the tracker's ``min_interval`` has not passed since the last announce, the forced + // announce will be scheduled to happen immediately as the ``min_interval`` expires. This is + // to honor trackers minimum re-announce interval settings. + // + // ``force_dht_announce`` will announce the torrent to the DHT immediately. void force_reannounce() const; - // announces this torrent to the DHT immediately void force_dht_announce() const; // forces a reannounce in the specified amount of time. @@ -376,32 +865,113 @@ namespace libtorrent // timed out. void force_reannounce(boost::posix_time::time_duration) const; - // performs a scrape request + // ``scrape_tracker()`` will send a scrape request to the tracker. A scrape request queries the + // tracker for statistics such as total number of incomplete peers, complete peers, number of + // downloads etc. + // + // This request will specifically update the ``num_complete`` and ``num_incomplete`` fields in + // the torrent_status_ struct once it completes. When it completes, it will generate a + // scrape_reply_alert_. If it fails, it will generate a scrape_failed_alert_. void scrape_tracker() const; + // ``set_upload_limit`` will limit the upload bandwidth used by this particular torrent to the + // limit you set. It is given as the number of bytes per second the torrent is allowed to upload. + // ``set_download_limit`` works the same way but for download bandwidth instead of upload bandwidth. + // Note that setting a higher limit on a torrent then the global limit (``session_settings::upload_rate_limit``) + // will not override the global rate limit. The torrent can never upload more than the global rate + // limit. + // + // ``upload_limit`` and ``download_limit`` will return the current limit setting, for upload and + // download, respectively. void set_upload_limit(int limit) const; int upload_limit() const; void set_download_limit(int limit) const; int download_limit() const; + // ``set_sequential_download()`` enables or disables *sequential download*. When enabled, the piece + // picker will pick pieces in sequence instead of rarest first. + // + // Enabling sequential download will affect the piece distribution negatively in the swarm. It should be + // used sparingly. void set_sequential_download(bool sd) const; - // manually connect a peer + // ``connect_peer()`` is a way to manually connect to peers that one believe is a part of the + // torrent. If the peer does not respond, or is not a member of this torrent, it will simply + // be disconnected. No harm can be done by using this other than an unnecessary connection + // attempt is made. If the torrent is uninitialized or in queued or checking mode, this + // will throw libtorrent_exception_. The second (optional) argument will be bitwised ORed into + // the source mask of this peer. Typically this is one of the source flags in peer_info_. + // i.e. ``tracker``, ``pex``, ``dht`` etc. void connect_peer(tcp::endpoint const& adr, int source = 0) const; - // -1 means unlimited unchokes + // ``set_max_uploads()`` sets the maximum number of peers that's unchoked at the same time on this + // torrent. If you set this to -1, there will be no limit. This defaults to infinite. The primary + // setting controlling this is the global unchoke slots limit, set by unchoke_slots_limit + // in session_settings. + // + // ``max_uploads()`` returns the current settings. void set_max_uploads(int max_uploads) const; int max_uploads() const; - // -1 means unlimited connections + // ``set_max_connections()`` sets the maximum number of connection this torrent will open. If all + // connections are used up, incoming connections may be refused or poor connections may be closed. + // This must be at least 2. The default is unlimited number of connections. If -1 is given to the + // function, it means unlimited. There is also a global limit of the number of connections, set + // by ``connections_limit`` in session_settings_. + // + // ``max_connections()`` returns the current settings. void set_max_connections(int max_connections) const; int max_connections() const; + // sets a username and password that will be sent along in the HTTP-request + // of the tracker announce. Set this if the tracker requires authorization. void set_tracker_login(std::string const& name , std::string const& password) const; - // post condition: save_path() == save_path if true is returned + // Moves the file(s) that this torrent are currently seeding from or downloading to. If + // the given ``save_path`` is not located on the same drive as the original save path, + // the files will be copied to the new drive and removed from their original location. + // This will block all other disk IO, and other torrents download and upload rates may + // drop while copying the file. + // + // Since disk IO is performed in a separate thread, this operation is also asynchronous. + // Once the operation completes, the ``storage_moved_alert`` is generated, with the new + // path as the message. If the move fails for some reason, ``storage_moved_failed_alert`` + // is generated instead, containing the error message. + // + // The ``flags`` argument determines the behavior of the copying/moving of the files + // in the torrent. see move_flags_t. + // + // * always_replace_files = 0 + // * fail_if_exist = 1 + // * dont_replace = 2 + // + // ``always_replace_files`` is the default and replaces any file that exist in both the + // source directory and the target directory. + // + // ``fail_if_exist`` first check to see that none of the copy operations would cause an + // overwrite. If it would, it will fail. Otherwise it will proceed as if it was in + // ``always_replace_files`` mode. Note that there is an inherent race condition here. + // If the files in the target directory appear after the check but before the copy + // or move completes, they will be overwritten. When failing because of files already + // existing in the target path, the ``error`` of ``move_storage_failed_alert`` is set + // to ``boost::system::errc::file_exists``. + // + // The intention is that a client may use this as a probe, and if it fails, ask the user + // which mode to use. The client may then re-issue the ``move_storage`` call with one + // of the other modes. + // + // ``dont_replace`` always takes the existing file in the target directory, if there is + // one. The source files will still be removed in that case. + // + // Files that have been renamed to have absolute pahts are not moved by this function. + // Keep in mind that files that don't belong to the torrent but are stored in the torrent's + // directory may be moved as well. This goes for files that have been renamed to + // absolute paths that still end up inside the save path. void move_storage(std::string const& save_path, int flags = 0) const; + + // Renames the file with the given index asynchronously. The rename operation is complete + // when either a file_renamed_alert or file_rename_failed_alert is posted. void rename_file(int index, std::string const& new_name) const; #if TORRENT_USE_WSTRING @@ -416,8 +986,11 @@ namespace libtorrent #endif // TORRENT_NO_DEPRECATE #endif // TORRENT_USE_WSTRING + // Enables or disabled super seeding/initial seeding for this torrent. The torrent + // needs to be a seed for this to take effect. void super_seeding(bool on) const; + // ``info_hash()`` returns the info-hash for the torrent. sha1_hash info_hash() const; bool operator==(const torrent_handle& h) const @@ -429,6 +1002,11 @@ namespace libtorrent bool operator<(const torrent_handle& h) const { return m_torrent.lock() < h.m_torrent.lock(); } + // This function is intended only for use by plugins and the alert dispatch function. Any code + // that runs in libtorrent's network thread may not use the public API of torrent_handle. + // Doing so results in a dead-lock. For such routines, the ``native_handle`` gives access to the + // underlying type representing the torrent. This type does not have a stable API and should + // be relied on as little as possible. boost::shared_ptr native_handle() const; private: