mirror of https://github.com/KLayout/klayout.git
commit
ea3bfabd90
|
|
@ -1486,16 +1486,20 @@ GuiApplication::process_events_impl (QEventLoop::ProcessEventsFlags flags, bool
|
|||
{
|
||||
if (mp_mw) {
|
||||
|
||||
if (silent && tl::DeferredMethodScheduler::instance ()) {
|
||||
tl::DeferredMethodScheduler::instance ()->enable (false);
|
||||
// prevent recursive process_events
|
||||
if (mp_mw->is_busy ()) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if QT_VERSION < 0x050000
|
||||
QApplication::syncX ();
|
||||
#endif
|
||||
if (silent) {
|
||||
tl::DeferredMethodScheduler::enable (false);
|
||||
}
|
||||
|
||||
mp_mw->enter_busy_mode (true);
|
||||
try {
|
||||
#if QT_VERSION < 0x050000
|
||||
QApplication::syncX ();
|
||||
#endif
|
||||
QApplication::processEvents (flags);
|
||||
// Qt seems not to send posted UserEvents in some cases (e.g. in the unit test application with GLib?
|
||||
// Glib not doing this without a main window visible?). Hence we do this explicitly here.
|
||||
|
|
@ -1505,8 +1509,8 @@ GuiApplication::process_events_impl (QEventLoop::ProcessEventsFlags flags, bool
|
|||
}
|
||||
mp_mw->enter_busy_mode (false);
|
||||
|
||||
if (silent && tl::DeferredMethodScheduler::instance ()) {
|
||||
tl::DeferredMethodScheduler::instance ()->enable (true);
|
||||
if (silent) {
|
||||
tl::DeferredMethodScheduler::enable (true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ namespace lay
|
|||
// LogReceiver implementation
|
||||
|
||||
LogReceiver::LogReceiver (LogFile *file, int verbosity, void (LogFile::*method)(const std::string &, bool))
|
||||
: mp_file (file), m_method (method), m_continued (false), m_verbosity (verbosity)
|
||||
: mp_file (file), m_method (method), m_verbosity (verbosity)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
|
@ -64,7 +64,9 @@ LogReceiver::puts (const char *s)
|
|||
}
|
||||
|
||||
if (*s == '\n') {
|
||||
endl ();
|
||||
QMutexLocker locker (&m_lock);
|
||||
(mp_file->*m_method) (m_text, true);
|
||||
m_text.clear ();
|
||||
++s;
|
||||
}
|
||||
|
||||
|
|
@ -78,9 +80,8 @@ LogReceiver::endl ()
|
|||
{
|
||||
if (tl::verbosity () >= m_verbosity) {
|
||||
QMutexLocker locker (&m_lock);
|
||||
(mp_file->*m_method) (m_text, m_continued);
|
||||
(mp_file->*m_method) (m_text, false);
|
||||
m_text.clear ();
|
||||
m_continued = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -99,9 +100,7 @@ LogReceiver::end ()
|
|||
void
|
||||
LogReceiver::begin ()
|
||||
{
|
||||
QMutexLocker locker (&m_lock);
|
||||
m_continued = false;
|
||||
m_text.clear ();
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
|
|
@ -254,6 +253,12 @@ LogFile::add (LogFileEntry::mode_type mode, const std::string &msg, bool continu
|
|||
void
|
||||
LogFile::yield ()
|
||||
{
|
||||
#if 0
|
||||
// This looked like a good idea, but in fact it introduces a hell lot of instability
|
||||
// as it potentially leads to a recursion of events inside innocent functions. Remember
|
||||
// that log output may be generated from every function called in response of an event
|
||||
// and not every such function may process further events
|
||||
|
||||
bool can_yield = false;
|
||||
|
||||
{
|
||||
|
|
@ -268,10 +273,10 @@ LogFile::yield ()
|
|||
// use this opportunity to process events
|
||||
// NOTE: as process events may trigger further log output, it's necessary to do process events outside any other
|
||||
// method (e.g. add) which is subject to locking. Hence we avoid deadlocks.
|
||||
// We accept the risk of recursion inside process_events as we have a timeout before accepting new yield calls.
|
||||
if (can_yield) {
|
||||
lay::ApplicationBase::instance ()->process_events (QEventLoop::AllEvents);
|
||||
lay::ApplicationBase::instance ()->process_events (QEventLoop::ExcludeUserInputEvents | QEventLoop::ExcludeSocketNotifiers, true /*silent*/);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
|||
|
|
@ -96,7 +96,6 @@ private:
|
|||
LogFile *mp_file;
|
||||
void (LogFile::*m_method)(const std::string &, bool);
|
||||
std::string m_text;
|
||||
bool m_continued;
|
||||
int m_verbosity;
|
||||
QMutex m_lock;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -408,6 +408,14 @@ public:
|
|||
m_busy = bm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns true if the application is busy
|
||||
*/
|
||||
bool is_busy () const
|
||||
{
|
||||
return m_busy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Enable synchronous mode or disable it
|
||||
*
|
||||
|
|
|
|||
|
|
@ -396,6 +396,13 @@ BitmapRedrawThreadCanvas::initialize_plane (lay::CanvasPlane *plane, unsigned in
|
|||
void
|
||||
BitmapRedrawThreadCanvas::to_image (const std::vector <lay::ViewOp> &view_ops, const lay::DitherPattern &dp, const lay::LineStyles &ls, QColor background, QColor foreground, QColor active, const lay::Drawings *drawings, QImage &img, unsigned int width, unsigned int height)
|
||||
{
|
||||
if (width > m_width) {
|
||||
width = m_width;
|
||||
}
|
||||
if (height > m_height) {
|
||||
height = m_height;
|
||||
}
|
||||
|
||||
// convert the plane data to image data
|
||||
bitmaps_to_image (view_ops, mp_plane_buffers, dp, ls, &img, width, height, true, &mutex ());
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ verbosity ()
|
|||
// Channel implementation
|
||||
|
||||
Channel::Channel ()
|
||||
: m_no_endl (false), m_active (false)
|
||||
: m_no_endl (false), m_active (false), m_in_yield (false)
|
||||
{
|
||||
// .. nothing else ..
|
||||
}
|
||||
|
|
@ -98,10 +98,19 @@ Channel::release_proxy ()
|
|||
end ();
|
||||
m_active = false;
|
||||
m_no_endl = false;
|
||||
bool in_yield = m_in_yield;
|
||||
m_in_yield = true;
|
||||
m_lock.unlock ();
|
||||
|
||||
// after we have released the lock we give the receivers an opportunity to process events
|
||||
yield ();
|
||||
// after we have released the lock we give the receivers an opportunity to process events. Note that we allow only one thread to yield
|
||||
// at the same time and no recursive yields.
|
||||
if (! in_yield) {
|
||||
yield ();
|
||||
// this should be atomic, but execution reordering may place it before yield(). Hence the lock.
|
||||
m_lock.lock ();
|
||||
m_in_yield = false;
|
||||
m_lock.unlock ();
|
||||
}
|
||||
}
|
||||
|
||||
ChannelEndl endl;
|
||||
|
|
|
|||
|
|
@ -154,6 +154,7 @@ private:
|
|||
|
||||
bool m_no_endl;
|
||||
bool m_active;
|
||||
bool m_in_yield;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue