[Core] Copy lt alerts to avoid segfaults
Changes in libtorrent 1.1 mean that alerts are no longer allowed to be accessed after the next call to pop_alerts. > It is safe to call pop_alerts from multiple different threads, as long as the alerts themselves are not accessed once another thread calls pop_alerts. Doing this requires manual synchronization between the popping threads. The solution is to copy the alert attributes and pass that to the handlers. Refs: https://github.com/arvidn/libtorrent/issues/2779 #3159
This commit is contained in:
parent
4212bd6800
commit
be74d96c6a
|
@ -18,6 +18,7 @@ This should typically only be used by the Core. Plugins should utilize the
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
import types
|
||||||
|
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
|
|
||||||
|
@ -124,7 +125,15 @@ class AlertManager(component.Component):
|
||||||
for handler in self.handlers[alert_type]:
|
for handler in self.handlers[alert_type]:
|
||||||
if log.isEnabledFor(logging.DEBUG):
|
if log.isEnabledFor(logging.DEBUG):
|
||||||
log.debug('Handling alert: %s', alert_type)
|
log.debug('Handling alert: %s', alert_type)
|
||||||
self.delayed_calls.append(reactor.callLater(0, handler, alert))
|
# Copy alert attributes
|
||||||
|
alert_copy = types.SimpleNamespace(
|
||||||
|
**{
|
||||||
|
attr: getattr(alert, attr)
|
||||||
|
for attr in dir(alert)
|
||||||
|
if not attr.startswith('__')
|
||||||
|
}
|
||||||
|
)
|
||||||
|
self.delayed_calls.append(reactor.callLater(0, handler, alert_copy))
|
||||||
|
|
||||||
def set_alert_queue_size(self, queue_size):
|
def set_alert_queue_size(self, queue_size):
|
||||||
"""Sets the maximum size of the libtorrent alert queue"""
|
"""Sets the maximum size of the libtorrent alert queue"""
|
||||||
|
|
Loading…
Reference in New Issue