Allow syncronizer to be GC-ed

Proper fix for #1525.
Using python's GC module, I've verified that the daemon, when running,
now releases all verifiers, synchronizers and wallets - all the resources
we care about releasing.
This commit is contained in:
Neil Booth 2015-11-12 08:40:58 +09:00
parent d612684196
commit 8cc3b58364
3 changed files with 14 additions and 1 deletions

View File

@ -556,6 +556,13 @@ class Network(util.DaemonThread):
message_id = self.queue_request(method, params)
self.unanswered_requests[message_id] = method, params, callback
def unsubscribe(self, callback):
'''Unsubscribe a callback to free object references to enable GC.'''
# Note: we can't unsubscribe from the server, so if we receive
# subsequent notifications process_response() will emit a harmless
# "received unexpected notification" warning
self.subscriptions.pop(callback, None)
def connection_down(self, server):
'''A connection to server either went down, or was never made.
We distinguish by whether it is in self.interfaces.'''

View File

@ -56,6 +56,9 @@ class Synchronizer(ThreadJob):
return (not self.requested_tx and not self.requested_histories
and not self.requested_addrs)
def release(self):
self.network.unsubscribe(self.addr_subscription_response)
def add(self, address):
'''This can be called from the proxy or GUI threads.'''
with self.lock:

View File

@ -36,6 +36,7 @@ from transaction import Transaction
from plugins import run_hook
import bitcoin
from synchronizer import Synchronizer
from verifier import SPV
from mnemonic import Mnemonic
import paymentrequest
@ -1128,7 +1129,6 @@ class Abstract_Wallet(PrintError):
self.transactions.pop(tx_hash)
def start_threads(self, network):
from verifier import SPV
self.network = network
if self.network is not None:
self.prepare_for_verifier()
@ -1142,8 +1142,11 @@ class Abstract_Wallet(PrintError):
def stop_threads(self):
if self.network:
self.network.remove_jobs([self.synchronizer, self.verifier])
self.synchronizer.release()
self.synchronizer = None
self.verifier = None
# Now no references to the syncronizer or verifier
# remain so they will be GC-ed
self.storage.put('stored_height', self.get_local_height(), True)
def wait_until_synchronized(self, callback=None):