changed the alerts to have categories and to be filtered with a bitmask instead of having a severity and be filtered by a severity level.

This commit is contained in:
Arvid Norberg 2008-07-06 12:22:56 +00:00
parent dab1b22982
commit e576babbb8
20 changed files with 1578 additions and 1322 deletions

View File

@ -53,15 +53,11 @@ void bind_alert()
{
scope alert_scope = class_<alert, noncopyable>("alert", alert_doc, no_init)
.def(
"msg", &alert::msg, return_value_policy<copy_const_reference>()
, alert_msg_doc
)
.def("message", &alert::message, alert_msg_doc)
.def("what", &alert::what)
.def("category", &alert::category)
.def("severity", &alert::severity, alert_severity_doc)
.def(
"__str__", &alert::msg, return_value_policy<copy_const_reference>()
, alert_msg_doc
)
.def("__str__", &alert::message, alert_msg_doc)
;
enum_<alert::severity_t>("severity_levels")
@ -72,6 +68,19 @@ void bind_alert()
.value("fatal", alert::fatal)
.value("none", alert::none)
;
enum_<alert::category_t>("category_t")
.value("error_notification", alert::error_notification)
.value("peer_notification", alert::peer_notification)
.value("port_mapping_notification", alert::port_mapping_notification)
.value("storage_notification", alert::storage_notification)
.value("tracker_notification", alert::tracker_notification)
.value("debug_notification", alert::debug_notification)
.value("status_notification", alert::status_notification)
.value("progress_notification", alert::progress_notification)
.value("ip_block_notification", alert::ip_block_notification)
.value("all_categories", alert::all_categories)
;
}
class_<torrent_alert, bases<alert>, noncopyable>(

View File

@ -323,6 +323,7 @@ void bind_session()
"set_severity_level", allow_threads(&session::set_severity_level)
, session_set_severity_level_doc
)
.def("set_alert_mask", allow_threads(&session::set_alert_mask))
.def("pop_alert", allow_threads(&session::pop_alert), session_pop_alert_doc)
.def("add_extension", &add_extension)
.def("set_peer_proxy", allow_threads(&session::set_peer_proxy))

View File

@ -3,7 +3,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
<title>libtorrent manual</title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
<link rel="stylesheet" href="style.css" type="text/css" />
@ -16,40 +16,40 @@
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td></tr>
<td>Arvid Norberg, <a class="last reference" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td></tr>
</tbody>
</table>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first">Table of contents</p>
<p class="topic-title first"><a name="table-of-contents">Table of contents</a></p>
<ul class="simple">
<li><a class="reference internal" href="#downloading-and-building" id="id9">downloading and building</a><ul>
<li><a class="reference internal" href="#building-from-svn" id="id10">building from svn</a></li>
<li><a class="reference internal" href="#building-with-bbv2" id="id11">building with BBv2</a></li>
<li><a class="reference internal" href="#building-with-autotools" id="id12">building with autotools</a></li>
<li><a class="reference internal" href="#building-with-other-build-systems" id="id13">building with other build systems</a></li>
<li><a class="reference internal" href="#build-configurations" id="id14">build configurations</a></li>
<li><a class="reference" href="#downloading-and-building" id="id9" name="id9">downloading and building</a><ul>
<li><a class="reference" href="#building-from-svn" id="id10" name="id10">building from svn</a></li>
<li><a class="reference" href="#building-with-bbv2" id="id11" name="id11">building with BBv2</a></li>
<li><a class="reference" href="#building-with-autotools" id="id12" name="id12">building with autotools</a></li>
<li><a class="reference" href="#building-with-other-build-systems" id="id13" name="id13">building with other build systems</a></li>
<li><a class="reference" href="#build-configurations" id="id14" name="id14">build configurations</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="downloading-and-building">
<h1>downloading and building</h1>
<div class="section">
<h1><a id="downloading-and-building" name="downloading-and-building">downloading and building</a></h1>
<p>To acquire the latest version of libtorrent, you'll have to grab it from SVN.
You'll find instructions on how to do this <a class="reference external" href="http://sourceforge.net/svn/?group_id=79942">here</a> (see subversion access).</p>
You'll find instructions on how to do this <a class="reference" href="http://sourceforge.net/svn/?group_id=79942">here</a> (see subversion access).</p>
<p>The build systems supported &quot;out of the box&quot; in libtorrent are boost-build v2
(BBv2) and autotools (for unix-like systems). If you still can't build after
following these instructions, you can usually get help in the <tt class="docutils literal"><span class="pre">#libtorrent</span></tt>
IRC channel on <tt class="docutils literal"><span class="pre">irc.freenode.net</span></tt>.</p>
<p>Community contributed build tutorials can be found on the <a class="reference external" href="http://code.rasterbar.com/libtorrent/wiki/Building">wiki</a>.</p>
<div class="section" id="building-from-svn">
<h2>building from svn</h2>
<p>Community contributed build tutorials can be found on the <a class="reference" href="http://code.rasterbar.com/libtorrent/wiki/Building">wiki</a>.</p>
<div class="section">
<h2><a id="building-from-svn" name="building-from-svn">building from svn</a></h2>
<p>To build libtorrent from svn you need to check out the libtorrent sources from
sourceforge and also check out the asio sources from its sourceforge cvs.
If you downloaded a release tarball, you can skip this section.</p>
<p>To prepare the directory structure for building, follow these steps:</p>
<ul class="simple">
<li>Check out libtorrent (<a class="reference external" href="http://sourceforge.net/svn/?group_id=79942">instructions</a>).</li>
<li>Check out asio (<a class="reference external" href="http://sourceforge.net/cvs/?group_id=122478">instructions</a>).</li>
<li>Check out libtorrent (<a class="reference" href="http://sourceforge.net/svn/?group_id=79942">instructions</a>).</li>
<li>Check out asio (<a class="reference" href="http://sourceforge.net/cvs/?group_id=122478">instructions</a>).</li>
<li>Copy the <tt class="docutils literal"><span class="pre">asio/include/asio/</span></tt> directory into the <tt class="docutils literal"><span class="pre">libtorrent/include/libtorrent/</span></tt>
directory. Alternatively you can make a symbolic link.</li>
<li>Copy <tt class="docutils literal"><span class="pre">asio/include/asio.hpp</span></tt> into <tt class="docutils literal"><span class="pre">libtorrent/include/libtorrent</span></tt>.</li>
@ -57,11 +57,11 @@ directory. Alternatively you can make a symbolic link.</li>
<p>Now the libtorrent directory is ready for building. Follow the steps in one
of the following sections depending on which build system you prefer to use.</p>
</div>
<div class="section" id="building-with-bbv2">
<h2>building with BBv2</h2>
<div class="section">
<h2><a id="building-with-bbv2" name="building-with-bbv2">building with BBv2</a></h2>
<p>The primary reason to use boost-build is that it will automatically build the
dependent boost libraries with the correct compiler settings, in order to
ensure that the build targets are link compatible (see <a class="reference external" href="http://boost.org/more/separate_compilation.html">boost guidelines</a>
ensure that the build targets are link compatible (see <a class="reference" href="http://boost.org/more/separate_compilation.html">boost guidelines</a>
for some details on this issue).</p>
<p>Since BBv2 will build the boost libraries for you, you need the full boost
source package. Having boost installed via some package system is usually not
@ -69,17 +69,17 @@ enough (and even if it is enough, the necessary environment variables are
usually not set by the package installer).</p>
<p>If you want to build against an installed copy of boost, you can skip directly
to step 3 (assuming you also have boost build installed).</p>
<div class="section" id="step-1-download-boost">
<h3>Step 1: Download boost</h3>
<p>You'll find boost <a class="reference external" href="http://sourceforge.net/project/showfiles.php?group_id=7586&amp;package_id=8041&amp;release_id=376197">here</a>.</p>
<div class="section">
<h3><a id="step-1-download-boost" name="step-1-download-boost">Step 1: Download boost</a></h3>
<p>You'll find boost <a class="reference" href="http://sourceforge.net/project/showfiles.php?group_id=7586&amp;package_id=8041&amp;release_id=376197">here</a>.</p>
<p>Extract the archive to some directory where you want it. For the sake of this
guide, let's assume you extract the package to <tt class="docutils literal"><span class="pre">c:\boost_1_34_0</span></tt> (I'm using
a windows path in this example since if you're on linux/unix you're more likely
to use the autotools). You'll need at least version 1.34 of the boost library
in order to build libtorrent.</p>
</div>
<div class="section" id="step-2-setup-bbv2">
<h3>Step 2: Setup BBv2</h3>
<div class="section">
<h3><a id="step-2-setup-bbv2" name="step-2-setup-bbv2">Step 2: Setup BBv2</a></h3>
<p>First you need to build <tt class="docutils literal"><span class="pre">bjam</span></tt>. You do this by opening a terminal (In
windows, run <tt class="docutils literal"><span class="pre">cmd</span></tt>). Change directory to
<tt class="docutils literal"><span class="pre">c:\boost_1_34_0\tools\jam\src</span></tt>. Then run the script called
@ -129,10 +129,10 @@ using darwin : 3.3 : g++-3.3 ;
using darwin : 4.0 : g++-4.0 ;
</pre>
<p>Note that the spaces around the semi-colons and colons are important!</p>
<p>Also see the <a class="reference external" href="http://www.boost.org/doc/html/bbv2/installation.html">official installation instructions</a>.</p>
<p>Also see the <a class="reference" href="http://www.boost.org/doc/html/bbv2/installation.html">official installation instructions</a>.</p>
</div>
<div class="section" id="step-3-building-libtorrent">
<h3>Step 3: Building libtorrent</h3>
<div class="section">
<h3><a id="step-3-building-libtorrent" name="step-3-building-libtorrent">Step 3: Building libtorrent</a></h3>
<p>When building libtorrent, the <tt class="docutils literal"><span class="pre">Jamfile</span></tt> expects the environment variable
<tt class="docutils literal"><span class="pre">BOOST_ROOT</span></tt> to be set to the boost installation directory. It uses this to
find the boost libraries it depends on, so they can be built and their headers
@ -194,7 +194,7 @@ Also, make sure the paths are correct in the different environments. In cygwin,
<tt class="docutils literal"><span class="pre">/cygdrive/c/boost_1_34_0</span></tt>). In the windows environment, they should have the typical
windows format (<tt class="docutils literal"><span class="pre">c:/boost_1_34_0</span></tt>).</p>
<p>The <tt class="docutils literal"><span class="pre">Jamfile</span></tt> will define <tt class="docutils literal"><span class="pre">NDEBUG</span></tt> when it's building a release build.
For more build configuration flags see <a class="reference internal" href="#build-configurations">Build configurations</a>.</p>
For more build configuration flags see <a class="reference" href="#build-configurations">Build configurations</a>.</p>
<p>Build features:</p>
<table border="1" class="docutils">
<colgroup>
@ -219,6 +219,15 @@ boost directory.</li>
</ul>
</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">boost-link</span></tt></td>
<td><ul class="first last simple">
<li><tt class="docutils literal"><span class="pre">static</span></tt> - links statically against the boost
libraries.</li>
<li><tt class="docutils literal"><span class="pre">shared</span></tt> - links dynamically against the boost
libraries.</li>
</ul>
</td>
</tr>
<tr><td><tt class="docutils literal"><span class="pre">logging</span></tt></td>
<td><ul class="first last simple">
<li><tt class="docutils literal"><span class="pre">none</span></tt> - no logging.</li>
@ -260,10 +269,10 @@ with the libtorrent package.</li>
<tr><td><tt class="docutils literal"><span class="pre">geoip</span></tt></td>
<td><ul class="first last simple">
<li><tt class="docutils literal"><span class="pre">off</span></tt> - geo ip lookups disabled</li>
<li><tt class="docutils literal"><span class="pre">static</span></tt> - <a class="reference external" href="http://www.maxmind.com/app/api">MaxMind</a> geo ip lookup code linked
<li><tt class="docutils literal"><span class="pre">static</span></tt> - <a class="reference" href="http://www.maxmind.com/app/api">MaxMind</a> geo ip lookup code linked
in statically. Note that this code is under
LGPL license.</li>
<li><tt class="docutils literal"><span class="pre">shared</span></tt> - The <a class="reference external" href="http://www.maxmind.com/app/api">MaxMind</a> geo ip lookup library
<li><tt class="docutils literal"><span class="pre">shared</span></tt> - The <a class="reference" href="http://www.maxmind.com/app/api">MaxMind</a> geo ip lookup library
is expected to be installed on the system and
it will be used.</li>
</ul>
@ -372,12 +381,12 @@ the name of the feature, just the value.</p>
<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 external" href="http://www.boost.org/tools/build/v2/index.html">Boost build v2 documentation</a>, or more
specifically <a class="reference external" href="http://www.boost.org/doc/html/bbv2/reference.html#bbv2.advanced.builtins.features">the section on builtin features</a>.</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>, or more
specifically <a class="reference" href="http://www.boost.org/doc/html/bbv2/reference.html#bbv2.advanced.builtins.features">the section on builtin features</a>.</p>
</div>
</div>
<div class="section" id="building-with-autotools">
<h2>building with autotools</h2>
<div class="section">
<h2><a id="building-with-autotools" name="building-with-autotools">building with autotools</a></h2>
<p>First of all, you need to install <tt class="docutils literal"><span class="pre">automake</span></tt> and <tt class="docutils literal"><span class="pre">autoconf</span></tt>. Many
unix/linux systems comes with these preinstalled.</p>
<p>The prerequisites for building libtorrent are boost.thread, boost.date_time
@ -388,11 +397,11 @@ boost.integer, boost.iterator, boost.tuple, boost.array, boost.function,
boost.smart_ptr, boost.preprocessor, boost.static_assert.</p>
<p>If you want to build the <tt class="docutils literal"><span class="pre">client_test</span></tt> example, you'll also need boost.regex
and boost.program_options.</p>
<div class="section" id="step-1-generating-the-build-system">
<h3>Step 1: Generating the build system</h3>
<div class="section">
<h3><a id="step-1-generating-the-build-system" name="step-1-generating-the-build-system">Step 1: Generating the build system</a></h3>
<p>No build system is present if libtorrent is checked out from CVS - it
needs to be generated first. If you're building from a released tarball,
you may skip directly to <a class="reference internal" href="#step-2-running-configure">Step 2: Running configure</a>.</p>
you may skip directly to <a class="reference" href="#step-2-running-configure">Step 2: Running configure</a>.</p>
<p>Execute the following commands, in the given order, to generate
the build system:</p>
<pre class="literal-block">
@ -404,8 +413,8 @@ autoconf
</pre>
<p>On darwin/OSX you have to run <tt class="docutils literal"><span class="pre">glibtoolize</span></tt> instead of <tt class="docutils literal"><span class="pre">libtoolize</span></tt>.</p>
</div>
<div class="section" id="step-2-running-configure">
<h3>Step 2: Running configure</h3>
<div class="section">
<h3><a id="step-2-running-configure" name="step-2-running-configure">Step 2: Running configure</a></h3>
<p>In your shell, change directory to the libtorrent directory and run
<tt class="docutils literal"><span class="pre">./configure</span></tt>. This will look for libraries and C++ features that libtorrent
is dependent on. If something is missing or can't be found it will print an
@ -453,8 +462,8 @@ checking for main in -lboost_thread... yes
directory contains spaces. Make sure you either rename the directories with
spaces in their names to remove the spaces or move the libtorrent directory.</p>
</div>
<div class="section" id="creating-a-debug-build">
<h3>Creating a debug build</h3>
<div class="section">
<h3><a id="creating-a-debug-build" name="creating-a-debug-build">Creating a debug build</a></h3>
<p>To tell configure to build a debug version (with debug info, asserts
and invariant checks enabled), you have to run the configure script
with the following option:</p>
@ -462,8 +471,8 @@ with the following option:</p>
./configure --enable-debug=yes
</pre>
</div>
<div class="section" id="creating-a-release-build">
<h3>Creating a release build</h3>
<div class="section">
<h3><a id="creating-a-release-build" name="creating-a-release-build">Creating a release build</a></h3>
<p>To tell the configure to build a release version (without debug info,
asserts and invariant checks), you have to run the configure script
with the following option:</p>
@ -472,8 +481,8 @@ with the following option:</p>
</pre>
<p>The above option make use of -DNDEBUG, which is used throughout libtorrent.</p>
</div>
<div class="section" id="id8">
<h3>Step 3: Building libtorrent</h3>
<div class="section">
<h3><a id="id8" name="id8">Step 3: Building libtorrent</a></h3>
<p>Once the configure script is run successfully, you just type <tt class="docutils literal"><span class="pre">make</span></tt> and
libtorrent, the examples and the tests will be built.</p>
<p>When libtorrent is built it may be a good idea to run the tests, you do this
@ -487,8 +496,8 @@ make
</pre>
</div>
</div>
<div class="section" id="building-with-other-build-systems">
<h2>building with other build systems</h2>
<div class="section">
<h2><a id="building-with-other-build-systems" name="building-with-other-build-systems">building with other build systems</a></h2>
<p>If you're making your own project file, note that there are two versions of
the file abstraction. There's one <tt class="docutils literal"><span class="pre">file_win.cpp</span></tt> which relies on windows
file API that supports files larger than 2 Gigabytes. This does not work in
@ -501,10 +510,10 @@ filenames, so if your target is Windows 2000 and up, you may want to use
<p>If you're building in MS Visual Studio, you may have to set the compiler
options &quot;force conformance in for loop scope&quot;, &quot;treat wchar_t as built-in
type&quot; and &quot;Enable Run-Time Type Info&quot; to Yes. For a detailed description
on how to build libtorrent with VS, see <a class="reference external" href="http://code.rasterbar.com/libtorrent/wiki/Building">the wiki</a>.</p>
on how to build libtorrent with VS, see <a class="reference" href="http://code.rasterbar.com/libtorrent/wiki/Building">the wiki</a>.</p>
</div>
<div class="section" id="build-configurations">
<h2>build configurations</h2>
<div class="section">
<h2><a id="build-configurations" name="build-configurations">build configurations</a></h2>
<p>By default libtorrent is built In debug mode, and will have pretty expensive
invariant checks and asserts built into it. If you want to disable such checks
(you want to do that in a release build) you can see the table below for which

