summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Plotnick <shrike@netaxs.com>2012-02-29 11:59:57 -0500
committerJulien Danjou <julien@danjou.info>2012-03-22 21:29:10 +0100
commit057b54d4bcd5b383343e00a3685e6b1ef343c2d2 (patch)
treed2c6b84efcd2c9ece3a1aaf45cf2e76e28887bd4
parentc5ff7fbf5a53cc20984a20d5461be2fc1f1eac39 (diff)
Avoid reference cycles in response instances.
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. Signed-off-by: Julien Danjou <julien@danjou.info>
-rwxr-xr-xsrc/py_client.py67
1 files changed, 35 insertions, 32 deletions
diff --git a/src/py_client.py b/src/py_client.py
index 61be2ae..d132f43 100755
--- a/src/py_client.py
+++ b/src/py_client.py
@@ -304,7 +304,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:
@@ -319,33 +318,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):
@@ -363,11 +362,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):
'''
@@ -384,25 +384,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):
'''
@@ -413,8 +416,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)
@@ -541,8 +544,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)
@@ -560,8 +563,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)