Merge pull request #803 from KLayout/wip

Wip
This commit is contained in:
Matthias Köfferlein 2021-05-21 00:52:36 +02:00 committed by GitHub
commit 85eee4d6cc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 79 additions and 35 deletions

View File

@ -341,7 +341,7 @@ add_native_impl("QChildEvent", <<'CODE', <<'DECL')
virtual bool can_upcast (const void *) const { return false; }
// Does not bind to a particular type
virtual bool is_of_type (const std::type_info & /*ti*/) const { return false; }
virtual bool binds () const { return false; }
virtual const std::type_info &type () const { return typeid (DummyQObject); }
};
}

View File

@ -545,6 +545,7 @@ module DRC
else
str = (" " * indent) + arg
RBA::Logger::log(str)
self._process_events
end
end
@ -563,6 +564,7 @@ module DRC
@log_file.puts(str)
else
RBA::Logger::info(str)
self._process_events
end
end
@ -577,6 +579,7 @@ module DRC
@log_file.puts("ERROR: " + arg)
else
RBA::Logger::error(arg)
self._process_events
end
end
@ -591,6 +594,7 @@ module DRC
@log_file.puts("WARNING: " + arg)
else
RBA::Logger::warn(arg)
self._process_events
end
end
@ -1988,6 +1992,7 @@ CODE
t = RBA::Timer::new
t.start
self._process_events
GC.start # force a garbage collection before the operation to free unused memory
res = yield
t.stop
@ -2554,6 +2559,12 @@ CODE
@used_output_layers[li] = true
end
end
def _process_events
if RBA::Application.instance
RBA::Application.instance.process_events
end
end
private

View File

@ -585,9 +585,9 @@ public:
set_name (name);
}
virtual bool is_of_type (const std::type_info &ti) const
virtual bool binds () const
{
return (ti == typeid (X));
return false;
}
virtual const std::type_info &type () const
@ -865,15 +865,9 @@ public:
return m_subclass_tester.get () && m_subclass_tester->can_upcast (p);
}
virtual bool is_of_type (const std::type_info &ti) const
virtual bool binds () const
{
if (adapted_type_info ()) {
// A class matches the typeinfo of the adapted type. We'll sort this out later
// on the client side.
return (ti == *adapted_type_info ());
} else {
return (ti == typeid (X));
}
return true;
}
virtual const std::type_info &type () const

View File

@ -816,7 +816,7 @@ bool has_class (const std::string &name)
static void add_class_to_map (const gsi::ClassBase *c)
{
if (c->declaration () != c) {
if (c->declaration () != c || ! c->binds ()) {
// only consider non-extensions
return;
}
@ -833,14 +833,12 @@ static void add_class_to_map (const gsi::ClassBase *c)
sp_tname_to_class = new tname_to_class_map_t ();
}
if (ti && c->is_of_type (*ti)) {
if (!sp_ti_to_class->insert (std::make_pair (ti, c)).second) {
// Duplicate registration of this class
tl::error << "Duplicate registration of class " << c->name () << " (type " << ti->name () << ")";
tl_assert (false);
} else {
sp_tname_to_class->insert (std::make_pair (std::string (ti->name ()), c));
}
if (!sp_ti_to_class->insert (std::make_pair (ti, c)).second) {
// Duplicate registration of this class
tl::error << "Duplicate registration of class " << c->name () << " (type " << ti->name () << ")";
tl_assert (false);
} else {
sp_tname_to_class->insert (std::make_pair (std::string (ti->name ()), c));
}
}

View File

@ -446,12 +446,9 @@ public:
}
/**
* @brief Class implementation: check C++ type of object
*
* This method returns true, if objects of this class are compatible with
* the given C++ type.
* @brief Class implementation: returns true if this class binds to a script class
*/
virtual bool is_of_type (const std::type_info & /*ti*/) const
virtual bool binds () const
{
tl_assert (false);
return false;

View File

@ -60,7 +60,7 @@
virtual bool can_upcast (const void *) const { return false; }
// Does not bind to a particular type
virtual bool is_of_type (const std::type_info & /*ti*/) const { return false; }
virtual bool binds () const { return false; }
virtual const std::type_info &type () const { return typeid (DummyQObject); }
};
}

View File

@ -85,6 +85,12 @@ DeferredMethodScheduler::unqueue (DeferredMethodBase *method)
}
m = mm;
}
for (std::list<DeferredMethodBase *>::iterator m = m_executing.begin (); m != m_executing.end (); ++m) {
if (*m == method) {
m_unqueued.insert (method);
break;
}
}
}
void
@ -102,19 +108,31 @@ DeferredMethodScheduler::do_enable (bool en)
void
DeferredMethodScheduler::do_execute ()
{
std::list<DeferredMethodBase *> methods;
m_lock.lock ();
methods.swap (m_methods);
m_executing.clear ();
m_unqueued.clear ();
m_executing.swap (m_methods);
m_scheduled = false;
m_lock.unlock ();
// do the execution outside the locked range to avoid deadlocks if the method's execution
// schedules another call.
for (std::list<DeferredMethodBase *>::iterator m = methods.begin (); m != methods.end (); ++m) {
(*m)->m_scheduled = false;
(*m)->execute ();
for (std::list<DeferredMethodBase *>::iterator m = m_executing.begin (); m != m_executing.end (); ++m) {
bool still_valid;
m_lock.lock ();
// during execution a method may be unqueued - make sure this is not executed
still_valid = (m_unqueued.find (*m) == m_unqueued.end ());
m_lock.unlock ();
if (still_valid) {
(*m)->m_scheduled = false;
(*m)->execute ();
}
}
m_lock.lock ();
m_unqueued.clear ();
m_executing.clear ();
m_lock.unlock ();
}
}

View File

@ -28,6 +28,7 @@
#include "tlThreads.h"
#include <list>
#include <set>
namespace tl
{
@ -141,7 +142,8 @@ protected:
private:
int m_disabled;
bool m_scheduled;
std::list<DeferredMethodBase *> m_methods;
std::list<DeferredMethodBase *> m_methods, m_executing;
std::set<DeferredMethodBase *> m_unqueued;
tl::Mutex m_lock;
void do_enable (bool en);
@ -263,8 +265,6 @@ public:
*/
void execute ()
{
// cancel execution which might be pending
cancel ();
(mp_t->*m_method) ();
}

View File

@ -186,3 +186,29 @@ TEST(1)
}
static int y_inst = 0;
class Y
{
public:
Y () : da (this, &Y::a), db (this, &Y::b) { ++y_inst; }
~Y () { --y_inst; }
void a () { delete this; }
void b () { tl_assert(false); }
tl::DeferredMethod<Y> da, db;
};
TEST(2)
{
// execution of a deletes db which must not be executed
y_inst = 0;
Y *y = new Y ();
y->da ();
y->db ();
QCoreApplication::instance ()->processEvents ();
EXPECT_EQ (y_inst, 0);
}