View File

@ -3,42 +3,41 @@
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/" />
<meta name="generator" content="Docutils 0.4: http://docutils.sourceforge.net/" />
<title></title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<div class="document">
<table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" />
<col class="docinfo-content" />
<tbody valign="top">
<tr><th class="docinfo-name">Author:</th>
<td>Arvid Norberg, <a class="last reference external" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td></tr>
<td>Arvid Norberg, <a class="last reference" href="mailto:arvid&#64;rasterbar.com">arvid&#64;rasterbar.com</a></td></tr>
</tbody>
</table>
<div class="section" id="libtorrent-plugins">
<h1>libtorrent plugins</h1>
<div class="contents topic" id="contents">
<p class="topic-title first">Contents</p>
<div class="section">
<h1><a id="libtorrent-plugins" name="libtorrent-plugins">libtorrent plugins</a></h1>
<div class="contents topic" id="table-of-contents">
<p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<ul class="simple">
<li><a class="reference internal" href="#libtorrent-plugins" id="id1">libtorrent plugins</a><ul>
<li><a class="reference internal" href="#a-word-of-caution" id="id2">a word of caution</a></li>
<li><a class="reference" href="#libtorrent-plugins" id="id1" name="id1">libtorrent plugins</a><ul>
<li><a class="reference" href="#a-word-of-caution" id="id2" name="id2">a word of caution</a></li>
</ul>
</li>
<li><a class="reference internal" href="#plugin-interface" id="id3">plugin interface</a></li>
<li><a class="reference internal" href="#torrent-plugin" id="id4">torrent_plugin</a><ul>
<li><a class="reference internal" href="#new-connection" id="id5">new_connection()</a></li>
<li><a class="reference internal" href="#on-piece-pass-on-piece-fail" id="id6">on_piece_pass() on_piece_fail()</a></li>
<li><a class="reference internal" href="#tick" id="id7">tick()</a></li>
<li><a class="reference internal" href="#on-pause-on-resume" id="id8">on_pause() on_resume()</a></li>
<li><a class="reference internal" href="#on-files-checked" id="id9">on_files_checked()</a></li>
<li><a class="reference" href="#plugin-interface" id="id3" name="id3">plugin interface</a></li>
<li><a class="reference" href="#torrent-plugin" id="id4" name="id4">torrent_plugin</a><ul>
<li><a class="reference" href="#new-connection" id="id5" name="id5">new_connection()</a></li>
<li><a class="reference" href="#on-piece-pass-on-piece-fail" id="id6" name="id6">on_piece_pass() on_piece_fail()</a></li>
<li><a class="reference" href="#tick" id="id7" name="id7">tick()</a></li>
<li><a class="reference" href="#on-pause-on-resume" id="id8" name="id8">on_pause() on_resume()</a></li>
<li><a class="reference" href="#on-files-checked" id="id9" name="id9">on_files_checked()</a></li>
</ul>
</li>
<li><a class="reference internal" href="#peer-plugin" id="id10">peer_plugin</a></li>
<li><a class="reference internal" href="#disk-buffer-holder" id="id11">disk_buffer_holder</a></li>
<li><a class="reference" href="#peer-plugin" id="id10" name="id10">peer_plugin</a></li>
<li><a class="reference" href="#disk-buffer-holder" id="id11" name="id11">disk_buffer_holder</a></li>
</ul>
</div>
<p>libtorrent has a plugin interface for implementing extensions to the protocol.
@ -48,13 +47,13 @@ to fit a particular (closed) network.</p>
<p>In short, the plugin interface makes it possible to:</p>
<ul class="simple">
<li>register extension messages (sent in the extension handshake), see
<a class="reference external" href="extension_protocol.html">extensions</a>.</li>
<a class="reference" href="extension_protocol.html">extensions</a>.</li>
<li>add data and parse data from the extension handshake.</li>
<li>send extension messages and standard bittorrent messages.</li>
<li>override or block the handling of standard bittorrent messages.</li>
</ul>
<div class="section" id="a-word-of-caution">
<h2>a word of caution</h2>
<div class="section">
<h2><a id="a-word-of-caution" name="a-word-of-caution">a word of caution</a></h2>
<p>Writing your own plugin is a very easy way to introduce serious bugs such as
dead locks and race conditions. Since a plugin has access to internal
structures it is also quite easy to sabotage libtorrent's operation.</p>
@ -65,12 +64,12 @@ thread, you cannot use any of the member functions on the internal structures
in libtorrent, since those require the mutex to be locked. Futhermore, you would
also need to have a mutex on your own shared data within the plugin, to make
sure it is not accessed at the same time from the libtorrent thread (through a
callback). See <a class="reference external" href="http://www.boost.org/doc/html/mutex.html">boost thread's mutex</a>. If you need to send out a message from
callback). See <a class="reference" href="http://www.boost.org/doc/html/mutex.html">boost thread's mutex</a>. If you need to send out a message from
another thread, use an internal queue, and do the actual sending in <tt class="docutils literal"><span class="pre">tick()</span></tt>.</p>
</div>
</div>
<div class="section" id="plugin-interface">
<h1>plugin interface</h1>
<div class="section">
<h1><a id="plugin-interface" name="plugin-interface">plugin interface</a></h1>
<p>The plugin interface consists of two base classes that the plugin may
implement. These are called <tt class="docutils literal"><span class="pre">torrent_plugin</span></tt> and <tt class="docutils literal"><span class="pre">peer_plugin</span></tt>. They are
both found in the <tt class="docutils literal"><span class="pre">&lt;libtorrent/extensions.hpp&gt;</span></tt> header.</p>
@ -93,8 +92,8 @@ for this torrent. If it is a valid pointer (to a class inheriting
<tt class="docutils literal"><span class="pre">torrent_plugin</span></tt>), it will be associated with this torrent and callbacks
will be made on torrent events.</p>
</div>
<div class="section" id="torrent-plugin">
<h1>torrent_plugin</h1>
<div class="section">
<h1><a id="torrent-plugin" name="torrent-plugin">torrent_plugin</a></h1>
<p>The synopsis for <tt class="docutils literal"><span class="pre">torrent_plugin</span></tt> follows:</p>
<pre class="literal-block">
struct torrent_plugin
@ -116,8 +115,8 @@ struct torrent_plugin
<p>This is the base class for a torrent_plugin. Your derived class is (if added
as an extension) instantiated for each torrent in the session. The callback
hook functions are defined as follows.</p>
<div class="section" id="new-connection">
<h2>new_connection()</h2>
<div class="section">
<h2><a id="new-connection" name="new-connection">new_connection()</a></h2>
<pre class="literal-block">
boost::shared_ptr&lt;peer_plugin&gt; new_connection(peer_connection*);
</pre>
@ -134,8 +133,8 @@ held by the torrent object. So, it is generally a good idea to not keep a
use <tt class="docutils literal"><span class="pre">weak_ptr</span></tt>.</p>
<p>If this function throws an exception, the connection will be closed.</p>
</div>
<div class="section" id="on-piece-pass-on-piece-fail">
<h2>on_piece_pass() on_piece_fail()</h2>
<div class="section">
<h2><a id="on-piece-pass-on-piece-fail" name="on-piece-pass-on-piece-fail">on_piece_pass() on_piece_fail()</a></h2>
<pre class="literal-block">
void on_piece_pass(int index);
void on_piece_failed(int index);
@ -145,16 +144,16 @@ check, respectively. The <tt class="docutils literal"><span class="pre">index</s
It is possible to access the list of peers that participated in sending the
piece through the <tt class="docutils literal"><span class="pre">torrent</span></tt> and the <tt class="docutils literal"><span class="pre">piece_picker</span></tt>.</p>
</div>
<div class="section" id="tick">
<h2>tick()</h2>
<div class="section">
<h2><a id="tick" name="tick">tick()</a></h2>
<pre class="literal-block">
void tick();
</pre>
<p>This hook is called approximately once per second. It is a way of making it
easy for plugins to do timed events, for sending messages or whatever.</p>
</div>
<div class="section" id="on-pause-on-resume">
<h2>on_pause() on_resume()</h2>
<div class="section">
<h2><a id="on-pause-on-resume" name="on-pause-on-resume">on_pause() on_resume()</a></h2>
<pre class="literal-block">
bool on_pause();
bool on_resume();
@ -170,8 +169,8 @@ handler it will recurse back into your handler, so in order to invoke the
standard handler, you have to keep your own state on whether you want standard
behavior or overridden behavior.</p>
</div>
<div class="section" id="on-files-checked">
<h2>on_files_checked()</h2>
<div class="section">
<h2><a id="on-files-checked" name="on-files-checked">on_files_checked()</a></h2>
<pre class="literal-block">
void on_files_checked();
</pre>
@ -181,8 +180,8 @@ checked. If there are no files to check, this function is called immediately.</p
can start downloading.</p>
</div>
</div>
<div class="section" id="peer-plugin">
<h1>peer_plugin</h1>
<div class="section">
<h1><a id="peer-plugin" name="peer-plugin">peer_plugin</a></h1>
<pre class="literal-block">
struct peer_plugin
{
@ -190,7 +189,7 @@ struct peer_plugin
virtual void add_handshake(entry&amp;);
virtual bool on_handshake(char const* reserved_bits);
virtual bool on_extension_handshake(entry const&amp; h);
virtual bool on_extension_handshake(lazy_entry const&amp; h);
virtual bool on_choke();
virtual bool on_unchoke();
@ -219,8 +218,8 @@ struct peer_plugin
};
</pre>
</div>
<div class="section" id="disk-buffer-holder">
<h1>disk_buffer_holder</h1>
<div class="section">
<h1><a id="disk-buffer-holder" name="disk-buffer-holder">disk_buffer_holder</a></h1>
<pre class="literal-block">
struct disk_buffer_holder
{

File diff suppressed because it is too large Load Diff

View File

@ -141,7 +141,7 @@ The ``session`` class has the following synopsis::
std::auto_ptr<alert> pop_alert();
alert const* wait_for_alert(time_duration max_wait);
void set_severity_level(alert::severity_t s);
void set_alert_mask(int m);
void add_extension(boost::function<
boost::shared_ptr<torrent_plugin>(torrent*)> ext);
@ -673,18 +673,18 @@ with a DHT ping packet, and connect to those that responds first. On windows one
can only connect to a few peers at a time because of a built in limitation (in XP
Service pack 2).
pop_alert() set_severity_level() wait_for_alert()
-------------------------------------------------
pop_alert() set_alert_mask() wait_for_alert()
---------------------------------------------
::
std::auto_ptr<alert> pop_alert();
alert const* wait_for_alert(time_duration max_wait);
void set_severity_level(alert::severity_t s);
void set_alert_mask(int m);
``pop_alert()`` is used to ask the session if any errors or events has occurred. With
``set_severity_level()`` you can filter how serious the event has to be for you to
receive it through ``pop_alert()``. For information, see alerts_.
``set_alert_mask()`` you can filter which alerts to receive through ``pop_alert()``.
For information about the alert categories, see alerts_.
``wait_for_alert`` blocks until an alert is available, or for no more than ``max_wait``
time. If ``wait_for_alert`` returns because of the time-out, and no alerts are available,
@ -3653,55 +3653,54 @@ alerts
======
The ``pop_alert()`` function on session is the interface for retrieving
alerts, warnings, messages and errors from libtorrent. If there hasn't
occurred any errors (matching your severity level) ``pop_alert()`` will
return a zero pointer. If there has been some error, it will return a pointer
to an alert object describing it. You can then use the alert object and query
it for information about the error or message. To retrieve any alerts, you have
to select a severity level using ``session::set_severity_level()``. It defaults to
``alert::none``, which means that you don't get any messages at all, ever.
You have the following levels to select among:
alerts, warnings, messages and errors from libtorrent. If no alerts have
been posted by libtorrent ``pop_alert()`` will return a default initialized
``auto_ptr`` object. If there is an alert in libtorrent's queue, the alert
from the front of the queue is popped and returned.
You can then use the alert object and query
+--------------+----------------------------------------------------------+
| ``none`` | No alert will ever have this severity level, which |
| | effectively filters all messages. |
| | |
+--------------+----------------------------------------------------------+
| ``fatal`` | Fatal errors will have this severity level. Examples can |
| | be disk full or something else that will make it |
| | impossible to continue normal execution. |
| | |
+--------------+----------------------------------------------------------+
| ``critical`` | Signals errors that requires user interaction or |
| | messages that almost never should be ignored. For |
| | example, a chat message received from another peer is |
| | announced as severity ``critical``. |
| | |
+--------------+----------------------------------------------------------+
| ``warning`` | Messages with the warning severity can be a tracker that |
| | times out or responds with invalid data. It will be |
| | retried automatically, and the possible next tracker in |
| | a multitracker sequence will be tried. It does not |
| | require any user interaction. |
| | |
+--------------+----------------------------------------------------------+
| ``info`` | Events that can be considered normal, but still deserves |
| | an event. This could be a piece hash that fails. |
| | |
+--------------+----------------------------------------------------------+
| ``debug`` | This will include a lot of debug events that can be used |
| | both for debugging libtorrent but also when debugging |
| | other clients that are connected to libtorrent. It will |
| | report strange behaviors among the connected peers. |
| | |
+--------------+----------------------------------------------------------+
By default, only errors are reported. ``session::set_alert_mask()`` can be
used to specify which kinds of events should be reported. The alert mask
is a bitmask with the following bits:
When setting a severity level, you will receive messages of that severity and all
messages that are more sever. If you set ``alert::none`` (the default) you will not receive
any events at all.
+--------------------------------+---------------------------------------------------------------------+
| ``error_notification`` | Enables alerts that report an error. This includes: |
| | |
| | * tracker errors |
| | * tracker warnings |
| | * file errors |
| | * resume data failures |
| | * web seed errors |
| | * .torrent files errors |
| | * listen socket errors |
| | * port mapping errors |
+--------------------------------+---------------------------------------------------------------------+
| ``peer_notification`` | Enables alerts when peers send invalid requests, get banned or |
| | snubbed. |
+--------------------------------+---------------------------------------------------------------------+
| ``port_mapping_notification`` | Enables alerts for port mapping events. For NAT-PMP and UPnP. |
+--------------------------------+---------------------------------------------------------------------+
| ``storage_notification`` | Enables alerts for events related to the storage. File errors and |
| | synchronization events for moving the storage, renaming files etc. |
+--------------------------------+---------------------------------------------------------------------+
| ``tracker_notification`` | Enables all tracker events. Includes announcing to trackers, |
| | receiving responses, warnings and errors. |
+--------------------------------+---------------------------------------------------------------------+
| ``debug_notification`` | Low level alerts for when peers are connected and disconnected. |
+--------------------------------+---------------------------------------------------------------------+
| ``status_notification`` | Enables alerts for when a torrent or the session changes state. |
+--------------------------------+---------------------------------------------------------------------+
| ``progress_notification`` | Alerts for when blocks are requested and completed. Also when |
| | pieces are completed. |
+--------------------------------+---------------------------------------------------------------------+
| ``ip_block_notification`` | Alerts when a peer is blocked by the ip blocker or port blocker. |
+--------------------------------+---------------------------------------------------------------------+
| ``all_categories`` | The full bitmask, representing all available categories. |
+--------------------------------+---------------------------------------------------------------------+
When you set a severity level other than ``none``, you have the responsibility to call
``pop_alert()`` from time to time. If you don't do that, the alert queue will just grow.
Every alert belongs to one or more category. There is a small cost involved in posting alerts. Only
alerts that belong to an enabled category are posted. Setting the alert bitmask to 0 will disable
all alerts
When you get an alert, you can use ``typeid()`` or ``dynamic_cast<>`` to get more detailed
information on exactly which type it is. i.e. what kind of error it is. You can also use a
@ -3710,38 +3709,70 @@ dispatcher_ mechanism that's available in libtorrent.
All alert types are defined in the ``<libtorrent/alert_types.hpp>`` header file.
The ``alert`` class is the base class that specific messages are derived from. This
is its synopsis::
is its synopsis:
.. parsed-literal::
class alert
{
public:
enum severity_t { debug, info, warning, critical, fatal, none };
enum category_t
{
error_notification = *implementation defined*,
peer_notification = *implementation defined*,
port_mapping_notification = *implementation defined*,
storage_notification = *implementation defined*,
tracker_notification = *implementation defined*,
debug_notification = *implementation defined*,
status_notification = *implementation defined*,
progress_notification = *implementation defined*,
ip_block_notification = *implementation defined*,
all_categories = *implementation defined*
};
ptime timestamp() const;
alert(severity_t severity, std::string const& msg);
virtual ~alert();
std::string const& msg() const;
severity_t severity() const;
virtual std::string message() const = 0;
virtual char const* what() const = 0;
virtual int category() const = 0;
virtual std::auto_ptr<alert> clone() const = 0;
};
This means that all alerts have at least a string describing it. They also
have a severity level that can be used to sort them or present them to the
user in different ways.
``what()`` returns a string literal describing the type of the alert. It does
not include any information that might be bundled with the alert.
There's another alert base class that all most alerts derives from, all the
``category()`` returns a bitmask specifying which categories this alert belong to.
``clone()`` returns a pointer to a copy of the alert.
``message()`` generate a string describing the alert and the information bundled
with it. This is mainly intended for debug and development use. It is not suitable
to use this for applications that may be localized. Instead, handle each alert
type individually and extract and render the information from the alert depending
on the locale.
There's another alert base class that most alerts derives from, all the
alerts that are generated for a specific torrent are derived from::
struct torrent_alert: alert
{
torrent_alert(torrent_handle const& h, severity_t s, std::string const& msg);
// ...
torrent_handle handle;
};
The specific alerts, that all derives from ``alert``, are:
There's also a base class for all alerts referring to tracker events::
struct tracker_alert: torrent_alert
{
// ...
std::string url;
};
The specific alerts are:
external_ip_alert
-----------------
@ -3750,15 +3781,13 @@ Whenever libtorrent learns about the machines external IP, this alert is
generated. The external IP address can be acquired from the tracker (if it
supports that) or from peers that supports the extension protocol.
The address can be accessed through the ``external_address`` member.
This alert is generated as severity level ``info``.
::
struct external_ip_alert: alert
{
external_ip_alert(address const& ip, const std::string& msg);
// ...
address external_address;
virtual std::auto_ptr<alert> clone() const;
};
@ -3766,16 +3795,9 @@ listen_failed_alert
-------------------
This alert is generated when none of the ports, given in the port range, to
session_ can be opened for listening. This alert is generated as severity
level ``fatal``.
session_ can be opened for listening. This alert doesn't have any extra
data members.
::
struct listen_failed_alert: alert
{
listen_failed_alert(const std::string& msg);
virtual std::auto_ptr<alert> clone() const;
};
portmap_error_alert
-------------------
@ -3787,9 +3809,6 @@ case it appears the client is not running on a NAT:ed network or if it
appears there is no NAT router that can be remote controlled to add port
mappings.
The alert is generated as severity ``warning``, since it should be displayed
to the user somehow, and could mean reduced preformance.
``mapping`` refers to the mapping index of the port map that failed, i.e.
the index returned from add_mapping_.
@ -3799,10 +3818,9 @@ the index returned from add_mapping_.
struct portmap_error_alert: alert
{
portmap_error_alert(int mapping, int type, const std::string& msg);
// ...
int mapping;
int type;
virtual std::auto_ptr<alert> clone() const;
};
portmap_alert
@ -3811,8 +3829,7 @@ portmap_alert
This alert is generated when a NAT router was successfully found and
a port was successfully mapped on it. On a NAT:ed network with a NAT-PMP
capable router, this is typically generated once when mapping the TCP
port and, if DHT is enabled, when the UDP port is mapped. This is merely
an informational alert, and is generated at severity level ``info``.
port and, if DHT is enabled, when the UDP port is mapped.
``mapping`` refers to the mapping index of the port map that failed, i.e.
the index returned from add_mapping_.
@ -3825,28 +3842,29 @@ the index returned from add_mapping_.
struct portmap_alert: alert
{
portmap_alert(int mapping, int port, int type, const std::string& msg);
// ...
int mapping;
int external_port;
int type;
virtual std::auto_ptr<alert> clone() const;
};
file_error_alert
----------------
If the storage fails to read or write files that it needs access to, this alert is
generated and the torrent is paused. It is generated as severity level ``fatal``.
generated and the torrent is paused.
``file`` is the path to the file that was accessed when the error occurred.
``msg`` is the error message received from the OS.
::
struct file_error_alert: torrent_alert
{
file_error_alert(
const torrent_handle& h
, const std::string& msg);
virtual std::auto_ptr<alert> clone() const;
// ...
std::string file;
std::string msg;
};
@ -3854,43 +3872,16 @@ tracker_announce_alert
----------------------
This alert is generated each time a tracker announce is sent (or attempted to be sent).
It is generated at severity level ``info``.
There are no extra data members in this alert. The url can be found in the base class
however.
::
struct tracker_announce_alert: torrent_alert
{
tracker_announce_alert(
const torrent_handle& h
, const std::string& msg);
virtual std::auto_ptr<alert> clone() const;
};
tracker_alert
-------------
This is a base class for all alerts related to trackers.
::
struct tracker_alert: torrent_alert
{
tracker_alert(torrent_handle const& h
, std::string const& url
, alert::severity_t s
, std::string const& msg);
std::string url;
};
tracker_error_alert
-------------------
This alert is generated on tracker time outs, premature disconnects, invalid response or
a HTTP response other than "200 OK". From the alert you can get the handle to the torrent
the tracker belongs to. This alert is generated as severity level ``warning``.
the tracker belongs to.
The ``times_in_row`` member says how many times in a row this tracker has failed.
``status_code`` is the code returned from the HTTP server. 401 means the tracker needs
@ -3901,10 +3892,7 @@ to 0.
struct tracker_error_alert: tracker_alert
{
tracker_error_alert(torrent_handle const& h, int times, int status
, std::string const& url, std::string const& msg);
virtual std::auto_ptr<alert> clone() const;
// ...
int times_in_row;
int status_code;
};
@ -3915,90 +3903,88 @@ tracker_reply_alert
This alert is only for informational purpose. It is generated when a tracker announce
succeeds. It is generated regardless what kind of tracker was used, be it UDP, HTTP or
the DHT. It is generated with severity level ``info``.
the DHT.
::
struct tracker_reply_alert: tracker_alert
{
tracker_reply_alert(const torrent_handle& h
, int num_peers
. std::string const& url
, std::string const& msg);
// ...
int num_peers;
virtual std::auto_ptr<alert> clone() const;
};
The ``num_peers`` tells how many peers were returned from the tracker. This is
not necessarily all new peers, some of them may already be connected.
dht_reply_alert
-------------------
This alert is generated each time the DHT receives peers from a node. ``num_peers``
is the number of peers we received in this packet. Typically these packets are
received from multiple DHT nodes, and so the alerts are typically generated
a few at a time.
::
struct dht_reply_alert: tracker_alert
{
// ...
int num_peers;
};
tracker_warning_alert
---------------------
This alert is triggered if the tracker reply contains a warning field. Usually this
means that the tracker announce was successful, but the tracker has a message to
the client. The message string in the alert will contain the warning message from
the tracker. It is generated with severity level ``warning``.
the client. The ``msg`` string in the alert contains the warning message from
the tracker.
::
struct tracker_warning_alert: tracker_alert
{
tracker_warning_alert(torrent_handle const& h
, std::string const& url
, std::string const& msg);
virtual std::auto_ptr<alert> clone() const;
// ...
std::string msg;
};
scrape_reply_alert
------------------
::
struct scrape_reply_alert: tracker_alert
{
scrape_reply_alert(torrent_handle const& h
, int incomplete_
, int complete_
, std::string const& url
, std::string const& msg);
int incomplete;
int complete;
virtual std::auto_ptr<alert> clone() const;
};
This alert is generated when a scrape request succeeds. ``incomplete``
and ``complete`` is the data returned in the scrape response. These numbers
may be -1 if the reponse was malformed.
::
struct scrape_reply_alert: tracker_alert
{
// ...
int incomplete;
int complete;
};
scrape_failed_alert
-------------------
If a scrape request fails, this alert is generated. This might be due
to the tracker timing out, refusing connection or returning an http response
code indicating an error. ``msg`` contains a message describing the error.
::
struct scrape_failed_alert: tracker_alert
{
scrape_failed_alert(torrent_handle const& h
, std::string const& url
, std::string const& msg);
virtual std::auto_ptr<alert> clone() const;
// ...
std::string msg;
};
If a scrape request fails, this alert is generated. This might be due
to the tracker timing out, refusing connection or returning an http response
code indicating an error.
url_seed_alert
--------------
This alert is generated when a HTTP seed name lookup fails. This alert is
generated as severity level ``warning``.
This alert is generated when a HTTP seed name lookup fails.
It contains ``url`` to the HTTP seed that failed along with an error message.
@ -4006,10 +3992,7 @@ It contains ``url`` to the HTTP seed that failed along with an error message.
struct url_seed_alert: torrent_alert
{
url_seed_alert(torrent_handle const& h, std::string const& url
, const std::string& msg);
virtual std::auto_ptr<alert> clone() const;
// ...
std::string url;
};
@ -4019,19 +4002,12 @@ hash_failed_alert
This alert is generated when a finished piece fails its hash check. You can get the handle
to the torrent which got the failed piece and the index of the piece itself from the alert.
This alert is generated as severity level ``info``.
::
struct hash_failed_alert: torrent_alert
{
hash_failed_alert(
torrent_handle const& h
, int index
, const std::string& msg);
virtual std::auto_ptr<alert> clone() const;
// ...
int piece_index;
};
@ -4040,20 +4016,13 @@ peer_ban_alert
--------------
This alert is generated when a peer is banned because it has sent too many corrupt pieces
to us. It is generated at severity level ``info``. The ``handle`` member is a torrent_handle_
to the torrent that this peer was a member of.
to us. ``ip`` is the endpoint to the peer that was banned.
::
struct peer_ban_alert: torrent_alert
{
peer_ban_alert(
asio::ip::tcp::endpoint const& pip
, torrent_handle h
, const std::string& msg);
virtual std::auto_ptr<alert> clone() const;
// ...
asio::ip::tcp::endpoint ip;
};
@ -4062,19 +4031,13 @@ peer_error_alert
----------------
This alert is generated when a peer sends invalid data over the peer-peer protocol. The peer
will be disconnected, but you get its ip address from the alert, to identify it. This alert
is generated as severity level ``debug``.
will be disconnected, but you get its ip address from the alert, to identify it.
::
struct peer_error_alert: alert
struct peer_error_alert: torrent_alert
{
peer_error_alert(
asio::ip::tcp::endpoint const& pip
, peer_id const& pid
, const std::string& msg);
virtual std::auto_ptr<alert> clone() const;
// ...
asio::ip::tcp::endpoint ip;
peer_id id;
};
@ -4083,10 +4046,9 @@ is generated as severity level ``debug``.
invalid_request_alert
---------------------
This is a debug alert that is generated by an incoming invalid piece request. The ``handle``
is a handle to the torrent the peer is a member of. ``ìp`` is the address of the peer and the
``request`` is the actual incoming request from the peer. The alert is generated as severity level
``debug``.
This is a debug alert that is generated by an incoming invalid piece request.
``ìp`` is the address of the peer and the ``request`` is the actual incoming
request from the peer.
::
@ -4125,18 +4087,9 @@ torrent_finished_alert
This alert is generated when a torrent switches from being a downloader to a seed.
It will only be generated once per torrent. It contains a torrent_handle to the
torrent in question. This alert is generated as severity level ``info``.
torrent in question.
::
struct torrent_finished_alert: torrent_alert
{
torrent_finished_alert(
const torrent_handle& h
, const std::string& msg);
virtual std::auto_ptr<alert> clone() const;
};
There are no additional data members in this alert.
metadata_failed_alert
@ -4146,18 +4099,8 @@ This alert is generated when the metadata has been completely received and the i
failed to match it. i.e. the metadata that was received was corrupt. libtorrent will
automatically retry to fetch it in this case. This is only relevant when running a
torrent-less download, with the metadata extension provided by libtorrent.
It is generated at severity level ``info``.
::
struct metadata_failed_alert: torrent_alert
{
metadata_failed_alert(
torrent_handle const& h
, std::string const& msg);
virtual std::auto_ptr<alert> clone() const;
};
There are no additional data members in this alert.
metadata_received_alert
@ -4166,18 +4109,8 @@ metadata_received_alert
This alert is generated when the metadata has been completely received and the torrent
can start downloading. It is not generated on torrents that are started with metadata, but
only those that needs to download it from peers (when utilizing the libtorrent extension).
It is generated at severity level ``info``.
::
struct metadata_received_alert: torrent_alert
{
metadata_received_alert(
torrent_handle const_& h
, std::string const& msg);
virtual std::auto_ptr<alert> clone() const;
};
There are no additional data members in this alert.
fastresume_rejected_alert
@ -4185,52 +4118,49 @@ fastresume_rejected_alert
This alert is generated when a fastresume file has been passed to ``add_torrent`` but the
files on disk did not match the fastresume file. The string explains the reason why the
resume file was rejected. It is generated at severity level ``warning``.
resume file was rejected.
::
struct fastresume_rejected_alert: torrent_alert
{
fastresume_rejected_alert(torrent_handle const& h
, std::string const& msg);
virtual std::auto_ptr<alert> clone() const;
// ...
std::string msg;
};
peer_blocked_alert
------------------
This alert is generated when a peer is blocked by the IP filter. It has the severity leve
``info``. The ``ip`` member is the address that was blocked.
This alert is generated when a peer is blocked by the IP filter. The ``ip`` member is the
address that was blocked.
::
struct peer_blocked_alert: alert
{
peer_blocked_alert(address const& ip_
, std::string const& msg);
// ...
address ip;
virtual std::auto_ptr<alert> clone() const;
};
storage_moved_alert
-------------------
The ``storage_moved_alert`` is generated when all the disk IO has completed and the
files have been moved, as an effect of a call to ``torrent_handle::move_storage``. This
is useful to synchronize with the actual disk.
is useful to synchronize with the actual disk. The ``path`` member is the new path of
the storage.
::
struct storage_moved_alert: torrent_alert
{
storage_moved_alert(torrent_handle const& h, std::string const& path);
virtual std::auto_ptr<alert> clone() const;
// ...
std::string path;
};
torrent_paused_alert
--------------------
@ -4238,31 +4168,7 @@ This alert is generated as a response to a ``torrent_handle::pause`` request. It
generated once all disk IO is complete and the files in the torrent have been closed.
This is useful for synchronizing with the disk.
::
struct torrent_paused_alert: torrent_alert
{
torrent_paused_alert(torrent_handle const& h, std::string const& msg);
virtual std::auto_ptr<alert> clone() const;
};
save_resume_data_alert
----------------------
This alert is generated as a response to a ``torrent_handle::save_resume_data`` request.
It is generated once the disk IO thread is done writing the state for this torrent.
The ``resume_data`` member points to the resume data or is 0 on errors.
::
struct save_resume_data_alert: torrent_alert
{
save_resume_alert(torrent_handle const& h, std::string const& msg);
boost::shared_ptr<entry> resume_data;
virtual std::auto_ptr<alert> clone() const;
};
There are no additional data members in this alert.
torrent_resumed_alert
---------------------
@ -4270,12 +4176,35 @@ torrent_resumed_alert
This alert is generated as a response to a ``torrent_handle::resume`` request. It is
generated when a torrent goes from a paused state to an active state.
There are no additional data members in this alert.
save_resume_data_alert
----------------------
This alert is generated as a response to a ``torrent_handle::save_resume_data`` request.
It is generated once the disk IO thread is done writing the state for this torrent.
The ``resume_data`` member points to the resume data.
::
struct torrent_resumed_alert: torrent_alert
struct save_resume_data_alert: torrent_alert
{
torrent_resumed_alert(torrent_handle const& h, std::string const& msg);
virtual std::auto_ptr<alert> clone() const;
// ...
boost::shared_ptr<entry> resume_data;
};
save_resume_data_failed_alert
-----------------------------
This alert is generated instead of ``save_resume_data_alert`` if there was an error
generating the resume data. ``msg`` describes what went wrong.
::
struct save_resume_data_failed_alert: torrent_alert
{
// ...
std::string msg;
};
dispatcher

View File

@ -584,6 +584,33 @@ libtorrent::torrent_handle get_active_torrent(handles_t const& handles)
return i->second;
}
void handle_alert(libtorrent::session& ses, libtorrent::alert* a)
{
using namespace libtorrent;
if (torrent_finished_alert* p = dynamic_cast<torrent_finished_alert*>(a))
{
p->handle.set_max_connections(30);
// write resume data for the finished torrent
torrent_handle h = p->handle;
h.save_resume_data();
}
else if (save_resume_data_alert* p = dynamic_cast<save_resume_data_alert*>(a))
{
torrent_handle h = p->handle;
TORRENT_ASSERT(p->resume_data);
if (p->resume_data)
{
boost::filesystem::ofstream out(h.save_path() / (h.name() + ".fastresume")
, std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), *p->resume_data);
if (h.is_paused() && !h.is_auto_managed()) ses.remove_torrent(h);
}
}
}
static char const* state_str[] =
{"checking (q)", "checking", "connecting", "dl metadata"
, "downloading", "finished", "seeding", "allocating"};
@ -1047,7 +1074,7 @@ int main(int ac, char* av[])
save_resume_data_alert const* rd = dynamic_cast<save_resume_data_alert const*>(a);
if (!rd)
{
std::cout << a->msg() << std::endl;
std::cout << a->message() << std::endl;
continue;
}
--num_resume_data;
@ -1133,78 +1160,22 @@ int main(int ac, char* av[])
while (a.get())
{
std::stringstream event_string;
if (a->severity() == alert::fatal)
event_string << esc("31"); // red
else if (a->severity() == alert::warning)
event_string << esc("33"); // yellow
event_string << now << ": ";
if (torrent_finished_alert* p = dynamic_cast<torrent_finished_alert*>(a.get()))
if (a->category() & alert::error_notification)
{
p->handle.set_max_connections(30);
// write resume data for the finished torrent
torrent_handle h = p->handle;
h.save_resume_data();
event_string << h.name() << ": " << a->msg();
event_string << esc("31");
}
else if (peer_error_alert* p = dynamic_cast<peer_error_alert*>(a.get()))
else if (a->category() & (alert::peer_notification | alert::storage_notification))
{
event_string << identify_client(p->pid) << ", " << p->ip << ": " << a->msg();
}
else if (invalid_request_alert* p = dynamic_cast<invalid_request_alert*>(a.get()))
{
event_string << identify_client(p->pid) << ": " << a->msg();
}
else if (tracker_warning_alert* p = dynamic_cast<tracker_warning_alert*>(a.get()))
{
event_string << "tracker message: " << p->msg() << " (" << p->url << ") (" << p->handle.name() << ")";
}
else if (tracker_reply_alert* p = dynamic_cast<tracker_reply_alert*>(a.get()))
{
event_string << p->msg() << " (" << p->num_peers << ") (" << p->url << ") (" << p->handle.name() << ")";
}
else if (url_seed_alert* p = dynamic_cast<url_seed_alert*>(a.get()))
{
event_string << "web seed '" << p->url << "': " << p->msg() << " (" << p->handle.name() << ")";
}
else if (peer_blocked_alert* p = dynamic_cast<peer_blocked_alert*>(a.get()))
{
event_string << "(" << p->ip << ") " << p->msg();
}
else if (save_resume_data_alert* p = dynamic_cast<save_resume_data_alert*>(a.get()))
{
torrent_handle h = p->handle;
event_string << "(" << h.name() << ") " << p->msg();
if (p->resume_data)
{
boost::filesystem::ofstream out(h.save_path() / (h.name() + ".fastresume"), std::ios_base::binary);
out.unsetf(std::ios_base::skipws);
bencode(std::ostream_iterator<char>(out), *p->resume_data);
if (h.is_paused() && !h.is_auto_managed()) ses.remove_torrent(h);
}
}
else if (state_changed_alert* p = dynamic_cast<state_changed_alert*>(a.get()))
{
std::string name;
if (p->handle.is_valid()) name = p->handle.name();
event_string << "(" << name << ") " << p->msg() << " " << state_str[p->state];
}
else if (torrent_alert* p = dynamic_cast<torrent_alert*>(a.get()))
{
std::string name;
if (p->handle.is_valid()) name = p->handle.name();
event_string << "(" << name << ") " << p->msg();
}
else
{
event_string << a->msg();
event_string << esc("33");
}
event_string << a->message();
event_string << esc("0");
events.push_back(event_string.str());
if (events.size() >= 20) events.pop_front();
::handle_alert(ses, a.get());
a = ses.pop_alert();
}

