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) scope alert_scope = class_<alert, noncopyable>("alert", alert_doc, no_init)
.def( .def("message", &alert::message, alert_msg_doc)
"msg", &alert::msg, return_value_policy<copy_const_reference>() .def("what", &alert::what)
, alert_msg_doc .def("category", &alert::category)
)
.def("severity", &alert::severity, alert_severity_doc) .def("severity", &alert::severity, alert_severity_doc)
.def( .def("__str__", &alert::message, alert_msg_doc)
"__str__", &alert::msg, return_value_policy<copy_const_reference>()
, alert_msg_doc
)
; ;
enum_<alert::severity_t>("severity_levels") enum_<alert::severity_t>("severity_levels")
@ -72,6 +68,19 @@ void bind_alert()
.value("fatal", alert::fatal) .value("fatal", alert::fatal)
.value("none", alert::none) .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>( class_<torrent_alert, bases<alert>, noncopyable>(

View File

@ -323,6 +323,7 @@ void bind_session()
"set_severity_level", allow_threads(&session::set_severity_level) "set_severity_level", allow_threads(&session::set_severity_level)
, session_set_severity_level_doc , 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("pop_alert", allow_threads(&session::pop_alert), session_pop_alert_doc)
.def("add_extension", &add_extension) .def("add_extension", &add_extension)
.def("set_peer_proxy", allow_threads(&session::set_peer_proxy)) .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"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <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> <title>libtorrent manual</title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" /> <meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
<link rel="stylesheet" href="style.css" type="text/css" /> <link rel="stylesheet" href="style.css" type="text/css" />
@ -16,40 +16,40 @@
<col class="docinfo-content" /> <col class="docinfo-content" />
<tbody valign="top"> <tbody valign="top">
<tr><th class="docinfo-name">Author:</th> <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> </tbody>
</table> </table>
<div class="contents topic" id="table-of-contents"> <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"> <ul class="simple">
<li><a class="reference internal" href="#downloading-and-building" id="id9">downloading and building</a><ul> <li><a class="reference" href="#downloading-and-building" id="id9" name="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" href="#building-from-svn" id="id10" name="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" href="#building-with-bbv2" id="id11" name="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" href="#building-with-autotools" id="id12" name="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" href="#building-with-other-build-systems" id="id13" name="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="#build-configurations" id="id14" name="id14">build configurations</a></li>
</ul> </ul>
</li> </li>
</ul> </ul>
</div> </div>
<div class="section" id="downloading-and-building"> <div class="section">
<h1>downloading and building</h1> <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. <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 <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 (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> 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> 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> <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" id="building-from-svn"> <div class="section">
<h2>building from svn</h2> <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 <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. sourceforge and also check out the asio sources from its sourceforge cvs.
If you downloaded a release tarball, you can skip this section.</p> If you downloaded a release tarball, you can skip this section.</p>
<p>To prepare the directory structure for building, follow these steps:</p> <p>To prepare the directory structure for building, follow these steps:</p>
<ul class="simple"> <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 libtorrent (<a class="reference" 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 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> <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> 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> <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 <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> of the following sections depending on which build system you prefer to use.</p>
</div> </div>
<div class="section" id="building-with-bbv2"> <div class="section">
<h2>building with BBv2</h2> <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 <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 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> for some details on this issue).</p>
<p>Since BBv2 will build the boost libraries for you, you need the full boost <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 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> usually not set by the package installer).</p>
<p>If you want to build against an installed copy of boost, you can skip directly <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> to step 3 (assuming you also have boost build installed).</p>
<div class="section" id="step-1-download-boost"> <div class="section">
<h3>Step 1: Download boost</h3> <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 external" href="http://sourceforge.net/project/showfiles.php?group_id=7586&amp;package_id=8041&amp;release_id=376197">here</a>.</p> <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 <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 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 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 to use the autotools). You'll need at least version 1.34 of the boost library
in order to build libtorrent.</p> in order to build libtorrent.</p>
</div> </div>
<div class="section" id="step-2-setup-bbv2"> <div class="section">
<h3>Step 2: Setup BBv2</h3> <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 <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 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 <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 ; using darwin : 4.0 : g++-4.0 ;
</pre> </pre>
<p>Note that the spaces around the semi-colons and colons are important!</p> <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>
<div class="section" id="step-3-building-libtorrent"> <div class="section">
<h3>Step 3: Building libtorrent</h3> <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 <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 <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 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 <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> 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. <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> <p>Build features:</p>
<table border="1" class="docutils"> <table border="1" class="docutils">
<colgroup> <colgroup>
@ -219,6 +219,15 @@ boost directory.</li>
</ul> </ul>
</td> </td>
</tr> </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> <tr><td><tt class="docutils literal"><span class="pre">logging</span></tt></td>
<td><ul class="first last simple"> <td><ul class="first last simple">
<li><tt class="docutils literal"><span class="pre">none</span></tt> - no logging.</li> <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> <tr><td><tt class="docutils literal"><span class="pre">geoip</span></tt></td>
<td><ul class="first last simple"> <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">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 in statically. Note that this code is under
LGPL license.</li> 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 is expected to be installed on the system and
it will be used.</li> it will be used.</li>
</ul> </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 <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 <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> 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 <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 external" href="http://www.boost.org/doc/html/bbv2/reference.html#bbv2.advanced.builtins.features">the section on builtin features</a>.</p> 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> </div>
<div class="section" id="building-with-autotools"> <div class="section">
<h2>building with autotools</h2> <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 <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> unix/linux systems comes with these preinstalled.</p>
<p>The prerequisites for building libtorrent are boost.thread, boost.date_time <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> 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 <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> and boost.program_options.</p>
<div class="section" id="step-1-generating-the-build-system"> <div class="section">
<h3>Step 1: Generating the build system</h3> <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 <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, 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 <p>Execute the following commands, in the given order, to generate
the build system:</p> the build system:</p>
<pre class="literal-block"> <pre class="literal-block">
@ -404,8 +413,8 @@ autoconf
</pre> </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> <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>
<div class="section" id="step-2-running-configure"> <div class="section">
<h3>Step 2: Running configure</h3> <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 <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 <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 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 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> spaces in their names to remove the spaces or move the libtorrent directory.</p>
</div> </div>
<div class="section" id="creating-a-debug-build"> <div class="section">
<h3>Creating a debug build</h3> <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 <p>To tell configure to build a debug version (with debug info, asserts
and invariant checks enabled), you have to run the configure script and invariant checks enabled), you have to run the configure script
with the following option:</p> with the following option:</p>
@ -462,8 +471,8 @@ with the following option:</p>
./configure --enable-debug=yes ./configure --enable-debug=yes
</pre> </pre>
</div> </div>
<div class="section" id="creating-a-release-build"> <div class="section">
<h3>Creating a release build</h3> <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, <p>To tell the configure to build a release version (without debug info,
asserts and invariant checks), you have to run the configure script asserts and invariant checks), you have to run the configure script
with the following option:</p> with the following option:</p>
@ -472,8 +481,8 @@ with the following option:</p>
</pre> </pre>
<p>The above option make use of -DNDEBUG, which is used throughout libtorrent.</p> <p>The above option make use of -DNDEBUG, which is used throughout libtorrent.</p>
</div> </div>
<div class="section" id="id8"> <div class="section">
<h3>Step 3: Building libtorrent</h3> <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 <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> 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 <p>When libtorrent is built it may be a good idea to run the tests, you do this
@ -487,8 +496,8 @@ make
</pre> </pre>
</div> </div>
</div> </div>
<div class="section" id="building-with-other-build-systems"> <div class="section">
<h2>building with other build systems</h2> <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 <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 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 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 <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 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 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>
<div class="section" id="build-configurations"> <div class="section">
<h2>build configurations</h2> <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 <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 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 (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"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head> <head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <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> <title></title>
<meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" /> <meta name="author" content="Arvid Norberg, arvid&#64;rasterbar.com" />
<link rel="stylesheet" href="style.css" type="text/css" /> <link rel="stylesheet" href="style.css" type="text/css" />
</head> </head>
<body> <body>
<div class="document"> <div class="document">
<table class="docinfo" frame="void" rules="none"> <table class="docinfo" frame="void" rules="none">
<col class="docinfo-name" /> <col class="docinfo-name" />
<col class="docinfo-content" /> <col class="docinfo-content" />
<tbody valign="top"> <tbody valign="top">
<tr><th class="docinfo-name">Author:</th> <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> </tbody>
</table> </table>
<div class="section" id="libtorrent-plugins"> <div class="section">
<h1>libtorrent plugins</h1> <h1><a id="libtorrent-plugins" name="libtorrent-plugins">libtorrent plugins</a></h1>
<div class="contents topic" id="contents"> <div class="contents topic" id="table-of-contents">
<p class="topic-title first">Contents</p> <p class="topic-title first"><a id="contents" name="contents">Contents</a></p>
<ul class="simple"> <ul class="simple">
<li><a class="reference internal" href="#libtorrent-plugins" id="id1">libtorrent plugins</a><ul> <li><a class="reference" href="#libtorrent-plugins" id="id1" name="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="#a-word-of-caution" id="id2" name="id2">a word of caution</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#plugin-interface" id="id3">plugin interface</a></li> <li><a class="reference" href="#plugin-interface" id="id3" name="id3">plugin interface</a></li>
<li><a class="reference internal" href="#torrent-plugin" id="id4">torrent_plugin</a><ul> <li><a class="reference" href="#torrent-plugin" id="id4" name="id4">torrent_plugin</a><ul>
<li><a class="reference internal" href="#new-connection" id="id5">new_connection()</a></li> <li><a class="reference" href="#new-connection" id="id5" name="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" href="#on-piece-pass-on-piece-fail" id="id6" name="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" href="#tick" id="id7" name="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" href="#on-pause-on-resume" id="id8" name="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="#on-files-checked" id="id9" name="id9">on_files_checked()</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference internal" href="#peer-plugin" id="id10">peer_plugin</a></li> <li><a class="reference" href="#peer-plugin" id="id10" name="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="#disk-buffer-holder" id="id11" name="id11">disk_buffer_holder</a></li>
</ul> </ul>
</div> </div>
<p>libtorrent has a plugin interface for implementing extensions to the protocol. <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> <p>In short, the plugin interface makes it possible to:</p>
<ul class="simple"> <ul class="simple">
<li>register extension messages (sent in the extension handshake), see <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>add data and parse data from the extension handshake.</li>
<li>send extension messages and standard bittorrent messages.</li> <li>send extension messages and standard bittorrent messages.</li>
<li>override or block the handling of standard bittorrent messages.</li> <li>override or block the handling of standard bittorrent messages.</li>
</ul> </ul>
<div class="section" id="a-word-of-caution"> <div class="section">
<h2>a word of caution</h2> <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 <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 dead locks and race conditions. Since a plugin has access to internal
structures it is also quite easy to sabotage libtorrent's operation.</p> 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 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 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 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> 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> </div>
<div class="section" id="plugin-interface"> <div class="section">
<h1>plugin interface</h1> <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 <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 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> 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 <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> will be made on torrent events.</p>
</div> </div>
<div class="section" id="torrent-plugin"> <div class="section">
<h1>torrent_plugin</h1> <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> <p>The synopsis for <tt class="docutils literal"><span class="pre">torrent_plugin</span></tt> follows:</p>
<pre class="literal-block"> <pre class="literal-block">
struct torrent_plugin 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 <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 as an extension) instantiated for each torrent in the session. The callback
hook functions are defined as follows.</p> hook functions are defined as follows.</p>
<div class="section" id="new-connection"> <div class="section">
<h2>new_connection()</h2> <h2><a id="new-connection" name="new-connection">new_connection()</a></h2>
<pre class="literal-block"> <pre class="literal-block">
boost::shared_ptr&lt;peer_plugin&gt; new_connection(peer_connection*); boost::shared_ptr&lt;peer_plugin&gt; new_connection(peer_connection*);
</pre> </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> 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> <p>If this function throws an exception, the connection will be closed.</p>
</div> </div>
<div class="section" id="on-piece-pass-on-piece-fail"> <div class="section">
<h2>on_piece_pass() on_piece_fail()</h2> <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"> <pre class="literal-block">
void on_piece_pass(int index); void on_piece_pass(int index);
void on_piece_failed(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 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> 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>
<div class="section" id="tick"> <div class="section">
<h2>tick()</h2> <h2><a id="tick" name="tick">tick()</a></h2>
<pre class="literal-block"> <pre class="literal-block">
void tick(); void tick();
</pre> </pre>
<p>This hook is called approximately once per second. It is a way of making it <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> easy for plugins to do timed events, for sending messages or whatever.</p>
</div> </div>
<div class="section" id="on-pause-on-resume"> <div class="section">
<h2>on_pause() on_resume()</h2> <h2><a id="on-pause-on-resume" name="on-pause-on-resume">on_pause() on_resume()</a></h2>
<pre class="literal-block"> <pre class="literal-block">
bool on_pause(); bool on_pause();
bool on_resume(); 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 standard handler, you have to keep your own state on whether you want standard
behavior or overridden behavior.</p> behavior or overridden behavior.</p>
</div> </div>
<div class="section" id="on-files-checked"> <div class="section">
<h2>on_files_checked()</h2> <h2><a id="on-files-checked" name="on-files-checked">on_files_checked()</a></h2>
<pre class="literal-block"> <pre class="literal-block">
void on_files_checked(); void on_files_checked();
</pre> </pre>
@ -181,8 +180,8 @@ checked. If there are no files to check, this function is called immediately.</p
can start downloading.</p> can start downloading.</p>
</div> </div>
</div> </div>
<div class="section" id="peer-plugin"> <div class="section">
<h1>peer_plugin</h1> <h1><a id="peer-plugin" name="peer-plugin">peer_plugin</a></h1>
<pre class="literal-block"> <pre class="literal-block">
struct peer_plugin struct peer_plugin
{ {
@ -190,7 +189,7 @@ struct peer_plugin
virtual void add_handshake(entry&amp;); virtual void add_handshake(entry&amp;);
virtual bool on_handshake(char const* reserved_bits); 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_choke();
virtual bool on_unchoke(); virtual bool on_unchoke();
@ -219,8 +218,8 @@ struct peer_plugin
}; };
</pre> </pre>
</div> </div>
<div class="section" id="disk-buffer-holder"> <div class="section">
<h1>disk_buffer_holder</h1> <h1><a id="disk-buffer-holder" name="disk-buffer-holder">disk_buffer_holder</a></h1>
<pre class="literal-block"> <pre class="literal-block">
struct disk_buffer_holder 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(); std::auto_ptr<alert> pop_alert();
alert const* wait_for_alert(time_duration max_wait); 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< void add_extension(boost::function<
boost::shared_ptr<torrent_plugin>(torrent*)> ext); 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 can only connect to a few peers at a time because of a built in limitation (in XP
Service pack 2). 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(); std::auto_ptr<alert> pop_alert();
alert const* wait_for_alert(time_duration max_wait); 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 ``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 ``set_alert_mask()`` you can filter which alerts to receive through ``pop_alert()``.
receive it through ``pop_alert()``. For information, see alerts_. For information about the alert categories, see alerts_.
``wait_for_alert`` blocks until an alert is available, or for no more than ``max_wait`` ``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, 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 The ``pop_alert()`` function on session is the interface for retrieving
alerts, warnings, messages and errors from libtorrent. If there hasn't alerts, warnings, messages and errors from libtorrent. If no alerts have
occurred any errors (matching your severity level) ``pop_alert()`` will been posted by libtorrent ``pop_alert()`` will return a default initialized
return a zero pointer. If there has been some error, it will return a pointer ``auto_ptr`` object. If there is an alert in libtorrent's queue, the alert
to an alert object describing it. You can then use the alert object and query from the front of the queue is popped and returned.
it for information about the error or message. To retrieve any alerts, you have You can then use the alert object and query
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:
+--------------+----------------------------------------------------------+ By default, only errors are reported. ``session::set_alert_mask()`` can be
| ``none`` | No alert will ever have this severity level, which | used to specify which kinds of events should be reported. The alert mask
| | effectively filters all messages. | is a bitmask with the following bits:
| | |
+--------------+----------------------------------------------------------+
| ``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. |
| | |
+--------------+----------------------------------------------------------+
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 | ``error_notification`` | Enables alerts that report an error. This includes: |
any events at all. | | |
| | * 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 Every alert belongs to one or more category. There is a small cost involved in posting alerts. Only
``pop_alert()`` from time to time. If you don't do that, the alert queue will just grow. 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 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 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. 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 The ``alert`` class is the base class that specific messages are derived from. This
is its synopsis:: is its synopsis:
.. parsed-literal::
class alert class alert
{ {
public: 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(); virtual ~alert();
std::string const& msg() const; virtual std::string message() const = 0;
severity_t severity() const; virtual char const* what() const = 0;
virtual int category() const = 0;
virtual std::auto_ptr<alert> clone() const = 0; virtual std::auto_ptr<alert> clone() const = 0;
}; };
This means that all alerts have at least a string describing it. They also ``what()`` returns a string literal describing the type of the alert. It does
have a severity level that can be used to sort them or present them to the not include any information that might be bundled with the alert.
user in different ways.
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:: alerts that are generated for a specific torrent are derived from::
struct torrent_alert: alert struct torrent_alert: alert
{ {
torrent_alert(torrent_handle const& h, severity_t s, std::string const& msg); // ...
torrent_handle handle; 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 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 generated. The external IP address can be acquired from the tracker (if it
supports that) or from peers that supports the extension protocol. supports that) or from peers that supports the extension protocol.
The address can be accessed through the ``external_address`` member. The address can be accessed through the ``external_address`` member.
This alert is generated as severity level ``info``.
:: ::
struct external_ip_alert: alert struct external_ip_alert: alert
{ {
external_ip_alert(address const& ip, const std::string& msg); // ...
address external_address; 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 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 session_ can be opened for listening. This alert doesn't have any extra
level ``fatal``. data members.
::
struct listen_failed_alert: alert
{
listen_failed_alert(const std::string& msg);
virtual std::auto_ptr<alert> clone() const;
};
portmap_error_alert 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 appears there is no NAT router that can be remote controlled to add port
mappings. 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. ``mapping`` refers to the mapping index of the port map that failed, i.e.
the index returned from add_mapping_. the index returned from add_mapping_.
@ -3799,10 +3818,9 @@ the index returned from add_mapping_.
struct portmap_error_alert: alert struct portmap_error_alert: alert
{ {
portmap_error_alert(int mapping, int type, const std::string& msg); // ...
int mapping; int mapping;
int type; int type;
virtual std::auto_ptr<alert> clone() const;
}; };
portmap_alert portmap_alert
@ -3811,8 +3829,7 @@ portmap_alert
This alert is generated when a NAT router was successfully found and 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 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 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 port and, if DHT is enabled, when the UDP port is mapped.
an informational alert, and is generated at severity level ``info``.
``mapping`` refers to the mapping index of the port map that failed, i.e. ``mapping`` refers to the mapping index of the port map that failed, i.e.
the index returned from add_mapping_. the index returned from add_mapping_.
@ -3825,28 +3842,29 @@ the index returned from add_mapping_.
struct portmap_alert: alert struct portmap_alert: alert
{ {
portmap_alert(int mapping, int port, int type, const std::string& msg); // ...
int mapping; int mapping;
int external_port; int external_port;
int type; int type;
virtual std::auto_ptr<alert> clone() const;
}; };
file_error_alert file_error_alert
---------------- ----------------
If the storage fails to read or write files that it needs access to, this alert is 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 struct file_error_alert: torrent_alert
{ {
file_error_alert( // ...
const torrent_handle& h std::string file;
, const std::string& msg); std::string msg;
virtual std::auto_ptr<alert> clone() const;
}; };
@ -3854,43 +3872,16 @@ tracker_announce_alert
---------------------- ----------------------
This alert is generated each time a tracker announce is sent (or attempted to be sent). 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 tracker_error_alert
------------------- -------------------
This alert is generated on tracker time outs, premature disconnects, invalid response or 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 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. 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 ``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 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 times_in_row;
int status_code; int status_code;
}; };
@ -3915,90 +3903,88 @@ tracker_reply_alert
This alert is only for informational purpose. It is generated when a tracker announce 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 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 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; int num_peers;
virtual std::auto_ptr<alert> clone() const;
}; };
The ``num_peers`` tells how many peers were returned from the tracker. This is 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. 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 tracker_warning_alert
--------------------- ---------------------
This alert is triggered if the tracker reply contains a warning field. Usually this 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 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 client. The ``msg`` string in the alert contains the warning message from
the tracker. It is generated with severity level ``warning``. the tracker.
:: ::
struct tracker_warning_alert: tracker_alert struct tracker_warning_alert: tracker_alert
{ {
tracker_warning_alert(torrent_handle const& h // ...
, std::string const& url std::string msg;
, std::string const& msg);
virtual std::auto_ptr<alert> clone() const;
}; };
scrape_reply_alert 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`` This alert is generated when a scrape request succeeds. ``incomplete``
and ``complete`` is the data returned in the scrape response. These numbers and ``complete`` is the data returned in the scrape response. These numbers
may be -1 if the reponse was malformed. may be -1 if the reponse was malformed.
::
struct scrape_reply_alert: tracker_alert
{
// ...
int incomplete;
int complete;
};
scrape_failed_alert 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 struct scrape_failed_alert: tracker_alert
{ {
scrape_failed_alert(torrent_handle const& h // ...
, std::string const& url std::string msg;
, std::string const& msg);
virtual std::auto_ptr<alert> clone() const;
}; };
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 url_seed_alert
-------------- --------------
This alert is generated when a HTTP seed name lookup fails. This alert is This alert is generated when a HTTP seed name lookup fails.
generated as severity level ``warning``.
It contains ``url`` to the HTTP seed that failed along with an error message. 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 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; 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 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. 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 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; 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 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 us. ``ip`` is the endpoint to the peer that was banned.
to the torrent that this peer was a member of.
:: ::
struct peer_ban_alert: torrent_alert 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; 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 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 will be disconnected, but you get its ip address from the alert, to identify it.
is generated as severity level ``debug``.
:: ::
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; asio::ip::tcp::endpoint ip;
peer_id id; peer_id id;
}; };
@ -4083,10 +4046,9 @@ is generated as severity level ``debug``.
invalid_request_alert invalid_request_alert
--------------------- ---------------------
This is a debug alert that is generated by an incoming invalid piece request. The ``handle`` This is a debug alert that is generated by an incoming invalid piece request.
is a handle to the torrent the peer is a member of. ``ìp`` is the address of the peer and the ``ìp`` is the address of the peer and the ``request`` is the actual incoming
``request`` is the actual incoming request from the peer. The alert is generated as severity level request from the peer.
``debug``.
:: ::
@ -4125,18 +4087,9 @@ torrent_finished_alert
This alert is generated when a torrent switches from being a downloader to a seed. 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 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.
:: There are no additional data members in this alert.
struct torrent_finished_alert: torrent_alert
{
torrent_finished_alert(
const torrent_handle& h
, const std::string& msg);
virtual std::auto_ptr<alert> clone() const;
};
metadata_failed_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 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 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. torrent-less download, with the metadata extension provided by libtorrent.
It is generated at severity level ``info``.
:: There are no additional data members in this alert.
struct metadata_failed_alert: torrent_alert
{
metadata_failed_alert(
torrent_handle const& h
, std::string const& msg);
virtual std::auto_ptr<alert> clone() const;
};
metadata_received_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 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 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). only those that needs to download it from peers (when utilizing the libtorrent extension).
It is generated at severity level ``info``.
:: There are no additional data members in this alert.
struct metadata_received_alert: torrent_alert
{
metadata_received_alert(
torrent_handle const_& h
, std::string const& msg);
virtual std::auto_ptr<alert> clone() const;
};
fastresume_rejected_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 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 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 struct fastresume_rejected_alert: torrent_alert
{ {
fastresume_rejected_alert(torrent_handle const& h // ...
, std::string const& msg); std::string msg;
virtual std::auto_ptr<alert> clone() const;
}; };
peer_blocked_alert peer_blocked_alert
------------------ ------------------
This alert is generated when a peer is blocked by the IP filter. It has the severity leve This alert is generated when a peer is blocked by the IP filter. The ``ip`` member is the
``info``. The ``ip`` member is the address that was blocked. address that was blocked.
:: ::
struct peer_blocked_alert: alert struct peer_blocked_alert: alert
{ {
peer_blocked_alert(address const& ip_ // ...
, std::string const& msg);
address ip; address ip;
virtual std::auto_ptr<alert> clone() const;
}; };
storage_moved_alert storage_moved_alert
------------------- -------------------
The ``storage_moved_alert`` is generated when all the disk IO has completed and the 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 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 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 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. generated once all disk IO is complete and the files in the torrent have been closed.
This is useful for synchronizing with the disk. This is useful for synchronizing with the disk.
:: There are no additional data members in this alert.
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;
};
torrent_resumed_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 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. 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 dispatcher

