forked from premiere/premiere-libtorrent
Merge pull request #584 from arvidn/python-sharedptr-1.1
fix python GIL issue
This commit is contained in:
commit
d0edcaf632
|
@ -207,7 +207,16 @@ namespace
|
||||||
{
|
{
|
||||||
// torrent_info objects are always held by a shared_ptr in the python binding
|
// 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())
|
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"))
|
if (params.has_key("info_hash"))
|
||||||
p.info_hash = sha1_hash(bytes(extract<bytes>(params["info_hash"])).arr);
|
p.info_hash = sha1_hash(bytes(extract<bytes>(params["info_hash"])).arr);
|
||||||
|
|
|
@ -73,6 +73,25 @@ class test_alerts(unittest.TestCase):
|
||||||
print(st.info_hash)
|
print(st.info_hash)
|
||||||
self.assertEqual(st.save_path, os.getcwd())
|
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):
|
class test_bencoder(unittest.TestCase):
|
||||||
|
|
||||||
def test_bencode(self):
|
def test_bencode(self):
|
||||||
|
|
|
@ -163,9 +163,9 @@ namespace libtorrent {
|
||||||
const static int header_size = (sizeof(header_t) + sizeof(uintptr_t)
|
const static int header_size = (sizeof(header_t) + sizeof(uintptr_t)
|
||||||
- 1) / 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));
|
, (std::max)(m_capacity * 3 / 2, 128));
|
||||||
|
|
||||||
uintptr_t* new_storage = new uintptr_t[m_capacity + amount_to_grow];
|
uintptr_t* new_storage = new uintptr_t[m_capacity + amount_to_grow];
|
||||||
|
|
Loading…
Reference in New Issue