merged python GIL fix from RC_0_16

This commit is contained in:
Arvid Norberg 2012-09-19 06:13:04 +00:00
parent fdb89b6d7b
commit 15ecec3ae5
8 changed files with 16 additions and 610 deletions

View File

@ -3,6 +3,7 @@
* fix uTP edge case where udp socket buffer fills up
* fix nagle implementation in uTP
* fix GIL issue in python bindings. Deprecated extension support in python
* fixed bug where setting upload slots to -1 would not mean infinite
* extend the UDP tracker protocol to include the request string from the tracker URL
* fix mingw build for linux crosscompiler

View File

@ -21,18 +21,6 @@ rule libtorrent_linking ( properties * )
result += <cxxflags>-fvisibility=hidden ;
}
# when building peer_plugin.cpp on msvc-7.1 it fails
# running out of internal heap space. Don't add it
# to windows build, since it's not critical anyway
if <toolset>msvc in $(properties)
{
result += <define>TORRENT_NO_PYTHON_PLUGINS ;
}
else
{
result += <source>src/peer_plugin.cpp ;
}
if <boost>source in $(properties)
{
if <boost-link>static in $(properties) || <link>static in $(properties)
@ -71,7 +59,6 @@ python-extension libtorrent
src/version.cpp
src/alert.cpp
src/datetime.cpp
src/extensions.cpp
src/torrent.cpp
src/peer_info.cpp
src/ip_filter.cpp

View File

@ -13,7 +13,6 @@ EXTRA_DIST = \
src/datetime.cpp \
src/entry.cpp \
src/error_code.cpp \
src/extensions.cpp \
src/fingerprint.cpp \
src/gil.hpp \
src/ip_filter.cpp \
@ -21,7 +20,6 @@ EXTRA_DIST = \
src/module.cpp \
src/optional.hpp \
src/peer_info.cpp \
src/peer_plugin.cpp \
src/session.cpp \
src/session_settings.cpp \
src/torrent.cpp \

View File

@ -63,25 +63,6 @@ else:
import termios
import select
class PythonExtension(lt.torrent_plugin):
def __init__(self, alerts):
lt.torrent_plugin.__init__(self)
self.alerts = alerts
self.alerts.append('PythonExtension')
self.count = 0
def on_piece_pass(self, index):
self.alerts.append('got piece %d' % index)
def on_piece_failed(self, index):
self.alerts.append('failed piece %d' % index)
def tick(self):
self.count += 1
if self.count >= 10:
self.count = 0
self.alerts.append('PythonExtension tick')
def write_line(console, line):
console.write(line)
@ -225,18 +206,11 @@ def main():
ses.set_upload_rate_limit(int(options.max_upload_rate))
ses.listen_on(options.port, options.port + 10)
ses.set_settings(settings)
# ses.set_severity_level(lt.alert.severity_levels.info)
ses.set_alert_mask(0xfffffff)
# ses.add_extension(lt.create_ut_pex_plugin)
# ses.add_extension(lt.create_ut_metadata_plugin)
# ses.add_extension(lt.create_metadata_plugin)
handles = []
alerts = []
# Extensions
# ses.add_extension(lambda x: PythonExtension(alerts))
for f in args:
e = lt.bdecode(open(f, 'rb').read())
info = lt.torrent_info(e)

View File

@ -1,172 +0,0 @@
// Copyright Daniel Wallin, Arvid Norberg 2007. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <boost/python.hpp>
#include <libtorrent/extensions.hpp>
#include <libtorrent/torrent.hpp>
#include <libtorrent/entry.hpp>
#include <libtorrent/peer_request.hpp>
#include <libtorrent/peer_connection.hpp>
#include <libtorrent/extensions/ut_pex.hpp>
#include <libtorrent/extensions/metadata_transfer.hpp>
#include <libtorrent/extensions/ut_metadata.hpp>
#include <libtorrent/extensions/smart_ban.hpp>
#include "gil.hpp"
using namespace boost::python;
using namespace libtorrent;
namespace
{
struct torrent_plugin_wrap : torrent_plugin, wrapper<torrent_plugin>
{
boost::shared_ptr<peer_plugin> new_connection(peer_connection* p)
{
lock_gil lock;
if (override f = this->get_override("new_connection"))
return f(ptr(p));
return torrent_plugin::new_connection(p);
}
boost::shared_ptr<peer_plugin> default_new_connection(peer_connection* p)
{
return this->torrent_plugin::new_connection(p);
}
void on_piece_pass(int index)
{
lock_gil lock;
if (override f = this->get_override("on_piece_pass"))
f(index);
else
torrent_plugin::on_piece_pass(index);
}
void default_on_piece_pass(int index)
{
this->torrent_plugin::on_piece_pass(index);
}
void on_piece_failed(int index)
{
lock_gil lock;
if (override f = this->get_override("on_piece_failed"))
f(index);
else
torrent_plugin::on_piece_failed(index);
}
void default_on_piece_failed(int index)
{
return this->torrent_plugin::on_piece_failed(index);
}
void tick()
{
lock_gil lock;
if (override f = this->get_override("tick"))
f();
else
torrent_plugin::tick();
}
void default_tick()
{
return this->torrent_plugin::tick();
}
bool on_pause()
{
lock_gil lock;
if (override f = this->get_override("on_pause"))
return f();
return torrent_plugin::on_pause();
}
bool default_on_pause()
{
return this->torrent_plugin::on_pause();
}
bool on_resume()
{
lock_gil lock;
if (override f = this->get_override("on_resume"))
return f();
return torrent_plugin::on_resume();
}
bool default_on_resume()
{
return this->torrent_plugin::on_resume();
}
};
} // namespace unnamed
boost::shared_ptr<torrent_plugin> create_metadata_plugin_wrapper(torrent* t) {
return create_metadata_plugin(t, NULL);
}
boost::shared_ptr<torrent_plugin> create_ut_metadata_plugin_wrapper(torrent *t) {
return create_ut_metadata_plugin(t, NULL);
}
boost::shared_ptr<torrent_plugin> create_ut_pex_plugin_wrapper(torrent* t) {
return create_ut_pex_plugin(t, NULL);
}
boost::shared_ptr<torrent_plugin> create_smart_ban_plugin_wrapper(torrent* t) {
return create_smart_ban_plugin(t, NULL);
}
void bind_extensions()
{
class_<
torrent_plugin_wrap, boost::shared_ptr<torrent_plugin_wrap>, boost::noncopyable
>("torrent_plugin")
.def(
"new_connection"
, &torrent_plugin::new_connection, &torrent_plugin_wrap::default_new_connection
)
.def(
"on_piece_pass"
, &torrent_plugin::on_piece_pass, &torrent_plugin_wrap::default_on_piece_pass
)
.def(
"on_piece_failed"
, &torrent_plugin::on_piece_failed, &torrent_plugin_wrap::default_on_piece_failed
)
.def(
"tick"
, &torrent_plugin::tick, &torrent_plugin_wrap::default_tick
)
.def(
"on_pause"
, &torrent_plugin::on_pause, &torrent_plugin_wrap::default_on_pause
)
.def(
"on_resume"
, &torrent_plugin::on_resume, &torrent_plugin_wrap::default_on_resume
);
// TODO move to it's own file
class_<peer_connection, boost::noncopyable>("peer_connection", no_init);
class_<torrent_plugin, boost::shared_ptr<torrent_plugin> >("torrent_plugin", no_init);
def("create_ut_pex_plugin", create_ut_pex_plugin_wrapper);
def("create_metadata_plugin", create_metadata_plugin_wrapper);
def("create_ut_metadata_plugin", create_ut_metadata_plugin_wrapper);
def("create_smart_ban_plugin", create_smart_ban_plugin_wrapper);
}

View File

@ -20,8 +20,6 @@ void bind_session_settings();
void bind_version();
void bind_alert();
void bind_datetime();
void bind_extensions();
void bind_peer_plugin();
void bind_torrent();
void bind_peer_info();
void bind_ip_filter();
@ -48,10 +46,6 @@ BOOST_PYTHON_MODULE(libtorrent)
bind_version();
bind_alert();
bind_datetime();
bind_extensions();
#ifndef TORRENT_NO_PYTHON_PLUGINS
bind_peer_plugin();
#endif
bind_torrent();
bind_peer_info();
bind_ip_filter();

View File

@ -1,372 +0,0 @@
// Copyright Daniel Wallin 2007. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#include <cctype>
#include <iostream>
#include <libtorrent/extensions.hpp>
#include <libtorrent/entry.hpp>
#include <libtorrent/lazy_entry.hpp>
#include <libtorrent/peer_request.hpp>
#include <libtorrent/disk_buffer_holder.hpp>
#include <libtorrent/bitfield.hpp>
#include <boost/python.hpp>
using namespace boost::python;
using namespace libtorrent;
namespace
{
struct peer_plugin_wrap : peer_plugin, wrapper<peer_plugin>
{
void add_handshake(entry& e)
{
if (override f = this->get_override("add_handshake"))
e = call<entry>(f.ptr(), e);
else
peer_plugin::add_handshake(e);
}
void default_add_handshake(entry& e)
{
this->peer_plugin::add_handshake(e);
}
bool on_handshake(char const* reserved_bits)
{
if (override f = this->get_override("on_handshake"))
return f();
else
return peer_plugin::on_handshake(reserved_bits);
}
bool default_on_handshake(char const* reserved_bits)
{
return this->peer_plugin::on_handshake(reserved_bits);
}
bool on_extension_handshake(lazy_entry const& e)
{
if (override f = this->get_override("on_extension_handshake"))
return f(e);
else
return peer_plugin::on_extension_handshake(e);
}
bool default_on_extension_handshake(lazy_entry const& e)
{
return this->peer_plugin::on_extension_handshake(e);
}
bool on_choke()
{
if (override f = this->get_override("on_choke"))
return f();
else
return peer_plugin::on_choke();
}
bool default_on_choke()
{
return this->peer_plugin::on_choke();
}
bool on_unchoke()
{
if (override f = this->get_override("on_unchoke"))
return f();
else
return peer_plugin::on_unchoke();
}
bool default_on_unchoke()
{
return this->peer_plugin::on_unchoke();
}
bool on_interested()
{
if (override f = this->get_override("on_interested"))
return f();
else
return peer_plugin::on_interested();
}
bool default_on_interested()
{
return this->peer_plugin::on_interested();
}
bool on_not_interested()
{
if (override f = this->get_override("on_not_interested"))
return f();
else
return peer_plugin::on_not_interested();
}
bool default_on_not_interested()
{
return this->peer_plugin::on_not_interested();
}
bool on_have(int index)
{
if (override f = this->get_override("on_have"))
return f(index);
else
return peer_plugin::on_have(index);
}
bool default_on_have(int index)
{
return this->peer_plugin::on_have(index);
}
bool on_bitfield(list _bf)
{
//Convert list to a bitfield
bitfield bf(len(_bf));
for (int i = 0; i < len(_bf); ++i)
{
if (_bf[i])
bf.set_bit(i);
else
bf.clear_bit(i);
}
if (override f = this->get_override("on_bitfield"))
return f(bf);
else
return peer_plugin::on_bitfield(bf);
}
bool default_on_bitfield(const bitfield &bf)
{
return this->peer_plugin::on_bitfield(bf);
}
bool on_request(peer_request const& req)
{
if (override f = this->get_override("on_request"))
return f(req);
else
return peer_plugin::on_request(req);
}
bool default_on_request(peer_request const& req)
{
return this->peer_plugin::on_request(req);
}
bool on_piece(peer_request const& piece, disk_buffer_holder& data)
{
if (override f = this->get_override("on_piece"))
return f(piece, data);
else
return peer_plugin::on_piece(piece, data);
}
bool default_on_piece(peer_request const& piece, disk_buffer_holder& data)
{
return this->peer_plugin::on_piece(piece, data);
}
bool on_cancel(peer_request const& req)
{
if (override f = this->get_override("on_cancel"))
return f(req);
else
return peer_plugin::on_cancel(req);
}
bool default_on_cancel(peer_request const& req)
{
return this->peer_plugin::on_cancel(req);
}
bool on_extended(int length, int msg, buffer::const_interval body)
{
if (override f = this->get_override("on_extended"))
return f(length, msg, body);
else
return peer_plugin::on_extended(length, msg, body);
}
bool default_on_extended(int length, int msg, buffer::const_interval body)
{
return this->peer_plugin::on_extended(length, msg, body);
}
bool on_unknown_message(int length, int msg, buffer::const_interval body)
{
if (override f = this->get_override("on_unknown_message"))
return f(length, msg, body);
else
return peer_plugin::on_unknown_message(length, msg, body);
}
bool default_on_unknown_message(int length, int msg, buffer::const_interval body)
{
return this->peer_plugin::on_unknown_message(length, msg, body);
}
void on_piece_pass(int index)
{
if (override f = this->get_override("on_piece_pass"))
f(index);
else
peer_plugin::on_piece_pass(index);
}
void default_on_piece_pass(int index)
{
this->peer_plugin::on_piece_pass(index);
}
void on_piece_failed(int index)
{
if (override f = this->get_override("on_piece_failed"))
f(index);
else
peer_plugin::on_piece_failed(index);
}
void default_on_piece_failed(int index)
{
this->peer_plugin::on_piece_failed(index);
}
void tick()
{
if (override f = this->get_override("tick"))
f();
else
peer_plugin::tick();
}
void default_tick()
{
this->peer_plugin::tick();
}
bool write_request(peer_request const& req)
{
if (override f = this->get_override("write_request"))
return f(req);
else
return peer_plugin::write_request(req);
}
bool default_write_request(peer_request const& req)
{
return this->peer_plugin::write_request(req);
}
};
object get_buffer()
{
static char const data[] = "foobar";
#if PY_VERSION_HEX >= 0x03000000
Py_buffer view;
memset(&view, 0, sizeof(Py_buffer));
view.buf = (void*)data;
view.len = 6;
view.ndim = 1;
view.readonly = true;
view.itemsize = sizeof(char);
Py_ssize_t shape[] = { 6 };
view.shape = shape;
return object(handle<>(PyMemoryView_FromBuffer(&view)));
#else
return object(handle<>(PyBuffer_FromMemory((void*)data, 6)));
#endif
}
} // namespace unnamed
void bind_peer_plugin()
{
class_<
peer_plugin_wrap, boost::shared_ptr<peer_plugin_wrap>, boost::noncopyable
>("peer_plugin")
.def(
"add_handshake"
, &peer_plugin::add_handshake, &peer_plugin_wrap::default_add_handshake
)
.def(
"on_handshake"
, &peer_plugin::on_handshake, &peer_plugin_wrap::default_on_handshake
)
.def(
"on_extension_handshake"
, &peer_plugin::on_extension_handshake
, &peer_plugin_wrap::default_on_extension_handshake
)
.def(
"on_choke"
, &peer_plugin::on_choke, &peer_plugin_wrap::default_on_choke
)
.def(
"on_unchoke"
, &peer_plugin::on_unchoke, &peer_plugin_wrap::default_on_unchoke
)
.def(
"on_interested"
, &peer_plugin::on_interested, &peer_plugin_wrap::default_on_interested
)
.def(
"on_not_interested"
, &peer_plugin::on_not_interested, &peer_plugin_wrap::default_on_not_interested
)
.def(
"on_have"
, &peer_plugin::on_have, &peer_plugin_wrap::default_on_have
)
.def(
"on_bitfield"
, &peer_plugin::on_bitfield, &peer_plugin_wrap::default_on_bitfield
)
.def(
"on_request"
, &peer_plugin::on_request, &peer_plugin_wrap::default_on_request
)
.def(
"on_piece"
, &peer_plugin::on_piece, &peer_plugin_wrap::default_on_piece
)
.def(
"on_cancel"
, &peer_plugin::on_cancel, &peer_plugin_wrap::default_on_cancel
)
.def(
"on_piece_pass"
, &peer_plugin::on_piece_pass, &peer_plugin_wrap::default_on_piece_pass
)
.def(
"on_piece_failed"
, &peer_plugin::on_piece_failed, &peer_plugin_wrap::default_on_piece_failed
)
.def(
"tick"
, &peer_plugin::tick, &peer_plugin_wrap::default_tick
)
.def(
"write_request"
, &peer_plugin::write_request, &peer_plugin_wrap::default_write_request
)
// These seem to make VC7.1 freeze. Needs special handling.
/*.def(
"on_extended"
, &peer_plugin::on_extended, &peer_plugin_wrap::default_on_extended
)
.def(
"on_unknown_message"
, &peer_plugin::on_unknown_message, &peer_plugin_wrap::default_on_unknown_message
)*/
;
def("get_buffer", &get_buffer);
}

View File

@ -11,6 +11,7 @@
#include <libtorrent/storage.hpp>
#include <libtorrent/ip_filter.hpp>
#include <libtorrent/disk_io_thread.hpp>
#include <libtorrent/extensions.hpp>
#include "gil.hpp"
using namespace boost::python;
@ -42,27 +43,15 @@ namespace
}
#endif
struct invoke_extension_factory
{
invoke_extension_factory(object const& callback)
: cb(callback)
{}
#ifndef TORRENT_NO_DEPRECATE
void add_extension(session& s, object const& e) {}
boost::shared_ptr<torrent_plugin> operator()(torrent* t, void*)
{
lock_gil lock;
return extract<boost::shared_ptr<torrent_plugin> >(cb(ptr(t)))();
}
object cb;
};
void add_extension(session& s, object const& e)
{
allow_threading_guard guard;
s.add_extension(invoke_extension_factory(e));
boost::shared_ptr<torrent_plugin> dummy_plugin_wrapper(torrent* t) {
return boost::shared_ptr<torrent_plugin>();
}
#endif
void session_set_settings(session& ses, dict const& sett_dict)
{
bencode_map_entry* map;
@ -601,8 +590,8 @@ void bind_session()
.def("set_alert_mask", allow_threads(&session::set_alert_mask))
.def("pop_alert", allow_threads(&session::pop_alert))
.def("wait_for_alert", &wait_for_alert, return_internal_reference<>())
.def("add_extension", &add_extension)
#ifndef TORRENT_NO_DEPRECATE
.def("add_extension", &add_extension)
.def("set_peer_proxy", allow_threads(&session::set_peer_proxy))
.def("set_tracker_proxy", allow_threads(&session::set_tracker_proxy))
.def("set_web_seed_proxy", allow_threads(&session::set_web_seed_proxy))
@ -658,6 +647,13 @@ void bind_session()
.def("settings", &get_feed_settings)
;
#ifndef TORRENT_NO_DEPRECATE
def("create_ut_pex_plugin", dummy_plugin_wrapper);
def("create_metadata_plugin", dummy_plugin_wrapper);
def("create_ut_metadata_plugin", dummy_plugin_wrapper);
def("create_smart_ban_plugin", dummy_plugin_wrapper);
#endif
register_ptr_to_python<std::auto_ptr<alert> >();
def("high_performance_seed", high_performance_seed);