View File

@ -584,6 +584,33 @@ libtorrent::torrent_handle get_active_torrent(handles_t const& handles)
return i->second; 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[] = static char const* state_str[] =
{"checking (q)", "checking", "connecting", "dl metadata" {"checking (q)", "checking", "connecting", "dl metadata"
, "downloading", "finished", "seeding", "allocating"}; , "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); save_resume_data_alert const* rd = dynamic_cast<save_resume_data_alert const*>(a);
if (!rd) if (!rd)
{ {
std::cout << a->msg() << std::endl; std::cout << a->message() << std::endl;
continue; continue;
} }
--num_resume_data; --num_resume_data;
@ -1133,78 +1160,22 @@ int main(int ac, char* av[])
while (a.get()) while (a.get())
{ {
std::stringstream event_string; 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 (a->category() & alert::error_notification)
if (torrent_finished_alert* p = dynamic_cast<torrent_finished_alert*>(a.get()))
{ {
p->handle.set_max_connections(30); event_string << esc("31");
// write resume data for the finished torrent
torrent_handle h = p->handle;
h.save_resume_data();
event_string << h.name() << ": " << a->msg();
} }
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(); event_string << esc("33");
}
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 << a->message();
event_string << esc("0"); event_string << esc("0");
events.push_back(event_string.str()); events.push_back(event_string.str());
if (events.size() >= 20) events.pop_front(); if (events.size() >= 20) events.pop_front();
::handle_alert(ses, a.get());
a = ses.pop_alert(); a = ses.pop_alert();
} }

