fix python GIL issue when passing in a torrent_info object that later gets destroyed from within libtorrent
This commit is contained in:
parent
cf5c39a050
commit
90efec5d19
|
@ -188,7 +188,16 @@ namespace
|
|||
{
|
||||
// torrent_info objects are always held by a shared_ptr in the python binding
|
||||
if (params.has_key("ti") && params.get("ti") != boost::python::object())
|
||||
p.ti = extract<boost::shared_ptr<torrent_info> >(params["ti"]);
|
||||
{
|
||||
// make a copy here. We don't want to end up holding a python-owned
|
||||
// object inside libtorrent. If the last reference goes out of scope
|
||||
// on the C++ side, it will end up freeing the python object
|
||||
// without holding the GIL and likely crash.
|
||||
// https://mail.python.org/pipermail/cplusplus-sig/2007-June/012130.html
|
||||
p.ti = boost::make_shared<torrent_info>(
|
||||
extract<torrent_info const&>(params["ti"]));
|
||||
}
|
||||
|
||||
|
||||
if (params.has_key("info_hash"))
|
||||
p.info_hash = sha1_hash(bytes(extract<bytes>(params["info_hash"])).arr);
|
||||
|
@ -420,20 +429,20 @@ namespace
|
|||
return ret;
|
||||
}
|
||||
|
||||
cache_status get_cache_info1(lt::session& s, torrent_handle h, int flags)
|
||||
{
|
||||
cache_status ret;
|
||||
s.get_cache_info(&ret, h, flags);
|
||||
return ret;
|
||||
}
|
||||
cache_status get_cache_info1(lt::session& s, torrent_handle h, int flags)
|
||||
{
|
||||
cache_status ret;
|
||||
s.get_cache_info(&ret, h, flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef TORRENT_NO_DEPRECATE
|
||||
cache_status get_cache_status(lt::session& s)
|
||||
{
|
||||
cache_status ret;
|
||||
s.get_cache_info(&ret);
|
||||
return ret;
|
||||
}
|
||||
cache_status get_cache_status(lt::session& s)
|
||||
{
|
||||
cache_status ret;
|
||||
s.get_cache_info(&ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dict get_utp_stats(session_status const& st)
|
||||
{
|
||||
|
|
|
@ -73,6 +73,25 @@ class test_alerts(unittest.TestCase):
|
|||
print(st.info_hash)
|
||||
self.assertEqual(st.save_path, os.getcwd())
|
||||
|
||||
def test_pop_alerts(self):
|
||||
ses = lt.session({'alert_mask': lt.alert.category_t.all_categories})
|
||||
|
||||
ses.async_add_torrent({"ti": lt.torrent_info("base.torrent"), "save_path": "."})
|
||||
# this will cause an error (because of duplicate torrents) and the
|
||||
# torrent_info object created here will be deleted once the alert goes out
|
||||
# of scope. When that happens, it will decrement the python object, to allow
|
||||
# it to release the object.
|
||||
# we're trying to catch the error described in this post, with regards to
|
||||
# torrent_info.
|
||||
# https://mail.python.org/pipermail/cplusplus-sig/2007-June/012130.html
|
||||
ses.async_add_torrent({"ti": lt.torrent_info("base.torrent"), "save_path": "."})
|
||||
time.sleep(1)
|
||||
for i in range(0, 10):
|
||||
alerts = ses.pop_alerts()
|
||||
for a in alerts:
|
||||
print(a.message())
|
||||
time.sleep(0.1)
|
||||
|
||||
class test_bencoder(unittest.TestCase):
|
||||
|
||||
def test_bencode(self):
|
||||
|
|
|
@ -163,9 +163,9 @@ namespace libtorrent {
|
|||
const static int header_size = (sizeof(header_t) + sizeof(uintptr_t)
|
||||
- 1) / sizeof(uintptr_t);
|
||||
|
||||
void grow_capacity(int size)
|
||||
void grow_capacity(int const size)
|
||||
{
|
||||
int amount_to_grow = (std::max)(size + header_size
|
||||
int const amount_to_grow = (std::max)(size + header_size
|
||||
, (std::max)(m_capacity * 3 / 2, 128));
|
||||
|
||||
uintptr_t* new_storage = new uintptr_t[m_capacity + amount_to_grow];
|
||||
|
|
Loading…
Reference in New Issue