premiere-libtorrent/include/libtorrent/session.hpp

381 lines
14 KiB
C++
Raw Normal View History

/*
Copyright (c) 2006-2016, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
2003-10-26 18:35:23 +01:00
#ifndef TORRENT_SESSION_HPP_INCLUDED
#define TORRENT_SESSION_HPP_INCLUDED
#include <thread>
#include "libtorrent/config.hpp"
#include "libtorrent/build_config.hpp"
#include "libtorrent/io_service.hpp"
#include "libtorrent/settings_pack.hpp"
#include "libtorrent/session_handle.hpp"
#include "libtorrent/session_settings.hpp" // for dht_settings
#include "libtorrent/kademlia/dht_state.hpp"
#include "libtorrent/kademlia/dht_storage.hpp"
2015-03-28 18:31:27 +01:00
#ifndef TORRENT_NO_DEPRECATE
#include "libtorrent/fingerprint.hpp"
#include <cstdio> // for snprintf
2015-03-28 18:31:27 +01:00
#endif
namespace libtorrent
{
struct plugin;
2014-02-02 06:09:18 +01:00
// The default values of the session settings are set for a regular
// bittorrent client running on a desktop system. There are functions that
// can set the session settings to pre set settings for other environments.
// These can be used for the basis, and should be tweaked to fit your needs
// better.
//
2014-02-02 06:09:18 +01:00
// ``min_memory_usage`` returns settings that will use the minimal amount of
// RAM, at the potential expense of upload and download performance. It
// adjusts the socket buffer sizes, disables the disk cache, lowers the send
// buffer watermarks so that each connection only has at most one block in
// use at any one time. It lowers the outstanding blocks send to the disk
// I/O thread so that connections only have one block waiting to be flushed
// to disk at any given time. It lowers the max number of peers in the peer
// list for torrents. It performs multiple smaller reads when it hashes
// pieces, instead of reading it all into memory before hashing.
//
// This configuration is intended to be the starting point for embedded
2014-02-02 06:09:18 +01:00
// devices. It will significantly reduce memory usage.
//
2014-02-02 06:09:18 +01:00
// ``high_performance_seed`` returns settings optimized for a seed box,
// serving many peers and that doesn't do any downloading. It has a 128 MB
// disk cache and has a limit of 400 files in its file pool. It support fast
// upload rates by allowing large send buffers.
TORRENT_EXPORT settings_pack min_memory_usage();
TORRENT_EXPORT settings_pack high_performance_seed();
#ifndef TORRENT_NO_DEPRECATE
TORRENT_DEPRECATED
inline void min_memory_usage(settings_pack& set)
{ set = min_memory_usage(); }
TORRENT_DEPRECATED
inline void high_performance_seed(settings_pack& set)
{ set = high_performance_seed(); }
#endif
2014-07-06 21:18:00 +02:00
#ifndef TORRENT_CFG
#error TORRENT_CFG is not defined!
#endif
void TORRENT_EXPORT TORRENT_CFG();
namespace aux
{
struct session_impl;
}
struct disk_interface;
struct counters;
2014-02-02 06:09:18 +01:00
// this is a holder for the internal session implementation object. Once the
// session destruction is explicitly initiated, this holder is used to
// synchronize the completion of the shutdown. The lifetime of this object
// may outlive session, causing the session destructor to not block. The
// session_proxy destructor will block however, until the underlying session
// is done shutting down.
class TORRENT_EXPORT session_proxy
{
friend class session;
public:
// default constructor, does not refer to any session
// implementation object.
2016-07-05 00:19:55 +02:00
session_proxy();
~session_proxy();
2016-07-05 00:19:55 +02:00
session_proxy(session_proxy const&);
session_proxy& operator=(session_proxy const&);
private:
session_proxy(
std::shared_ptr<io_service> ios
, std::shared_ptr<std::thread> t
, std::shared_ptr<aux::session_impl> impl);
2016-07-05 00:19:55 +02:00
std::shared_ptr<io_service> m_io_service;
std::shared_ptr<std::thread> m_thread;
std::shared_ptr<aux::session_impl> m_impl;
};
// The session_params is a parameters pack for configuring the session
// before it's started.
struct TORRENT_EXPORT session_params
{
// This constructor can be used to start with the default plugins
// (ut_metadata, ut_pex and smart_ban). The default values in the
// settings is to start the default features like upnp, nat-pmp,
// and dht for example.
explicit session_params(settings_pack sp = settings_pack());
// This constructor helps to configure the set of initial plugins
// to be added to the session before it's started.
session_params(settings_pack sp
, std::vector<std::shared_ptr<plugin>> exts);
session_params(session_params const&) = default;
session_params(session_params&&) = default;
session_params& operator=(session_params const&) = default;
session_params& operator=(session_params&&) = default;
settings_pack settings;
std::vector<std::shared_ptr<plugin>> extensions;
libtorrent::dht_settings dht_settings;
dht::dht_state dht_state;
dht::dht_storage_constructor_type dht_storage_constructor;
};
// This function helps to construct a ``session_params`` from a
// bencoded data generated by ``session_handle::save_state``
TORRENT_EXPORT session_params read_session_params(bdecode_node const& e
, std::uint32_t flags = 0xffffffff);
2014-02-02 06:09:18 +01:00
// The session holds all state that spans multiple torrents. Among other
// things it runs the network loop and manages all torrents. Once it's
// created, the session object will spawn the main thread that will do all
// the work. The main thread will be idle as long it doesn't have any
// torrents to participate in.
2014-07-06 21:18:00 +02:00
//
// You have some control over session configuration through the
// ``session_handle::apply_settings()`` member function. To change one or more
2014-07-06 21:18:00 +02:00
// configuration options, create a settings_pack. object and fill it with
// the settings to be set and pass it in to ``session::apply_settings()``.
//
2014-07-06 21:18:00 +02:00
// see apply_settings().
2016-07-05 00:19:55 +02:00
class TORRENT_EXPORT session : public session_handle
{
public:
// Constructs the session objects which acts as the container of torrents.
// In order to avoid a race condition between starting the session and
// configuring it, you can pass in a session_params object. Its settings
// will take effect before the session starts up.
explicit session(session_params params = session_params())
: session_handle(nullptr)
{
TORRENT_CFG();
start(std::move(params), nullptr);
}
// Overload of the constructor that takes an external io_service to run
// the session object on. This is primarily useful for tests that may want
// to run multiple sessions on a single io_service, or low resource
// systems where additional threads are expensive and sharing an
// io_service with other events is fine.
//
// .. warning::
// The session object does not cleanly terminate with an external
// ``io_service``. The ``io_service::run()`` call _must_ have returned
// before it's safe to destruct the session. Which means you *MUST*
// call session::abort() and save the session_proxy first, then
// destruct the session object, then sync with the io_service, then
// destruct the session_proxy object.
session(session_params params, io_service& ios)
: session_handle(nullptr)
{
TORRENT_CFG();
start(std::move(params), &ios);
}
// Constructs the session objects which acts as the container of torrents.
// It provides configuration options across torrents (such as rate limits,
// disk cache, ip filter etc.). In order to avoid a race condition between
// starting the session and configuring it, you can pass in a
// settings_pack object. Its settings will take effect before the session
// starts up.
//
// The ``flags`` parameter can be used to start default features (upnp &
2014-02-02 06:09:18 +01:00
// nat-pmp) and default plugins (ut_metadata, ut_pex and smart_ban). The
2014-07-06 21:18:00 +02:00
// default is to start those features. If you do not want them to start,
2014-02-02 06:09:18 +01:00
// pass 0 as the flags parameter.
session(settings_pack pack
, int flags = start_default_features | add_default_plugins)
: session_handle(nullptr)
{
TORRENT_CFG();
start(flags, std::move(pack), nullptr);
}
2014-07-06 21:18:00 +02:00
2016-07-05 00:19:55 +02:00
// moveable
session(session&&) = default;
session& operator=(session&&) = default;
// noncopyable
session(session const&) = delete;
session& operator=(session const&) = delete;
// overload of the constructor that takes an external io_service to run
// the session object on. This is primarily useful for tests that may want
// to run multiple sessions on a single io_service, or low resource
// systems where additional threads are expensive and sharing an
// io_service with other events is fine.
//
// .. warning::
// The session object does not cleanly terminate with an external
// ``io_service``. The ``io_service::run()`` call _must_ have returned
// before it's safe to destruct the session. Which means you *MUST*
// call session::abort() and save the session_proxy first, then
// destruct the session object, then sync with the io_service, then
// destruct the session_proxy object.
2016-08-05 06:28:03 +02:00
session(settings_pack pack
, io_service& ios
2014-07-06 21:18:00 +02:00
, int flags = start_default_features | add_default_plugins)
: session_handle(nullptr)
2014-07-06 21:18:00 +02:00
{
TORRENT_CFG();
start(flags, std::move(pack), &ios);
2014-07-06 21:18:00 +02:00
}
#ifndef TORRENT_NO_DEPRECATE
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#ifdef __clang__
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif
#ifdef _MSC_VER
#pragma warning(push, 1)
#pragma warning(disable: 4996)
#endif
TORRENT_DEPRECATED
2015-06-05 08:38:07 +02:00
session(fingerprint const& print
, int flags = start_default_features | add_default_plugins
, std::uint32_t alert_mask = alert::error_notification)
: session_handle(nullptr)
{
TORRENT_CFG();
2014-07-06 21:18:00 +02:00
settings_pack pack;
pack.set_int(settings_pack::alert_mask, int(alert_mask));
pack.set_str(settings_pack::peer_fingerprint, print.to_string());
2014-07-06 21:18:00 +02:00
if ((flags & start_default_features) == 0)
{
pack.set_bool(settings_pack::enable_upnp, false);
pack.set_bool(settings_pack::enable_natpmp, false);
pack.set_bool(settings_pack::enable_lsd, false);
pack.set_bool(settings_pack::enable_dht, false);
}
2016-08-05 06:28:03 +02:00
start(flags, std::move(pack), nullptr);
}
TORRENT_DEPRECATED
session(fingerprint const& print
2004-03-29 00:44:40 +02:00
, std::pair<int, int> listen_port_range
2007-11-16 22:21:28 +01:00
, char const* listen_interface = "0.0.0.0"
, int flags = start_default_features | add_default_plugins
, int alert_mask = alert::error_notification)
: session_handle(nullptr)
{
TORRENT_CFG();
TORRENT_ASSERT(listen_port_range.first > 0);
2014-07-06 21:18:00 +02:00
TORRENT_ASSERT(listen_port_range.first <= listen_port_range.second);
settings_pack pack;
pack.set_int(settings_pack::alert_mask, int(alert_mask));
2014-07-06 21:18:00 +02:00
pack.set_int(settings_pack::max_retry_port_bind, listen_port_range.second - listen_port_range.first);
pack.set_str(settings_pack::peer_fingerprint, print.to_string());
2014-07-06 21:18:00 +02:00
char if_string[100];
if (listen_interface == nullptr) listen_interface = "0.0.0.0";
std::snprintf(if_string, sizeof(if_string), "%s:%d", listen_interface, listen_port_range.first);
2014-07-06 21:18:00 +02:00
pack.set_str(settings_pack::listen_interfaces, if_string);
if ((flags & start_default_features) == 0)
{
pack.set_bool(settings_pack::enable_upnp, false);
pack.set_bool(settings_pack::enable_natpmp, false);
pack.set_bool(settings_pack::enable_lsd, false);
pack.set_bool(settings_pack::enable_dht, false);
}
2016-08-05 06:28:03 +02:00
start(flags, std::move(pack), nullptr);
}
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif
#ifdef __clang__
#pragma clang diagnostic pop
#endif
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#endif // TORRENT_NO_DEPRECATE
2015-05-30 19:41:38 +02:00
2014-02-02 06:09:18 +01:00
// The destructor of session will notify all trackers that our torrents
// have been shut down. If some trackers are down, they will time out.
// All this before the destructor of session returns. So, it's advised
// that any kind of interface (such as windows) are closed before
// destructing the session object. Because it can take a few second for
2014-07-06 21:18:00 +02:00
// it to finish. The timeout can be set with apply_settings().
~session();
2016-02-10 17:58:09 +01:00
// In case you want to destruct the session asynchronously, you can
2014-02-02 06:09:18 +01:00
// request a session destruction proxy. If you don't do this, the
// destructor of the session object will block while the trackers are
// contacted. If you keep one ``session_proxy`` to the session when
// destructing it, the destructor will not block, but start to close down
// the session, the destructor of the proxy will then synchronize the
// threads. So, the destruction of the session is performed from the
// ``session`` destructor call until the ``session_proxy`` destructor
// call. The ``session_proxy`` does not have any operations on it (since
// the session is being closed down, no operations are allowed on it).
// The only valid operation is calling the destructor::
//
// class session_proxy
// {
// public:
// session_proxy();
// ~session_proxy()
// };
session_proxy abort();
private:
void start(session_params params, io_service* ios);
void start(int flags, settings_pack sp, io_service* ios);
2003-10-31 05:02:51 +01:00
// data shared between the main thread
// and the working thread
std::shared_ptr<io_service> m_io_service;
std::shared_ptr<std::thread> m_thread;
std::shared_ptr<aux::session_impl> m_impl;
};
}
#endif // TORRENT_SESSION_HPP_INCLUDED