Pyolian: fix segfault on shutdown

also improve abit all_namespaces performance by using a set (hashable)
This commit is contained in:
Davide Andreoli 2018-01-02 21:52:57 +01:00
parent b9ed84f4ed
commit a2b24d0948
3 changed files with 25 additions and 16 deletions

View File

@ -24,6 +24,7 @@ a way that this folder will be available on PYTHON_PATH, fe:
"""
from enum import IntEnum
import atexit
from ctypes import cast, byref, c_char_p, c_void_p, c_int
import ctypes
@ -32,6 +33,7 @@ try:
except ImportError:
from eolian_lib import lib
_already_halted = False
### Eolian Enums ############################################################
@ -303,13 +305,16 @@ class Eolian_Unit(EolianBaseObject):
@property
def all_namespaces(self):
# TODO find a better way to find namespaces (maybe inside eolian?)
nspaces = []
for cls in self.all_classes:
ns = Namespace(self, cls.namespace)
if not ns in nspaces:
nspaces.append(ns)
nspaces.sort()
return nspaces
nspaces = set()
for obj in self.all_classes:
nspaces.add(Namespace(self, obj.namespace))
for obj in self.typedecl_all_aliases:
nspaces.add(Namespace(self, obj.namespace))
for obj in self.typedecl_all_structs:
nspaces.add(Namespace(self, obj.namespace))
for obj in self.typedecl_all_enums:
nspaces.add(Namespace(self, obj.namespace))
return sorted(nspaces)
def namespace_get_by_name(self, name):
return Namespace(self, name)
@ -392,10 +397,8 @@ class Eolian(Eolian_Unit):
self._obj = lib.eolian_new() # Eolian *
def __del__(self):
# TODO I'm not sure about this, It is automatically called on gc, that
# is fired after atexit (eolian_shutdown). Thus causing a segfault
# if the user do not call del before exit.
lib.eolian_free(self._obj)
if not _already_halted: # do not free after eolian_shutdown
lib.eolian_free(self._obj)
def file_parse(self, filepath):
c_unit = lib.eolian_file_parse(self._obj, _str_to_bytes(filepath))
@ -449,6 +452,9 @@ class Namespace(object):
def __gt__(self, other):
return self.name > other.name
def __hash__(self):
return hash(self._name)
@property
def name(self):
return self._name
@ -1420,10 +1426,13 @@ def _str_to_py(s):
### module init/shutdown ####################################################
def _cleanup():
global _already_halted
lib.eolian_shutdown()
_already_halted = True
import atexit
lib.eolian_init()
atexit.register(lambda: lib.eolian_shutdown())
atexit.register(_cleanup)
### API coverage statistics #################################################

View File

@ -174,8 +174,8 @@ class Template(pyratemp.Template):
ctx['alias'] = eolian_db.typedecl_alias_get_by_name(alias)
if verbose and filename:
print('generating "{}" from template "{}"'.format(
filename, self.template_filename))
print("rendering: {} => {}".format(
self.template_filename, filename))
# render with the augmented context
output = self(**ctx)

View File

@ -154,7 +154,7 @@ class TestEolianNamespace(unittest.TestCase):
for ns in state.all_namespaces:
self.assertIsInstance(ns, eolian.Namespace)
count += 1
self.assertGreater(count, 100)
self.assertGreater(count, 200)
def test_namespace_equality(self):
ns1 = eolian.Namespace(state, 'Efl.Io')