View File

@ -67,23 +67,40 @@ namespace libtorrent {
class TORRENT_EXPORT alert class TORRENT_EXPORT alert
{ {
public: public:
// only here for backwards compatibility
enum severity_t { debug, info, warning, critical, fatal, none }; 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(); virtual ~alert();
// a timestamp is automatically created in the constructor // a timestamp is automatically created in the constructor
ptime timestamp() const; 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; virtual std::auto_ptr<alert> clone() const = 0;
private: private:
std::string m_msg;
severity_t m_severity;
ptime m_timestamp; ptime m_timestamp;
}; };
@ -97,16 +114,18 @@ namespace libtorrent {
bool pending() const; bool pending() const;
std::auto_ptr<alert> get(); std::auto_ptr<alert> get();
void set_severity(alert::severity_t severity); template <class T>
bool should_post(alert::severity_t severity) const; bool should_post() const { return m_alert_mask & T::static_category; }
alert const* wait_for_alert(time_duration max_wait); alert const* wait_for_alert(time_duration max_wait);
void set_alert_mask(int m) { m_alert_mask = m; }
private: private:
std::queue<alert*> m_alerts; std::queue<alert*> m_alerts;
alert::severity_t m_severity;
mutable boost::mutex m_mutex; mutable boost::mutex m_mutex;
boost::condition m_condition; boost::condition m_condition;
int m_alert_mask;
}; };
struct TORRENT_EXPORT unhandled_alert : std::exception 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 check_torrent(boost::shared_ptr<torrent> const& t);
void done_checking(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(); std::auto_ptr<alert> pop_alert();
alert const* wait_for_alert(time_duration max_wait); 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); void set_max_half_open_connections(int limit);
std::auto_ptr<alert> pop_alert(); 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); alert const* wait_for_alert(time_duration max_wait);

View File

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

View File

@ -173,10 +173,10 @@ namespace libtorrent { namespace
m_metadata_progress = 0; m_metadata_progress = 0;
m_metadata_size = 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.alerts().post_alert(metadata_failed_alert(
m_torrent.get_handle(), "invalid metadata received from swarm")); m_torrent.get_handle()));
} }
return false; return false;

View File

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

View File

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

View File

@ -513,9 +513,27 @@ namespace libtorrent
return m_impl->wait_for_alert(max_wait); 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) 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() void session::start_lsd()

View File

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

View File

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

View File

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