You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ac...@apache.org on 2017/01/18 01:16:18 UTC
[02/10] qpid-proton git commit: PROTON-1312: fix memory leak on
BlockingConnection.close()
PROTON-1312: fix memory leak on BlockingConnection.close()
Project: http://git-wip-us.apache.org/repos/asf/qpid-proton/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-proton/commit/98e26f69
Tree: http://git-wip-us.apache.org/repos/asf/qpid-proton/tree/98e26f69
Diff: http://git-wip-us.apache.org/repos/asf/qpid-proton/diff/98e26f69
Branch: refs/heads/go1
Commit: 98e26f69995e6628c4b6c97b1826a761d9168d8c
Parents: 431c00d
Author: Clifford Jansen <cl...@apache.org>
Authored: Wed Jan 11 14:20:14 2017 -0800
Committer: Clifford Jansen <cl...@apache.org>
Committed: Wed Jan 11 14:20:14 2017 -0800
----------------------------------------------------------------------
proton-c/bindings/python/proton/__init__.py | 3 +++
proton-c/bindings/python/proton/reactor.py | 5 -----
proton-c/bindings/python/proton/utils.py | 14 ++++++++++++++
3 files changed, 17 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/98e26f69/proton-c/bindings/python/proton/__init__.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton/__init__.py b/proton-c/bindings/python/proton/__init__.py
index cfac01e..2b354df 100644
--- a/proton-c/bindings/python/proton/__init__.py
+++ b/proton-c/bindings/python/proton/__init__.py
@@ -2581,6 +2581,9 @@ and SASL layers to identify the peer.
"""
self._update_cond()
pn_connection_close(self._impl)
+ if hasattr(self, '_session_policy'):
+ # break circular ref
+ del self._session_policy
@property
def state(self):
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/98e26f69/proton-c/bindings/python/proton/reactor.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton/reactor.py b/proton-c/bindings/python/proton/reactor.py
index e4dab95..269ed9e 100644
--- a/proton-c/bindings/python/proton/reactor.py
+++ b/proton-c/bindings/python/proton/reactor.py
@@ -494,13 +494,8 @@ class SessionPerConnection(object):
def session(self, connection):
if not self._default_session:
self._default_session = _create_session(connection)
- self._default_session.context = self
return self._default_session
- def on_session_remote_close(self, event):
- event.connection.close()
- self._default_session = None
-
class GlobalOverrides(object):
"""
Internal handler that triggers the necessary socket connect for an
http://git-wip-us.apache.org/repos/asf/qpid-proton/blob/98e26f69/proton-c/bindings/python/proton/utils.py
----------------------------------------------------------------------
diff --git a/proton-c/bindings/python/proton/utils.py b/proton-c/bindings/python/proton/utils.py
index 9cd7cf3..05ef80d 100644
--- a/proton-c/bindings/python/proton/utils.py
+++ b/proton-c/bindings/python/proton/utils.py
@@ -132,10 +132,15 @@ class BlockingReceiver(BlockingLink):
raise LinkException("Failed to open receiver %s, source does not match" % self.link.name)
if credit: receiver.flow(credit)
self.fetcher = fetcher
+ self.container = connection.container
def __del__(self):
self.fetcher = None
+ # The next line causes a core dump if the Proton-C reactor finalizes
+ # first. The self.container reference prevents reactor finalization
+ # until after it is set to None.
self.link.handler = None
+ self.container = None
def receive(self, timeout=False):
if not self.fetcher:
@@ -222,12 +227,19 @@ class BlockingConnection(Handler):
self, self.container.create_receiver(self.conn, address, name=name, dynamic=dynamic, handler=handler or fetcher, options=options), fetcher, credit=prefetch)
def close(self):
+ if not self.conn:
+ return
self.conn.close()
try:
self.wait(lambda: not (self.conn.state & Endpoint.REMOTE_ACTIVE),
msg="Closing connection")
finally:
+ self.conn.free()
+ # For cleanup, reactor needs to process PN_CONNECTION_FINAL
+ # and all events with embedded contexts must be drained.
+ self.run() # will not block any more
self.conn = None
+ self.container.global_handler = None # break circular ref: container to cadapter.on_error
self.container = None
def _is_closed(self):
@@ -236,6 +248,8 @@ class BlockingConnection(Handler):
def run(self):
""" Hand control over to the event loop (e.g. if waiting indefinitely for incoming messages) """
while self.container.process(): pass
+ self.container.stop()
+ self.container.process()
def wait(self, condition, timeout=False, msg=None):
"""Call process until condition() is true"""
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org