View File

@ -67,23 +67,40 @@ namespace libtorrent {
class TORRENT_EXPORT alert
{
public:
// only here for backwards compatibility
enum severity_t { debug, info, warning, critical, fatal, none };
alert(severity_t severity, const std::string& msg);
enum category_t
{
error_notification = 0x1,
peer_notification = 0x2,
port_mapping_notification = 0x4,
storage_notification = 0x8,
tracker_notification = 0x10,
debug_notification = 0x20,
status_notification = 0x40,
progress_notification = 0x80,
ip_block_notification = 0x100,
all_categories = 0xffffffff
};
alert();
virtual ~alert();
// a timestamp is automatically created in the constructor
ptime timestamp() const;
std::string const& msg() const;
virtual char const* what() const = 0;
virtual std::string message() const = 0;
virtual int category() const = 0;
severity_t severity() const;
severity_t severity() const TORRENT_DEPRECATED { return warning; }
virtual std::auto_ptr<alert> clone() const = 0;
private:
std::string m_msg;
severity_t m_severity;
ptime m_timestamp;
};
@ -97,16 +114,18 @@ namespace libtorrent {
bool pending() const;
std::auto_ptr<alert> get();
void set_severity(alert::severity_t severity);
bool should_post(alert::severity_t severity) const;
template <class T>
bool should_post() const { return m_alert_mask & T::static_category; }
alert const* wait_for_alert(time_duration max_wait);
void set_alert_mask(int m) { m_alert_mask = m; }
private:
std::queue<alert*> m_alerts;
alert::severity_t m_severity;
mutable boost::mutex m_mutex;
boost::condition m_condition;
int m_alert_mask;
};
struct TORRENT_EXPORT unhandled_alert : std::exception

File diff suppressed because it is too large Load Diff

View File

@ -211,7 +211,7 @@ namespace libtorrent
void check_torrent(boost::shared_ptr<torrent> const& t);
void done_checking(boost::shared_ptr<torrent> const& t);
void set_severity_level(alert::severity_t s);
void set_alert_mask(int m);
std::auto_ptr<alert> pop_alert();
alert const* wait_for_alert(time_duration max_wait);

View File

@ -317,7 +317,8 @@ namespace libtorrent
void set_max_half_open_connections(int limit);
std::auto_ptr<alert> pop_alert();
void set_severity_level(alert::severity_t s);
void set_severity_level(alert::severity_t s) TORRENT_DEPRECATED;
void set_alert_mask(int m);
alert const* wait_for_alert(time_duration max_wait);

View File

@ -35,38 +35,16 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/alert.hpp"
#include <boost/thread/xtime.hpp>
enum { queue_size_limit = 1000 };
namespace libtorrent {
alert::alert(severity_t severity, const std::string& msg)
: m_msg(msg)
, m_severity(severity)
, m_timestamp(time_now())
{
}
alert::~alert()
{
}
ptime alert::timestamp() const
{
return m_timestamp;
}
const std::string& alert::msg() const
{
return m_msg;
}
alert::severity_t alert::severity() const
{
return m_severity;
}
alert::alert() : m_timestamp(time_now()) {}
alert::~alert() {}
ptime alert::timestamp() const { return m_timestamp; }
alert_manager::alert_manager()
: m_severity(alert::fatal)
: m_alert_mask(alert::error_notification)
{}
alert_manager::~alert_manager()
@ -105,15 +83,8 @@ namespace libtorrent {
void alert_manager::post_alert(const alert& alert_)
{
boost::mutex::scoped_lock lock(m_mutex);
if (m_severity > alert_.severity()) return;
// the internal limit is 100 alerts
if (m_alerts.size() == 100)
{
alert* result = m_alerts.front();
m_alerts.pop();
delete result;
}
if (m_alerts.size() >= queue_size_limit) return;
m_alerts.push(alert_.clone().release());
m_condition.notify_all();
}
@ -136,17 +107,5 @@ namespace libtorrent {
return !m_alerts.empty();
}
void alert_manager::set_severity(alert::severity_t severity)
{
boost::mutex::scoped_lock lock(m_mutex);
m_severity = severity;
}
bool alert_manager::should_post(alert::severity_t severity) const
{
return severity >= m_severity;
}
} // namespace libtorrent

View File

@ -173,10 +173,10 @@ namespace libtorrent { namespace
m_metadata_progress = 0;
m_metadata_size = 0;
if (m_torrent.alerts().should_post(alert::info))
if (m_torrent.alerts().should_post<metadata_failed_alert>())
{
m_torrent.alerts().post_alert(metadata_failed_alert(
m_torrent.get_handle(), "invalid metadata received from swarm"));
m_torrent.get_handle()));
}
return false;

View File

@ -1378,14 +1378,10 @@ namespace libtorrent
write_reject_request(r);
++m_num_invalid_requests;
if (t->alerts().should_post(alert::debug))
if (t->alerts().should_post<invalid_request_alert>())
{
t->alerts().post_alert(invalid_request_alert(
r
, t->get_handle()
, m_remote
, m_peer_id
, "peer sent an illegal piece request"));
t->alerts().post_alert(invalid_request_alert(r
, t->get_handle(), m_remote, m_peer_id));
}
}
}
@ -1524,13 +1520,10 @@ namespace libtorrent
if (b == m_download_queue.end())
{
if (t->alerts().should_post(alert::debug))
if (t->alerts().should_post<peer_error_alert>())
{
t->alerts().post_alert(
peer_error_alert(
m_remote
, m_peer_id
, "got a block that was not in the request queue"));
t->alerts().post_alert(peer_error_alert(t->get_handle(), m_remote
, m_peer_id, "got a block that was not in the request queue"));
}
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_ERROR_LOGGING
(*m_logger) << " *** The block we just got was not in the "
@ -1637,7 +1630,7 @@ namespace libtorrent
return;
}
if (t->alerts().should_post(alert::fatal))
if (t->alerts().should_post<file_error_alert>())
{
t->alerts().post_alert(file_error_alert(j.error_file, t->get_handle(), j.str));
}
@ -1652,10 +1645,10 @@ namespace libtorrent
TORRENT_ASSERT(p.piece == j.piece);
TORRENT_ASSERT(p.start == j.offset);
picker.mark_as_finished(block_finished, peer_info_struct());
if (t->alerts().should_post(alert::debug))
if (t->alerts().should_post<block_finished_alert>())
{
t->alerts().post_alert(block_finished_alert(t->get_handle(),
block_finished.block_index, block_finished.piece_index, "block finished"));
block_finished.block_index, block_finished.piece_index));
}
// did we just finish the piece?
@ -1934,10 +1927,10 @@ namespace libtorrent
if (!t->picker().mark_as_downloading(block, peer_info_struct(), state))
return;
if (t->alerts().should_post(alert::debug))
if (t->alerts().should_post<block_downloading_alert>())
{
t->alerts().post_alert(block_downloading_alert(t->get_handle(),
speedmsg, block.block_index, block.piece_index, "block downloading"));
speedmsg, block.block_index, block.piece_index));
}
m_request_queue.push_back(block);
@ -2238,18 +2231,20 @@ namespace libtorrent
}
boost::shared_ptr<torrent> t = m_torrent.lock();
torrent_handle handle;
if (t) handle = t->get_handle();
if (message)
{
if (error > 1 && m_ses.m_alerts.should_post(alert::info))
if (error > 1 && m_ses.m_alerts.should_post<peer_error_alert>())
{
m_ses.m_alerts.post_alert(
peer_error_alert(remote(), pid(), message));
peer_error_alert(handle, remote(), pid(), message));
}
else if (error <= 1 && m_ses.m_alerts.should_post(alert::debug))
else if (error <= 1 && m_ses.m_alerts.should_post<peer_disconnected_alert>())
{
m_ses.m_alerts.post_alert(
peer_disconnected_alert(remote(), pid(), message));
peer_disconnected_alert(handle, remote(), pid(), message));
}
}
@ -2615,8 +2610,16 @@ namespace libtorrent
if (!m_download_queue.empty()
&& now > m_requested + seconds(m_ses.settings().request_timeout)
&& t->has_picker())
{
if (!m_snubbed)
{
m_snubbed = true;
if (m_ses.m_alerts.should_post<peer_snubbed_alert>())
{
m_ses.m_alerts.post_alert(peer_snubbed_alert(t->get_handle()
, m_remote, m_peer_id));
}
}
m_desired_queue_size = 1;
piece_picker& picker = t->picker();
// the front request timed out!
@ -2695,7 +2698,15 @@ namespace libtorrent
<< " " << total_seconds(now - m_last_piece) << "] ***\n";
#endif
if (!m_snubbed)
{
m_snubbed = true;
if (m_ses.m_alerts.should_post<peer_snubbed_alert>())
{
m_ses.m_alerts.post_alert(peer_snubbed_alert(t->get_handle()
, m_remote, m_peer_id));
}
}
m_desired_queue_size = 1;
if (t->is_seed())
@ -2843,10 +2854,8 @@ namespace libtorrent
return;
}
if (t->alerts().should_post(alert::fatal))
{
if (t->alerts().should_post<file_error_alert>())
t->alerts().post_alert(file_error_alert(j.error_file, t->get_handle(), j.str));
}
t->set_error(j.str);
t->pause();
return;
@ -3378,10 +3387,10 @@ namespace libtorrent
, bind(&peer_connection::on_connection_complete, self(), _1));
m_connect = time_now();
if (t->alerts().should_post(alert::debug))
if (t->alerts().should_post<peer_connect_alert>())
{
t->alerts().post_alert(peer_error_alert(
m_remote, m_peer_id, "connecting to peer"));
t->alerts().post_alert(peer_connect_alert(
t->get_handle(), m_remote));
}
}

