From 6e589e2bb31e8ef0391f47217dcb495284e1dc00 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sun, 19 Nov 2023 21:14:32 +0100 Subject: [PATCH] Fixed issue #1533 (KLayout crashing with two consecutive calls of the same LayoutView::show_layout command) --- .../laybasic/gsiDeclLayLayoutViewBase.cc | 15 +++++++++++--- src/laybasic/laybasic/layCellView.cc | 15 ++++++++++++++ src/laybasic/laybasic/layCellView.h | 8 ++++++++ testdata/ruby/layLayoutView.rb | 20 +++++++++++++++++++ 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/laybasic/laybasic/gsiDeclLayLayoutViewBase.cc b/src/laybasic/laybasic/gsiDeclLayLayoutViewBase.cc index 39dbe2404..5e9af3dd0 100644 --- a/src/laybasic/laybasic/gsiDeclLayLayoutViewBase.cc +++ b/src/laybasic/laybasic/gsiDeclLayLayoutViewBase.cc @@ -277,7 +277,10 @@ static unsigned int show_layout1 (lay::LayoutViewBase *view, db::Layout *layout, { // the layout gets held by the LayoutHandle object layout->keep (); - lay::LayoutHandle *handle = new lay::LayoutHandle (layout, std::string ()); + lay::LayoutHandle *handle = lay::LayoutHandle::find_layout (layout); + if (! handle) { + handle = new lay::LayoutHandle (layout, std::string ()); + } return view->add_layout (handle, add_cellview); } @@ -285,7 +288,10 @@ static unsigned int show_layout2 (lay::LayoutViewBase *view, db::Layout *layout, { // the layout gets held by the LayoutHandle object layout->keep (); - lay::LayoutHandle *handle = new lay::LayoutHandle (layout, std::string ()); + lay::LayoutHandle *handle = lay::LayoutHandle::find_layout (layout); + if (! handle) { + handle = new lay::LayoutHandle (layout, std::string ()); + } handle->set_tech_name (tech); return view->add_layout (handle, add_cellview); } @@ -294,7 +300,10 @@ static unsigned int show_layout3 (lay::LayoutViewBase *view, db::Layout *layout, { // the layout gets held by the LayoutHandle object layout->keep (); - lay::LayoutHandle *handle = new lay::LayoutHandle (layout, std::string ()); + lay::LayoutHandle *handle = lay::LayoutHandle::find_layout (layout); + if (! handle) { + handle = new lay::LayoutHandle (layout, std::string ()); + } handle->set_tech_name (tech); return view->add_layout (handle, add_cellview, initialize_layers); } diff --git a/src/laybasic/laybasic/layCellView.cc b/src/laybasic/laybasic/layCellView.cc index d0afaa103..55c97743f 100644 --- a/src/laybasic/laybasic/layCellView.cc +++ b/src/laybasic/laybasic/layCellView.cc @@ -272,6 +272,17 @@ LayoutHandle::find (const std::string &name) } } +LayoutHandle * +LayoutHandle::find_layout (const db::Layout *layout) +{ + for (auto h = ms_dict.begin (); h != ms_dict.end (); ++h) { + if (h->second->mp_layout == layout) { + return h->second; + } + } + return 0; +} + void LayoutHandle::get_names (std::vector &names) { @@ -484,6 +495,10 @@ LayoutHandleRef::operator= (const LayoutHandleRef &r) void LayoutHandleRef::set (LayoutHandle *h) { + if (mp_handle == h) { + return; + } + if (mp_handle) { mp_handle->remove_ref (); mp_handle = 0; diff --git a/src/laybasic/laybasic/layCellView.h b/src/laybasic/laybasic/layCellView.h index 0f5bee9d9..7f350f691 100644 --- a/src/laybasic/laybasic/layCellView.h +++ b/src/laybasic/laybasic/layCellView.h @@ -144,6 +144,14 @@ public: */ static LayoutHandle *find (const std::string &name); + /** + * @brief Finds a handle by layout object + * + * @param layout The Layout object bound to the handle + * @return 0, if there is no layout object with this name. Otherwise a pointer to its handle + */ + static LayoutHandle *find_layout (const db::Layout *layout); + /** * @brief Gets the names of all registered layout objects */ diff --git a/testdata/ruby/layLayoutView.rb b/testdata/ruby/layLayoutView.rb index fdd384cc6..d2c29ea0b 100644 --- a/testdata/ruby/layLayoutView.rb +++ b/testdata/ruby/layLayoutView.rb @@ -550,6 +550,26 @@ class LAYLayoutView_TestClass < TestBase end + # issue-1533 + def test_8 + + if !RBA.constants.member?(:Application) + return + end + + app = RBA::Application.instance + mw = app.main_window + mw.close_all + mw.create_view + + ly = RBA::Layout::new + mw.current_view.show_layout(ly, false) + + # was crashing + mw.current_view.show_layout(ly, false) + + end + end load("test_epilogue.rb")