[Xcb] [PATCH 7/7] Avoid reference cycles in response instances.
Alex Plotnick
shrike at netaxs.com
Wed Feb 29 08:59:57 PST 2012
The issue is with fields that use self as the parent buffer; we end
up with cycles that the GC can't collect, since buffer objects aren't
GC-aware.
Also took the opportunity to replace separate "count" variables with
offsets wherever possible, and skip size calculations entirely for
fixed-size Unions.
---
src/py_client.py | 67 ++++++++++++++++++++++++++++-------------------------
1 files changed, 35 insertions(+), 32 deletions(-)
diff --git a/src/py_client.py b/src/py_client.py
index 961c60c..d897ecd 100755
--- a/src/py_client.py
+++ b/src/py_client.py
@@ -300,7 +300,6 @@ def _py_type_alignsize(field):
def _py_complex(self, name):
need_alignment = False
- _py(' count = 0')
for field in self.fields:
if field.auto:
@@ -315,33 +314,33 @@ def _py_complex(self, name):
(format, size, list) = _py_flush_format()
if len(list) > 0:
- _py(' (%s,) = unpack_from(\'%s\', self, count)', list, format)
+ _py(' (%s,) = unpack_from(\'%s\', parent, offset)', list, format)
if size > 0:
- _py(' count += %d', size)
+ _py(' offset += %d', size)
if need_alignment:
- _py(' count += xcb.type_pad(%d, count)', _py_type_alignsize(field))
+ _py(' offset += xcb.type_pad(%d, offset)', _py_type_alignsize(field))
need_alignment = True
if field.type.is_list:
- _py(' self.%s = xcb.List(self, count, %s, %s, %d)', _n(field.field_name), _py_get_expr(field.type.expr), field.py_listtype, field.py_listsize)
- _py(' count += len(self.%s.buf())', _n(field.field_name))
+ _py(' self.%s = xcb.List(parent, offset, %s, %s, %d)', _n(field.field_name), _py_get_expr(field.type.expr), field.py_listtype, field.py_listsize)
+ _py(' offset += len(self.%s.buf())', _n(field.field_name))
elif field.type.is_container and field.type.fixed_size():
- _py(' self.%s = %s(self, count, %s)', _n(field.field_name), field.py_type, field.type.size)
- _py(' count += %s', field.type.size)
+ _py(' self.%s = %s(parent, offset, %s)', _n(field.field_name), field.py_type, field.type.size)
+ _py(' offset += %s', field.type.size)
else:
- _py(' self.%s = %s(self, count)', _n(field.field_name), field.py_type)
- _py(' count += len(self.%s)', _n(field.field_name))
+ _py(' self.%s = %s(parent, offset)', _n(field.field_name), field.py_type)
+ _py(' offset += len(self.%s)', _n(field.field_name))
(format, size, list) = _py_flush_format()
if len(list) > 0:
if need_alignment:
- _py(' count += xcb.type_pad(4, count)')
- _py(' (%s,) = unpack_from(\'%s\', self, count)', list, format)
- _py(' count += %d', size)
+ _py(' offset += xcb.type_pad(4, offset)')
+ _py(' (%s,) = unpack_from(\'%s\', parent, offset)', list, format)
+ _py(' offset += %d', size)
if self.fixed_size() or self.is_reply:
- if len(self.fields) > 0:
+ if self.fields and not all(field.auto or field.type.is_pad for field in self.fields):
_py_popline()
def py_struct(self, name):
@@ -359,11 +358,12 @@ def py_struct(self, name):
else:
_py(' def __init__(self, parent, offset):')
_py(' xcb.Struct.__init__(self, parent, offset)')
+ _py(' base = offset')
_py_complex(self, name)
if not self.fixed_size():
- _py(' xcb._resize_obj(self, count)')
+ _py(' xcb._resize_obj(self, offset - base)')
def py_union(self, name):
'''
@@ -380,25 +380,28 @@ def py_union(self, name):
else:
_py(' def __init__(self, parent, offset):')
_py(' xcb.Union.__init__(self, parent, offset)')
-
- _py(' count = 0')
+ _py(' size = 0')
for field in self.fields:
if field.type.is_simple:
- _py(' self.%s = unpack_from(\'%s\', self)', _n(field.field_name), field.type.py_format_str)
- _py(' count = max(count, %s)', field.type.size)
+ _py(' self.%s = unpack_from(\'%s\', parent, offset)', _n(field.field_name), field.type.py_format_str)
+ if not self.fixed_size():
+ _py(' size = max(size, %s)', field.type.size)
elif field.type.is_list:
- _py(' self.%s = xcb.List(self, 0, %s, %s, %s)', _n(field.field_name), _py_get_expr(field.type.expr), field.py_listtype, field.py_listsize)
- _py(' count = max(count, len(self.%s.buf()))', _n(field.field_name))
+ _py(' self.%s = xcb.List(parent, offset, %s, %s, %s)', _n(field.field_name), _py_get_expr(field.type.expr), field.py_listtype, field.py_listsize)
+ if not self.fixed_size():
+ _py(' size = max(size, len(self.%s.buf()))', _n(field.field_name))
elif field.type.is_container and field.type.fixed_size():
- _py(' self.%s = %s(self, 0, %s)', _n(field.field_name), field.py_type, field.type.size)
- _py(' count = max(count, %s)', field.type.size)
+ _py(' self.%s = %s(parent, offset, %s)', _n(field.field_name), field.py_type, field.type.size)
+ if not self.fixed_size():
+ _py(' size = max(size, %s)', field.type.size)
else:
- _py(' self.%s = %s(self, 0)', _n(field.field_name), field.py_type)
- _py(' count = max(count, len(self.%s))', _n(field.field_name))
+ _py(' self.%s = %s(parent, offset)', _n(field.field_name), field.py_type)
+ if not self.fixed_size():
+ _py(' size = max(size, len(self.%s))', _n(field.field_name))
if not self.fixed_size():
- _py(' xcb._resize_obj(self, count)')
+ _py(' xcb._resize_obj(self, size)')
def _py_reply(self, name):
'''
@@ -409,8 +412,8 @@ def _py_reply(self, name):
_py_setlevel(0)
_py('')
_py('class %s(xcb.Reply):', self.py_reply_name)
- _py(' def __init__(self, parent):')
- _py(' xcb.Reply.__init__(self, parent)')
+ _py(' def __init__(self, parent, offset=0):')
+ _py(' xcb.Reply.__init__(self, parent, offset)')
_py_complex(self, name)
@@ -537,8 +540,8 @@ def py_event(self, name):
_py_setlevel(0)
_py('')
_py('class %s(xcb.Event):', self.py_event_name)
- _py(' def __init__(self, parent):')
- _py(' xcb.Event.__init__(self, parent)')
+ _py(' def __init__(self, parent, offset=0):')
+ _py(' xcb.Event.__init__(self, parent, offset)')
_py_complex(self, name)
@@ -556,8 +559,8 @@ def py_error(self, name):
_py_setlevel(0)
_py('')
_py('class %s(xcb.Error):', self.py_error_name)
- _py(' def __init__(self, parent):')
- _py(' xcb.Error.__init__(self, parent)')
+ _py(' def __init__(self, parent, offset=0):')
+ _py(' xcb.Error.__init__(self, parent, offset)')
_py_complex(self, name)
--
1.7.6
More information about the Xcb
mailing list