View File

@ -359,21 +359,15 @@ namespace libtorrent
if (i->second.connection)
{
i->second.connection->disconnect("peer banned by IP filter");
if (ses.m_alerts.should_post(alert::info))
{
ses.m_alerts.post_alert(peer_blocked_alert(i->second.ip.address()
, "disconnected blocked peer"));
}
if (ses.m_alerts.should_post<peer_blocked_alert>())
ses.m_alerts.post_alert(peer_blocked_alert(i->second.ip.address()));
TORRENT_ASSERT(i->second.connection == 0
|| i->second.connection->peer_info_struct() == 0);
}
else
{
if (ses.m_alerts.should_post(alert::info))
{
ses.m_alerts.post_alert(peer_blocked_alert(i->second.ip.address()
, "blocked peer removed from peer list"));
}
if (ses.m_alerts.should_post<peer_blocked_alert>())
ses.m_alerts.post_alert(peer_blocked_alert(i->second.ip.address()));
}
erase_peer(i++);
}
@ -771,11 +765,8 @@ namespace libtorrent
port_filter const& pf = ses.m_port_filter;
if (pf.access(remote.port()) & port_filter::blocked)
{
if (ses.m_alerts.should_post(alert::info))
{
ses.m_alerts.post_alert(peer_blocked_alert(remote.address()
, "outgoing port blocked, peer not added to peer list"));
}
if (ses.m_alerts.should_post<peer_blocked_alert>())
ses.m_alerts.post_alert(peer_blocked_alert(remote.address()));
return 0;
}
@ -797,10 +788,9 @@ namespace libtorrent
// if the IP is blocked, don't add it
if (ses.m_ip_filter.access(remote.address()) & ip_filter::blocked)
{
if (ses.m_alerts.should_post(alert::info))
if (ses.m_alerts.should_post<peer_blocked_alert>())
{
ses.m_alerts.post_alert(peer_blocked_alert(remote.address()
, "blocked peer not added to peer list"));
ses.m_alerts.post_alert(peer_blocked_alert(remote.address()));
}
return 0;
}

