Pyolian: fix segfault on shutdown
also improve abit all_namespaces performance by using a set (hashable)
This commit is contained in:
parent
b9ed84f4ed
commit
a2b24d0948
|
@ -24,6 +24,7 @@ a way that this folder will be available on PYTHON_PATH, fe:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
|
import atexit
|
||||||
from ctypes import cast, byref, c_char_p, c_void_p, c_int
|
from ctypes import cast, byref, c_char_p, c_void_p, c_int
|
||||||
import ctypes
|
import ctypes
|
||||||
|
|
||||||
|
@ -32,6 +33,7 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from eolian_lib import lib
|
from eolian_lib import lib
|
||||||
|
|
||||||
|
_already_halted = False
|
||||||
|
|
||||||
### Eolian Enums ############################################################
|
### Eolian Enums ############################################################
|
||||||
|
|
||||||
|
@ -303,13 +305,16 @@ class Eolian_Unit(EolianBaseObject):
|
||||||
@property
|
@property
|
||||||
def all_namespaces(self):
|
def all_namespaces(self):
|
||||||
# TODO find a better way to find namespaces (maybe inside eolian?)
|
# TODO find a better way to find namespaces (maybe inside eolian?)
|
||||||
nspaces = []
|
nspaces = set()
|
||||||
for cls in self.all_classes:
|
for obj in self.all_classes:
|
||||||
ns = Namespace(self, cls.namespace)
|
nspaces.add(Namespace(self, obj.namespace))
|
||||||
if not ns in nspaces:
|
for obj in self.typedecl_all_aliases:
|
||||||
nspaces.append(ns)
|
nspaces.add(Namespace(self, obj.namespace))
|
||||||
nspaces.sort()
|
for obj in self.typedecl_all_structs:
|
||||||
return nspaces
|
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):
|
def namespace_get_by_name(self, name):
|
||||||
return Namespace(self, name)
|
return Namespace(self, name)
|
||||||
|
@ -392,10 +397,8 @@ class Eolian(Eolian_Unit):
|
||||||
self._obj = lib.eolian_new() # Eolian *
|
self._obj = lib.eolian_new() # Eolian *
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
# TODO I'm not sure about this, It is automatically called on gc, that
|
if not _already_halted: # do not free after eolian_shutdown
|
||||||
# is fired after atexit (eolian_shutdown). Thus causing a segfault
|
lib.eolian_free(self._obj)
|
||||||
# if the user do not call del before exit.
|
|
||||||
lib.eolian_free(self._obj)
|
|
||||||
|
|
||||||
def file_parse(self, filepath):
|
def file_parse(self, filepath):
|
||||||
c_unit = lib.eolian_file_parse(self._obj, _str_to_bytes(filepath))
|
c_unit = lib.eolian_file_parse(self._obj, _str_to_bytes(filepath))
|
||||||
|
@ -449,6 +452,9 @@ class Namespace(object):
|
||||||
def __gt__(self, other):
|
def __gt__(self, other):
|
||||||
return self.name > other.name
|
return self.name > other.name
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash(self._name)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
return self._name
|
return self._name
|
||||||
|
@ -1420,10 +1426,13 @@ def _str_to_py(s):
|
||||||
|
|
||||||
|
|
||||||
### module init/shutdown ####################################################
|
### module init/shutdown ####################################################
|
||||||
|
def _cleanup():
|
||||||
|
global _already_halted
|
||||||
|
lib.eolian_shutdown()
|
||||||
|
_already_halted = True
|
||||||
|
|
||||||
import atexit
|
|
||||||
lib.eolian_init()
|
lib.eolian_init()
|
||||||
atexit.register(lambda: lib.eolian_shutdown())
|
atexit.register(_cleanup)
|
||||||
|
|
||||||
|
|
||||||
### API coverage statistics #################################################
|
### API coverage statistics #################################################
|
||||||
|
|
|
@ -174,8 +174,8 @@ class Template(pyratemp.Template):
|
||||||
ctx['alias'] = eolian_db.typedecl_alias_get_by_name(alias)
|
ctx['alias'] = eolian_db.typedecl_alias_get_by_name(alias)
|
||||||
|
|
||||||
if verbose and filename:
|
if verbose and filename:
|
||||||
print('generating "{}" from template "{}"'.format(
|
print("rendering: {} => {}".format(
|
||||||
filename, self.template_filename))
|
self.template_filename, filename))
|
||||||
|
|
||||||
# render with the augmented context
|
# render with the augmented context
|
||||||
output = self(**ctx)
|
output = self(**ctx)
|
||||||
|
|
|
@ -154,7 +154,7 @@ class TestEolianNamespace(unittest.TestCase):
|
||||||
for ns in state.all_namespaces:
|
for ns in state.all_namespaces:
|
||||||
self.assertIsInstance(ns, eolian.Namespace)
|
self.assertIsInstance(ns, eolian.Namespace)
|
||||||
count += 1
|
count += 1
|
||||||
self.assertGreater(count, 100)
|
self.assertGreater(count, 200)
|
||||||
|
|
||||||
def test_namespace_equality(self):
|
def test_namespace_equality(self):
|
||||||
ns1 = eolian.Namespace(state, 'Efl.Io')
|
ns1 = eolian.Namespace(state, 'Efl.Io')
|
||||||
|
|
Loading…
Reference in New Issue