Fixed an internal error happening when a librrary isn't registered and destroyed by the GC

This commit is contained in:
Matthias Koefferlein 2020-08-30 11:35:30 +02:00
parent 79d3676257
commit eccbb9884c
6 changed files with 48 additions and 19 deletions

View File

@ -238,7 +238,6 @@ namespace tl
*/
template <> struct type_traits <db::Library> : public type_traits<void> {
typedef tl::false_tag has_copy_constructor;
typedef tl::false_tag has_public_destructor;
};
}

View File

@ -78,18 +78,35 @@ static std::string get_technology (db::Library *lib)
}
}
static void dummy_destroy (db::Library *) { }
static void destroy_lib (db::Library *lib)
{
if (db::LibraryManager::instance ().lib_ptr_by_name (lib->get_name ()) == lib) {
// Library is registered -> do not delete
} else {
delete lib;
}
}
Class<db::Library> decl_Library ("db", "Library",
gsi::method_ext ("_destroy", &dummy_destroy,
"@brief An inactive substitute for _destroy (delete the object)\n"
"As libraries need to be kept if cells are using them, library objects must "
"not be deleted. Hence the default '_destroy' implementation must not be called. "
"To keep old code working, this substitute is provided. It just returns without "
"deleting the object.\n"
"\n"
"This method has been introduced in version 0.26.7."
) +
namespace {
class LibraryClass
: public Class<db::Library>
{
public:
LibraryClass (const char *module, const char *name, const gsi::Methods &methods, const char *description)
: Class<db::Library> (module, name, methods, description)
{ }
virtual void destroy (void *p) const
{
db::Library *lib = reinterpret_cast<db::Library *> (p);
destroy_lib (lib);
}
};
}
LibraryClass decl_Library ("db", "Library",
gsi::constructor ("new", &new_lib,
"@brief Creates a new, empty library"
) +

View File

@ -832,6 +832,7 @@ class Basic_TestClass < TestBase
end
# TODO: this class is going to be deprecated
class X < Data
end
class Y < Object

View File

@ -35,11 +35,19 @@ class DBLibrary_TestClass < TestBase
lib.register("RBA-unit-test")
assert_equal(lib.name, "RBA-unit-test")
assert_equal(lib.id != 0, true)
lib_id = lib.id
assert_equal(lib_id != 0, true)
assert_equal(RBA::Library::library_names.member?("RBA-unit-test"), true)
assert_equal(RBA::Library::library_by_name("RBA-unit-test").id, lib.id)
assert_equal(RBA::Library::library_by_name("RBA-unit-test").id, lib_id)
# destroy should not do anything as libraries are not to be removed through the destructor
lib._destroy
assert_equal(RBA::Library::library_by_name("RBA-unit-test").id, lib_id)
assert_equal(lib.destroyed?, true)
lib = RBA::Library::library_by_name("RBA-unit-test")
assert_equal(lib.destroyed?, false)
lib.delete
assert_equal(RBA::Library::library_by_name("RBA-unit-test"), nil)
@ -85,6 +93,10 @@ class DBLibrary_TestClass < TestBase
lib.layout.create_cell("X")
assert_equal(lib.layout.top_cell.name, "X")
# this will actually destroy the library as it is not registered
lib._destroy
assert_equal(lib.destroyed?, true)
end
end

View File

@ -136,7 +136,7 @@ module Test
end
@@attribute_observers = StringifyKeyHash.new
def register_attribute_observer(attribute_name, observer=Proc.new)
def register_attribute_observer(attribute_name, &observer)
@@attribute_observers[attribute_name] ||= []
@@attribute_observers[attribute_name] << observer
end

View File

@ -15,7 +15,7 @@ module Test
PREPARE_HOOKS = []
class << self
def register_runner(id, runner_builder=Proc.new)
def register_runner(id, &runner_builder)
RUNNERS[id] = runner_builder
RUNNERS[id.to_s] = runner_builder
end
@ -33,7 +33,7 @@ module Test
@@default_runner = id
end
def register_collector(id, collector_builder=Proc.new)
def register_collector(id, &collector_builder)
COLLECTORS[id] = collector_builder
COLLECTORS[id.to_s] = collector_builder
end
@ -46,11 +46,11 @@ module Test
ColorScheme[id] = scheme
end
def setup_option(option_builder=Proc.new)
def setup_option(&option_builder)
ADDITIONAL_OPTIONS << option_builder
end
def prepare(hook=Proc.new)
def prepare(&hook)
PREPARE_HOOKS << hook
end