View File

@ -513,9 +513,27 @@ namespace libtorrent
return m_impl->wait_for_alert(max_wait);
}
void session::set_alert_mask(int m)
{
m_impl->set_alert_mask(m);
}
void session::set_severity_level(alert::severity_t s)
{
m_impl->set_severity_level(s);
int m = 0;
switch (s)
{
case alert::debug: m = alert::all_categories; break;
case alert::info: m = alert::all_categories & ~(alert::debug_notification
| alert::progress_notification); break;
case alert::warning: m = alert::all_categories & ~(alert::debug_notification
| alert::status_notification | alert::progress_notification); break;
case alert::critical: m = alert::error_notification | alert::storage_notification; break;
case alert::fatal: m = alert::error_notification; break;
default: break;
}
m_impl->set_alert_mask(m);
}
void session::start_lsd()

View File

@ -605,13 +605,8 @@ namespace aux {
if (ec)
{
// not even that worked, give up
if (m_alerts.should_post(alert::fatal))
{
std::stringstream msg;
msg << "cannot bind to interface '";
print_endpoint(msg, ep) << "' " << ec.message();
m_alerts.post_alert(listen_failed_alert(ep, msg.str()));
}
if (m_alerts.should_post<listen_failed_alert>())
m_alerts.post_alert(listen_failed_alert(ep, ec));
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
std::stringstream msg;
msg << "cannot bind to interface '";
@ -624,13 +619,8 @@ namespace aux {
s.sock->listen(0, ec);
if (ec)
{
if (m_alerts.should_post(alert::fatal))
{
std::stringstream msg;
msg << "cannot listen on interface '";
print_endpoint(msg, ep) << "' " << ec.message();
m_alerts.post_alert(listen_failed_alert(ep, msg.str()));
}
if (m_alerts.should_post<listen_failed_alert>())
m_alerts.post_alert(listen_failed_alert(ep, ec));
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
std::stringstream msg;
msg << "cannot listen on interface '";
@ -640,12 +630,8 @@ namespace aux {
return listen_socket_t();
}
if (m_alerts.should_post(alert::fatal))
{
std::string msg = "listening on interface "
+ boost::lexical_cast<std::string>(ep);
m_alerts.post_alert(listen_succeeded_alert(ep, msg));
}
if (m_alerts.should_post<listen_succeeded_alert>())
m_alerts.post_alert(listen_succeeded_alert(ep));
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
(*m_logger) << "listening on: " << ep
@ -767,12 +753,8 @@ namespace aux {
|| e == asio::error::connection_aborted)
m_dht->on_unreachable(ep);
if (m_alerts.should_post(alert::info))
{
std::string msg = "UDP socket error from '"
+ boost::lexical_cast<std::string>(ep) + "' " + e.message();
m_alerts.post_alert(udp_error_alert(ep, msg));
}
if (m_alerts.should_post<udp_error_alert>())
m_alerts.post_alert(udp_error_alert(ep, e));
return;
}
@ -832,12 +814,8 @@ namespace aux {
return;
}
#endif
if (m_alerts.should_post(alert::fatal))
{
std::string msg = "error accepting connection on '"
+ boost::lexical_cast<std::string>(ep) + "' " + e.message();
m_alerts.post_alert(listen_failed_alert(ep, msg));
}
if (m_alerts.should_post<listen_failed_alert>())
m_alerts.post_alert(listen_failed_alert(ep, e));
return;
}
async_accept(listener);
@ -870,11 +848,8 @@ namespace aux {
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
(*m_logger) << "filtered blocked ip\n";
#endif
if (m_alerts.should_post(alert::info))
{
m_alerts.post_alert(peer_blocked_alert(endp.address()
, "incoming connection blocked by IP filter"));
}
if (m_alerts.should_post<peer_blocked_alert>())
m_alerts.post_alert(peer_blocked_alert(endp.address()));
return;
}
@ -1108,11 +1083,10 @@ namespace aux {
m_tracker_manager.queue_request(m_io_service, m_half_open, req
, t.tracker_login(), m_listen_interface.address(), i->second);
if (m_alerts.should_post(alert::info))
if (m_alerts.should_post<tracker_announce_alert>())
{
m_alerts.post_alert(
tracker_announce_alert(
t.get_handle(), req.url, "tracker announce"));
tracker_announce_alert(t.get_handle(), req.url));
}
}
@ -1867,11 +1841,10 @@ namespace aux {
, t.tracker_login(), m_listen_interface.address());
#endif
if (m_alerts.should_post(alert::info))
if (m_alerts.should_post<tracker_announce_alert>())
{
m_alerts.post_alert(
tracker_announce_alert(
t.get_handle(), req.url, "tracker announce, event=stopped"));
tracker_announce_alert(t.get_handle(), req.url));
}
}
#ifndef NDEBUG
@ -1984,9 +1957,9 @@ namespace aux {
{
m_external_udp_port = port;
m_dht_settings.service_port = port;
if (m_alerts.should_post(alert::info))
if (m_alerts.should_post<portmap_alert>())
m_alerts.post_alert(portmap_alert(mapping, port
, map_transport, "successfully mapped UDP port"));
, map_transport));
return;
}
#endif
@ -1995,23 +1968,23 @@ namespace aux {
{
if (!m_listen_sockets.empty())
m_listen_sockets.front().external_port = port;
if (m_alerts.should_post(alert::info))
if (m_alerts.should_post<portmap_alert>())
m_alerts.post_alert(portmap_alert(mapping, port
, map_transport, "successfully mapped TCP port"));
, map_transport));
return;
}
if (!errmsg.empty())
{
if (m_alerts.should_post(alert::warning))
if (m_alerts.should_post<portmap_error_alert>())
m_alerts.post_alert(portmap_error_alert(mapping
, map_transport, errmsg));
}
else
{
if (m_alerts.should_post(alert::warning))
if (m_alerts.should_post<portmap_alert>())
m_alerts.post_alert(portmap_alert(mapping, port
, map_transport, "successfully mapped port"));
, map_transport));
}
}
@ -2309,10 +2282,10 @@ namespace aux {
return m_alerts.wait_for_alert(max_wait);
}
void session_impl::set_severity_level(alert::severity_t s)
void session_impl::set_alert_mask(int m)
{
mutex_t::scoped_lock l(m_mutex);
m_alerts.set_severity(s);
m_alerts.set_alert_mask(m);
}
int session_impl::upload_rate_limit() const
@ -2437,13 +2410,8 @@ namespace aux {
if (m_external_address == ip) return;
m_external_address = ip;
if (m_alerts.should_post(alert::info))
{
std::stringstream msg;
msg << "external address is '";
print_address(msg, ip) << "'";
m_alerts.post_alert(external_ip_alert(ip, msg.str()));
}
if (m_alerts.should_post<external_ip_alert>())
m_alerts.post_alert(external_ip_alert(ip));
}
void session_impl::free_disk_buffer(char* buf)

