mirror of
https://github.com/virt-manager/virt-manager.git
synced 2026-07-29 15:55:32 -05:00
virtManager: misc reference leak fixes
Signed-off-by: Cole Robinson <crobinso@redhat.com>
This commit is contained in:
@@ -1068,6 +1068,7 @@ class vmmConnection(vmmGObject):
|
|||||||
if not self._objects.add(obj):
|
if not self._objects.add(obj):
|
||||||
log.debug("New %s=%s requested, but it's already tracked.",
|
log.debug("New %s=%s requested, but it's already tracked.",
|
||||||
class_name, obj.get_name())
|
class_name, obj.get_name())
|
||||||
|
obj.cleanup()
|
||||||
return
|
return
|
||||||
|
|
||||||
if not obj.is_nodedev():
|
if not obj.is_nodedev():
|
||||||
|
|||||||
@@ -1890,8 +1890,11 @@ class vmmCreateVM(vmmGObjectUI):
|
|||||||
|
|
||||||
# We can re-enter this: cleanup() -> close() -> "details-closed"
|
# We can re-enter this: cleanup() -> close() -> "details-closed"
|
||||||
window = self._customize_window
|
window = self._customize_window
|
||||||
|
virtinst_domain = self._customize_window.vm
|
||||||
self._customize_window = None
|
self._customize_window = None
|
||||||
window.cleanup()
|
window.cleanup()
|
||||||
|
virtinst_domain.cleanup()
|
||||||
|
virtinst_domain = None
|
||||||
|
|
||||||
def _show_customize_dialog(self, origguest, installer):
|
def _show_customize_dialog(self, origguest, installer):
|
||||||
orig_vdomain = vmmDomainVirtinst(self.conn,
|
orig_vdomain = vmmDomainVirtinst(self.conn,
|
||||||
|
|||||||
@@ -532,6 +532,10 @@ class vmmDetails(vmmGObjectUI):
|
|||||||
self.vsockdetails = None
|
self.vsockdetails = None
|
||||||
self._xmleditor.cleanup()
|
self._xmleditor.cleanup()
|
||||||
self._xmleditor = None
|
self._xmleditor = None
|
||||||
|
self._addstorage.cleanup()
|
||||||
|
self._addstorage = None
|
||||||
|
self._os_list.cleanup()
|
||||||
|
self._os_list = None
|
||||||
|
|
||||||
|
|
||||||
##########################
|
##########################
|
||||||
|
|||||||
@@ -440,6 +440,34 @@ class VNCViewer(Viewer):
|
|||||||
# Spice viewer class #
|
# Spice viewer class #
|
||||||
######################
|
######################
|
||||||
|
|
||||||
|
class _SignalTracker:
|
||||||
|
# Helper class to more conveniently connect and disconnect signals
|
||||||
|
# from spice objects. This ensures we don't leave circular references
|
||||||
|
# at object destroy time
|
||||||
|
def __init__(self):
|
||||||
|
self._sigmap = {}
|
||||||
|
|
||||||
|
def _add_hid(self, obj, hid):
|
||||||
|
if obj not in self._sigmap:
|
||||||
|
self._sigmap[obj] = []
|
||||||
|
self._sigmap[obj].append(hid)
|
||||||
|
|
||||||
|
def connect(self, obj, name, handler, *args):
|
||||||
|
hid = GObject.GObject.connect(obj, name, handler, *args)
|
||||||
|
self._add_hid(obj, hid)
|
||||||
|
|
||||||
|
def connect_after(self, obj, name, handler, *args):
|
||||||
|
hid = GObject.GObject.connect_after(obj, name, handler, *args)
|
||||||
|
self._add_hid(obj, hid)
|
||||||
|
|
||||||
|
def disconnect_obj_signals(self, obj):
|
||||||
|
for hid in self._sigmap.get(obj, []):
|
||||||
|
GObject.GObject.disconnect(obj, hid)
|
||||||
|
|
||||||
|
|
||||||
|
_SIGS = _SignalTracker()
|
||||||
|
|
||||||
|
|
||||||
class SpiceViewer(Viewer):
|
class SpiceViewer(Viewer):
|
||||||
viewer_type = "spice"
|
viewer_type = "spice"
|
||||||
|
|
||||||
@@ -449,9 +477,9 @@ class SpiceViewer(Viewer):
|
|||||||
self._display = None
|
self._display = None
|
||||||
self._audio = None
|
self._audio = None
|
||||||
self._main_channel = None
|
self._main_channel = None
|
||||||
self._main_channel_hids = []
|
|
||||||
self._display_channel = None
|
self._display_channel = None
|
||||||
self._usbdev_manager = None
|
self._usbdev_manager = None
|
||||||
|
self._channels = set()
|
||||||
|
|
||||||
|
|
||||||
###################
|
###################
|
||||||
@@ -472,29 +500,24 @@ class SpiceViewer(Viewer):
|
|||||||
else:
|
else:
|
||||||
self.emit("pointer-ungrab")
|
self.emit("pointer-ungrab")
|
||||||
|
|
||||||
def _close_main_channel(self):
|
|
||||||
for i in self._main_channel_hids:
|
|
||||||
self._main_channel.handler_disconnect(i)
|
|
||||||
self._main_channel_hids = []
|
|
||||||
self._main_channel = None
|
|
||||||
|
|
||||||
def _create_spice_session(self):
|
def _create_spice_session(self):
|
||||||
self._spice_session = SpiceClientGLib.Session()
|
self._spice_session = SpiceClientGLib.Session()
|
||||||
SpiceClientGLib.set_session_option(self._spice_session)
|
SpiceClientGLib.set_session_option(self._spice_session)
|
||||||
gtk_session = SpiceClientGtk.GtkSession.get(self._spice_session)
|
gtk_session = SpiceClientGtk.GtkSession.get(self._spice_session)
|
||||||
gtk_session.set_property("auto-clipboard", True)
|
gtk_session.set_property("auto-clipboard", True)
|
||||||
|
|
||||||
GObject.GObject.connect(self._spice_session, "channel-new",
|
_SIGS.connect(self._spice_session, "channel-new", self._channel_new_cb)
|
||||||
self._channel_new_cb)
|
|
||||||
|
|
||||||
# Distros might have usb redirection compiled out, like OpenBSD
|
# Distros might have usb redirection compiled out, like OpenBSD
|
||||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1348479
|
# https://bugzilla.redhat.com/show_bug.cgi?id=1348479
|
||||||
try:
|
try:
|
||||||
self._usbdev_manager = SpiceClientGLib.UsbDeviceManager.get(
|
self._usbdev_manager = SpiceClientGLib.UsbDeviceManager.get(
|
||||||
self._spice_session)
|
self._spice_session)
|
||||||
self._usbdev_manager.connect("auto-connect-failed",
|
_SIGS.connect(
|
||||||
|
self._usbdev_manager, "auto-connect-failed",
|
||||||
self._usbdev_redirect_error)
|
self._usbdev_redirect_error)
|
||||||
self._usbdev_manager.connect("device-error",
|
_SIGS.connect(
|
||||||
|
self._usbdev_manager, "device-error",
|
||||||
self._usbdev_redirect_error)
|
self._usbdev_redirect_error)
|
||||||
|
|
||||||
autoredir = self.config.get_auto_usbredir()
|
autoredir = self.config.get_auto_usbredir()
|
||||||
@@ -560,18 +583,18 @@ class SpiceViewer(Viewer):
|
|||||||
channel.open_fd(fd)
|
channel.open_fd(fd)
|
||||||
|
|
||||||
def _channel_new_cb(self, session, channel):
|
def _channel_new_cb(self, session, channel):
|
||||||
GObject.GObject.connect(channel, "open-fd",
|
self._channels.add(channel)
|
||||||
self._channel_open_fd_request)
|
_SIGS.connect(channel, "open-fd", self._channel_open_fd_request)
|
||||||
|
|
||||||
if (isinstance(channel, SpiceClientGLib.MainChannel) and
|
if (isinstance(channel, SpiceClientGLib.MainChannel) and
|
||||||
not self._main_channel):
|
not self._main_channel):
|
||||||
self._main_channel = channel
|
self._main_channel = channel
|
||||||
hid = self._main_channel.connect_after("channel-event",
|
_SIGS.connect_after(
|
||||||
|
self._main_channel, "channel-event",
|
||||||
self._main_channel_event_cb)
|
self._main_channel_event_cb)
|
||||||
self._main_channel_hids.append(hid)
|
_SIGS.connect_after(
|
||||||
hid = self._main_channel.connect_after("notify::agent-connected",
|
self._main_channel, "notify::agent-connected",
|
||||||
self._agent_connected_cb)
|
self._agent_connected_cb)
|
||||||
self._main_channel_hids.append(hid)
|
|
||||||
|
|
||||||
elif (type(channel) == SpiceClientGLib.DisplayChannel and
|
elif (type(channel) == SpiceClientGLib.DisplayChannel and
|
||||||
not self._display):
|
not self._display):
|
||||||
@@ -602,6 +625,7 @@ class SpiceViewer(Viewer):
|
|||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
if self._spice_session is not None:
|
if self._spice_session is not None:
|
||||||
|
_SIGS.disconnect_obj_signals(self._spice_session)
|
||||||
self._spice_session.disconnect()
|
self._spice_session.disconnect()
|
||||||
self._spice_session = None
|
self._spice_session = None
|
||||||
self._audio = None
|
self._audio = None
|
||||||
@@ -610,7 +634,13 @@ class SpiceViewer(Viewer):
|
|||||||
self._display = None
|
self._display = None
|
||||||
self._display_channel = None
|
self._display_channel = None
|
||||||
|
|
||||||
self._close_main_channel()
|
for channel in self._channels:
|
||||||
|
_SIGS.disconnect_obj_signals(channel)
|
||||||
|
self._channels = None
|
||||||
|
|
||||||
|
self._main_channel = None
|
||||||
|
|
||||||
|
_SIGS.disconnect_obj_signals(self._usbdev_manager)
|
||||||
self._usbdev_manager = None
|
self._usbdev_manager = None
|
||||||
|
|
||||||
def _is_open(self):
|
def _is_open(self):
|
||||||
|
|||||||
@@ -60,6 +60,8 @@ class vmmAddStorage(vmmGObjectUI):
|
|||||||
|
|
||||||
def _cleanup(self):
|
def _cleanup(self):
|
||||||
self.conn = None
|
self.conn = None
|
||||||
|
self.top_box.destroy()
|
||||||
|
self.advanced_top_box.destroy()
|
||||||
|
|
||||||
|
|
||||||
##########################
|
##########################
|
||||||
|
|||||||
@@ -1659,6 +1659,11 @@ class vmmDomainVirtinst(vmmDomain):
|
|||||||
def _get_backend_status(self):
|
def _get_backend_status(self):
|
||||||
return libvirt.VIR_DOMAIN_SHUTOFF
|
return libvirt.VIR_DOMAIN_SHUTOFF
|
||||||
|
|
||||||
|
def _cleanup(self):
|
||||||
|
self._orig_backend = None
|
||||||
|
self._installer = None
|
||||||
|
super()._cleanup()
|
||||||
|
|
||||||
|
|
||||||
################
|
################
|
||||||
# XML handling #
|
# XML handling #
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ class vmmXMLEditor(vmmGObjectUI):
|
|||||||
self._curpage = _PAGE_DETAILS
|
self._curpage = _PAGE_DETAILS
|
||||||
self._srcxml = ""
|
self._srcxml = ""
|
||||||
self._srcview = None
|
self._srcview = None
|
||||||
self._srcbuf = None
|
self._srcbuff = None
|
||||||
self._init_ui()
|
self._init_ui()
|
||||||
|
|
||||||
self.details_changed = False
|
self.details_changed = False
|
||||||
@@ -51,7 +51,8 @@ class vmmXMLEditor(vmmGObjectUI):
|
|||||||
|
|
||||||
|
|
||||||
def _cleanup(self):
|
def _cleanup(self):
|
||||||
pass
|
self._srcview.destroy()
|
||||||
|
self._srcbuff = None
|
||||||
|
|
||||||
|
|
||||||
###########
|
###########
|
||||||
|
|||||||
Reference in New Issue
Block a user