View File

@ -297,7 +297,7 @@ namespace libtorrent
+ m_resume_data.size(), m_resume_entry) != 0)
{
std::vector<char>().swap(m_resume_data);
if (m_ses.m_alerts.should_post(alert::warning))
if (m_ses.m_alerts.should_post<fastresume_rejected_alert>())
{
m_ses.m_alerts.post_alert(fastresume_rejected_alert(get_handle(), "parse failed"));
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
@ -461,7 +461,7 @@ namespace libtorrent
if (!error && sha1_hash(info_hash) != m_torrent_file->info_hash())
error = "mismatching info-hash";
if (error && m_ses.m_alerts.should_post(alert::warning))
if (error && m_ses.m_alerts.should_post<fastresume_rejected_alert>())
{
m_ses.m_alerts.post_alert(fastresume_rejected_alert(get_handle(), error));
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
@ -493,7 +493,7 @@ namespace libtorrent
if (ret == piece_manager::fatal_disk_error)
{
if (m_ses.m_alerts.should_post(alert::fatal))
if (m_ses.m_alerts.should_post<file_error_alert>())
{
m_ses.m_alerts.post_alert(file_error_alert(j.error_file, get_handle(), j.str));
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
@ -552,7 +552,7 @@ namespace libtorrent
bool fastresume_rejected = !j.str.empty();
if (fastresume_rejected && m_ses.m_alerts.should_post(alert::warning))
if (fastresume_rejected && m_ses.m_alerts.should_post<fastresume_rejected_alert>())
{
m_ses.m_alerts.post_alert(fastresume_rejected_alert(get_handle(), j.str));
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
@ -672,7 +672,7 @@ namespace libtorrent
if (ret == piece_manager::fatal_disk_error)
{
if (m_ses.m_alerts.should_post(alert::fatal))
if (m_ses.m_alerts.should_post<file_error_alert>())
{
m_ses.m_alerts.post_alert(file_error_alert(j.error_file, get_handle(), j.str));
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
@ -710,7 +710,7 @@ namespace libtorrent
}
if (ret == piece_manager::fatal_disk_error)
{
if (m_ses.m_alerts.should_post(alert::fatal))
if (m_ses.m_alerts.should_post<file_error_alert>())
{
m_ses.m_alerts.post_alert(file_error_alert(j.error_file, get_handle(), j.str));
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
@ -809,10 +809,10 @@ namespace libtorrent
{
if (peers.empty()) return;
if (m_ses.m_alerts.should_post(alert::info))
if (m_ses.m_alerts.should_post<dht_reply_alert>())
{
m_ses.m_alerts.post_alert(tracker_reply_alert(
get_handle(), peers.size(), "DHT", "Got peers from DHT"));
m_ses.m_alerts.post_alert(dht_reply_alert(
get_handle(), peers.size()));
}
std::for_each(peers.begin(), peers.end(), bind(
&policy::peer_from_tracker, boost::ref(m_policy), _1, peer_id(0)
@ -861,11 +861,9 @@ namespace libtorrent
INVARIANT_CHECK;
if (m_ses.m_alerts.should_post(alert::warning))
{
if (m_ses.m_alerts.should_post<tracker_warning_alert>())
m_ses.m_alerts.post_alert(tracker_warning_alert(get_handle(), req.url, msg));
}
}
void torrent::tracker_scrape_response(tracker_request const& req
, int complete, int incomplete, int downloaded)
@ -878,10 +876,10 @@ namespace libtorrent
if (complete >= 0) m_complete = complete;
if (incomplete >= 0) m_incomplete = incomplete;
if (m_ses.m_alerts.should_post(alert::info))
if (m_ses.m_alerts.should_post<scrape_reply_alert>())
{
m_ses.m_alerts.post_alert(scrape_reply_alert(
get_handle(), m_incomplete, m_complete, req.url, "got scrape response from tracker"));
get_handle(), m_incomplete, m_complete, req.url));
}
}
@ -964,11 +962,8 @@ namespace libtorrent
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
debug_log("blocked ip from tracker: " + i->ip);
#endif
if (m_ses.m_alerts.should_post(alert::info))
{
m_ses.m_alerts.post_alert(peer_blocked_alert(a.address()
, "peer from tracker blocked by IP filter"));
}
if (m_ses.m_alerts.should_post<peer_blocked_alert>())
m_ses.m_alerts.post_alert(peer_blocked_alert(a.address()));
continue;
}
@ -977,10 +972,10 @@ namespace libtorrent
}
}
if (m_ses.m_alerts.should_post(alert::info))
if (m_ses.m_alerts.should_post<tracker_reply_alert>())
{
m_ses.m_alerts.post_alert(tracker_reply_alert(
get_handle(), peer_list.size(), r.url, "got response from tracker"));
get_handle(), peer_list.size(), r.url));
}
m_got_tracker_response = true;
}
@ -1000,10 +995,9 @@ namespace libtorrent
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
debug_log("blocked ip from tracker: " + host->endpoint().address().to_string());
#endif
if (m_ses.m_alerts.should_post(alert::info))
if (m_ses.m_alerts.should_post<peer_blocked_alert>())
{
m_ses.m_alerts.post_alert(peer_blocked_alert(host->endpoint().address()
, "peer from tracker blocked by IP filter"));
m_ses.m_alerts.post_alert(peer_blocked_alert(host->endpoint().address()));
}
return;
@ -1276,10 +1270,10 @@ namespace libtorrent
TORRENT_ASSERT(index >= 0);
TORRENT_ASSERT(index < m_torrent_file->num_pieces());
if (m_ses.m_alerts.should_post(alert::debug))
if (m_ses.m_alerts.should_post<piece_finished_alert>())
{
m_ses.m_alerts.post_alert(piece_finished_alert(get_handle()
, index, "piece finished"));
, index));
}
bool was_finished = m_picker->num_filtered() + num_have()
@ -1365,12 +1359,9 @@ namespace libtorrent
TORRENT_ASSERT(index >= 0);
TORRENT_ASSERT(index < m_torrent_file->num_pieces());
if (m_ses.m_alerts.should_post(alert::info))
{
std::stringstream s;
s << "hash for piece " << index << " failed";
m_ses.m_alerts.post_alert(hash_failed_alert(get_handle(), index, s.str()));
}
if (m_ses.m_alerts.should_post<hash_failed_alert>())
m_ses.m_alerts.post_alert(hash_failed_alert(get_handle(), index));
// increase the total amount of failed bytes
m_total_failed_bytes += m_torrent_file->piece_size(index);
@ -1424,12 +1415,10 @@ namespace libtorrent
{
// we don't trust this peer anymore
// ban it.
if (m_ses.m_alerts.should_post(alert::info))
if (m_ses.m_alerts.should_post<peer_ban_alert>())
{
m_ses.m_alerts.post_alert(peer_ban_alert(
p->ip
, get_handle()
, "banning peer because of too many corrupt pieces"));
p->ip, get_handle()));
}
// mark the peer as banned
@ -1539,16 +1528,15 @@ namespace libtorrent
{
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
if (alerts().should_post(alert::warning))
{
if (ret != 0)
{
alerts().post_alert(torrent_deleted_alert(get_handle(), "delete files failed: " + j.str));
if (alerts().should_post<torrent_delete_failed_alert>())
alerts().post_alert(torrent_delete_failed_alert(get_handle(), j.str));
}
else
{
alerts().post_alert(torrent_deleted_alert(get_handle(), "files deleted"));
}
if (alerts().should_post<torrent_deleted_alert>())
alerts().post_alert(torrent_deleted_alert(get_handle()));
}
}
@ -1557,9 +1545,9 @@ namespace libtorrent
/*
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
if (alerts().should_post(alert::warning))
if (alerts().should_post<torrent_paused_alert>())
{
alerts().post_alert(torrent_paused_alert(get_handle(), "torrent paused"));
alerts().post_alert(torrent_paused_alert(get_handle()));
}
*/
}
@ -1568,20 +1556,17 @@ namespace libtorrent
{
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
if (alerts().should_post(alert::warning))
if (!j.resume_data && alerts().should_post<save_resume_data_failed_alert>())
{
char const* msg;
if (j.resume_data)
alerts().post_alert(save_resume_data_failed_alert(get_handle(), j.str));
return;
}
if (j.resume_data && alerts().should_post<save_resume_data_alert>())
{
write_resume_data(*j.resume_data);
msg = "resume data generated";
}
else
{
msg = j.str.c_str();
}
alerts().post_alert(save_resume_data_alert(j.resume_data
, get_handle(), msg));
, get_handle()));
}
}
@ -1589,14 +1574,17 @@ namespace libtorrent
{
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
if (alerts().should_post(alert::warning))
{
if (ret == 0)
alerts().post_alert(file_renamed_alert(get_handle(), j.str
, "renamed file: " + j.str));
{
if (alerts().should_post<file_renamed_alert>())
alerts().post_alert(file_renamed_alert(get_handle(), j.str, j.piece));
}
else
alerts().post_alert(file_renamed_alert(get_handle(), "", j.str));
{
if (alerts().should_post<file_rename_failed_alert>())
alerts().post_alert(file_rename_failed_alert(get_handle(), j.str, j.piece));
}
}
}
@ -1604,10 +1592,8 @@ namespace libtorrent
{
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
if (alerts().should_post(alert::warning))
{
alerts().post_alert(torrent_paused_alert(get_handle(), "torrent paused"));
}
if (alerts().should_post<torrent_paused_alert>())
alerts().post_alert(torrent_paused_alert(get_handle()));
}
std::string torrent::tracker_login() const
@ -2050,7 +2036,7 @@ namespace libtorrent
if (protocol != "http")
#endif
{
if (m_ses.m_alerts.should_post(alert::warning))
if (m_ses.m_alerts.should_post<url_seed_alert>())
{
m_ses.m_alerts.post_alert(
url_seed_alert(get_handle(), url, "unknown protocol"));
@ -2062,7 +2048,7 @@ namespace libtorrent
if (hostname.empty())
{
if (m_ses.m_alerts.should_post(alert::warning))
if (m_ses.m_alerts.should_post<url_seed_alert>())
{
m_ses.m_alerts.post_alert(
url_seed_alert(get_handle(), url, "invalid hostname"));
@ -2074,7 +2060,7 @@ namespace libtorrent
if (port == 0)
{
if (m_ses.m_alerts.should_post(alert::warning))
if (m_ses.m_alerts.should_post<url_seed_alert>())
{
m_ses.m_alerts.post_alert(
url_seed_alert(get_handle(), url, "invalid port"));
@ -2099,7 +2085,7 @@ namespace libtorrent
{
if (m_ses.m_port_filter.access(port) & port_filter::blocked)
{
if (m_ses.m_alerts.should_post(alert::warning))
if (m_ses.m_alerts.should_post<url_seed_alert>())
{
m_ses.m_alerts.post_alert(
url_seed_alert(get_handle(), url, "port blocked by port-filter"));
@ -2130,7 +2116,7 @@ namespace libtorrent
if (e || host == tcp::resolver::iterator())
{
if (m_ses.m_alerts.should_post(alert::warning))
if (m_ses.m_alerts.should_post<url_seed_alert>())
{
m_ses.m_alerts.post_alert(
url_seed_alert(get_handle(), url, e.message()));
@ -2155,7 +2141,7 @@ namespace libtorrent
if (error)
{
if (m_ses.m_alerts.should_post(alert::warning))
if (m_ses.m_alerts.should_post<url_seed_alert>())
{
m_ses.m_alerts.post_alert(
url_seed_alert(get_handle(), url, error));
@ -2166,11 +2152,8 @@ namespace libtorrent
if (m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked)
{
if (m_ses.m_alerts.should_post(alert::info))
{
m_ses.m_alerts.post_alert(peer_blocked_alert(a.address()
, "proxy (" + hostname + ") blocked by IP filter"));
}
if (m_ses.m_alerts.should_post<peer_blocked_alert>())
m_ses.m_alerts.post_alert(peer_blocked_alert(a.address()));
return;
}
@ -2195,7 +2178,7 @@ namespace libtorrent
if (e || host == tcp::resolver::iterator())
{
if (m_ses.m_alerts.should_post(alert::warning))
if (m_ses.m_alerts.should_post<url_seed_alert>())
{
std::stringstream msg;
msg << "HTTP seed hostname lookup failed: " << e.message();
@ -2218,11 +2201,8 @@ namespace libtorrent
if (m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked)
{
if (m_ses.m_alerts.should_post(alert::info))
{
m_ses.m_alerts.post_alert(peer_blocked_alert(a.address()
, "web seed (" + url + ") blocked by IP filter"));
}
if (m_ses.m_alerts.should_post<peer_blocked_alert>())
m_ses.m_alerts.post_alert(peer_blocked_alert(a.address()));
return;
}
@ -2770,10 +2750,10 @@ namespace libtorrent
return false;
}
if (m_ses.m_alerts.should_post(alert::info))
if (m_ses.m_alerts.should_post<metadata_received_alert>())
{
m_ses.m_alerts.post_alert(metadata_received_alert(
get_handle(), "metadata successfully received from swarm"));
get_handle()));
}
init();
@ -3054,11 +3034,10 @@ namespace libtorrent
{
INVARIANT_CHECK;
if (alerts().should_post(alert::info))
if (alerts().should_post<torrent_finished_alert>())
{
alerts().post_alert(torrent_finished_alert(
get_handle()
, "torrent has finished downloading"));
get_handle()));
}
set_state(torrent_status::finished);
@ -3243,11 +3222,10 @@ namespace libtorrent
}
}
if (m_ses.m_alerts.should_post(alert::info))
if (m_ses.m_alerts.should_post<torrent_checked_alert>())
{
m_ses.m_alerts.post_alert(torrent_checked_alert(
get_handle()
, "torrent finished checking"));
get_handle()));
}
m_files_checked = true;
@ -3296,7 +3274,7 @@ namespace libtorrent
{
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
if (alerts().should_post(alert::warning))
if (alerts().should_post<storage_moved_alert>())
{
alerts().post_alert(storage_moved_alert(get_handle(), j.str));
}
@ -3682,10 +3660,10 @@ namespace libtorrent
if (m_state == torrent_status::queued_for_checking
|| m_state == torrent_status::checking_files)
{
if (alerts().should_post(alert::warning))
if (alerts().should_post<save_resume_data_failed_alert>())
{
alerts().post_alert(save_resume_data_alert(boost::shared_ptr<entry>()
, get_handle(), "won't save resume data, torrent does not have a complete resume state yet"));
alerts().post_alert(save_resume_data_failed_alert(get_handle()
, "won't save resume data, torrent does not have a complete resume state yet"));
}
}
else
@ -3696,10 +3674,10 @@ namespace libtorrent
}
else
{
if (alerts().should_post(alert::warning))
if (alerts().should_post<save_resume_data_failed_alert>())
{
alerts().post_alert(save_resume_data_alert(boost::shared_ptr<entry>()
, get_handle(), "save resume data failed, torrent is being destructed"));
alerts().post_alert(save_resume_data_failed_alert(get_handle()
, "save resume data failed, torrent is being destructed"));
}
}
}
@ -3759,10 +3737,8 @@ namespace libtorrent
}
else
{
if (alerts().should_post(alert::warning))
{
alerts().post_alert(torrent_paused_alert(get_handle(), "torrent paused"));
}
if (alerts().should_post<torrent_paused_alert>())
alerts().post_alert(torrent_paused_alert(get_handle()));
}
}
@ -3796,10 +3772,8 @@ namespace libtorrent
m_started = time_now();
m_error.clear();
if (alerts().should_post(alert::warning))
{
alerts().post_alert(torrent_resumed_alert(get_handle(), "torrent resumed"));
}
if (alerts().should_post<torrent_resumed_alert>())
alerts().post_alert(torrent_resumed_alert(get_handle()));
// tell the tracker that we're back
m_event = tracker_request::started;
@ -3982,10 +3956,8 @@ namespace libtorrent
if (ret == -1)
{
if (alerts().should_post(alert::fatal))
{
if (alerts().should_post<file_error_alert>())
alerts().post_alert(file_error_alert(j.error_file, get_handle(), j.str));
}
m_error = j.str;
pause();
}
@ -4043,11 +4015,8 @@ namespace libtorrent
{
if (m_state == s) return;
m_state = s;
if (m_ses.m_alerts.should_post(alert::info))
{
m_ses.m_alerts.post_alert(state_changed_alert(get_handle()
, s, "torrent status changed"));
}
if (m_ses.m_alerts.should_post<state_changed_alert>())
m_ses.m_alerts.post_alert(state_changed_alert(get_handle(), s));
}
torrent_status torrent::status() const
@ -4215,16 +4184,20 @@ namespace libtorrent
debug_log("*** tracker timed out");
#endif
if (m_ses.m_alerts.should_post(alert::warning))
{
if (r.kind == tracker_request::announce_request)
{
if (m_ses.m_alerts.should_post<tracker_error_alert>())
{
m_ses.m_alerts.post_alert(tracker_error_alert(get_handle()
, m_failed_trackers + 1, 0, r.url, "tracker timed out"));
}
}
else if (r.kind == tracker_request::scrape_request)
{
m_ses.m_alerts.post_alert(scrape_failed_alert(get_handle(), r.url, "tracker timed out"));
if (m_ses.m_alerts.should_post<scrape_failed_alert>())
{
m_ses.m_alerts.post_alert(scrape_failed_alert(get_handle()
, r.url, "tracker timed out"));
}
}
@ -4245,14 +4218,17 @@ namespace libtorrent
#if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING || defined TORRENT_ERROR_LOGGING
debug_log(std::string("*** tracker error: ") + str);
#endif
if (m_ses.m_alerts.should_post(alert::warning))
{
if (r.kind == tracker_request::announce_request)
{
if (m_ses.m_alerts.should_post<tracker_error_alert>())
{
m_ses.m_alerts.post_alert(tracker_error_alert(get_handle()
, m_failed_trackers + 1, response_code, r.url, str));
}
}
else if (r.kind == tracker_request::scrape_request)
{
if (m_ses.m_alerts.should_post<scrape_failed_alert>())
{
m_ses.m_alerts.post_alert(scrape_failed_alert(get_handle(), r.url, str));
}

View File

@ -139,10 +139,10 @@ namespace libtorrent { namespace
{
std::fill(m_requested_metadata.begin(), m_requested_metadata.end(), 0);
if (m_torrent.alerts().should_post(alert::info))
if (m_torrent.alerts().should_post<metadata_failed_alert>())
{
m_torrent.alerts().post_alert(metadata_failed_alert(
m_torrent.get_handle(), "invalid metadata received from swarm"));
m_torrent.get_handle()));
}
return false;

View File

@ -386,7 +386,7 @@ namespace libtorrent
t->remove_url_seed(m_url);
std::string error_msg = boost::lexical_cast<std::string>(m_parser.status_code())
+ " " + m_parser.message();
if (m_ses.m_alerts.should_post(alert::warning))
if (m_ses.m_alerts.should_post<url_seed_alert>())
{
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
m_ses.m_alerts.post_alert(url_seed_alert(t->get_handle(), url()