mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 13:18:28 +00:00
Fix segfault after deleting monitor
The boost signal was sent synchronously, and so made the Qt signal to be posted
in FileMonitor::changed after the boost signal returned, so after the sender was
possibly destroyed.
The solution is to make the boost signal asynchronous using the Qt event loop.
Thanks to Scott Kostyshak for the report and MWE.
(cherry picked from commit 131f4b92ba
)
This commit is contained in:
parent
7950ace3d9
commit
a8ad4002a0
@ -304,6 +304,7 @@ void RenderMonitoredPreview::startMonitoring() const
|
||||
{
|
||||
if (!monitoring()) {
|
||||
monitor_ = FileSystemWatcher::activeMonitor(filename_);
|
||||
// Disconnected at the same time as this is destroyed.
|
||||
monitor_->connect([this](bool /* exists */){ changed_(); });
|
||||
}
|
||||
}
|
||||
|
@ -176,7 +176,14 @@ FileMonitor::FileMonitor(std::shared_ptr<FileMonitorGuard> monitor)
|
||||
|
||||
void FileMonitor::connectToFileMonitorGuard()
|
||||
{
|
||||
// Connections need to be asynchronous because the receiver can own this
|
||||
// object and therefore is allowed to delete it.
|
||||
// Qt signal:
|
||||
QObject::connect(monitor_.get(), SIGNAL(fileChanged(bool)),
|
||||
this, SIGNAL(fileChanged(bool)),
|
||||
Qt::QueuedConnection);
|
||||
// Boost signal:
|
||||
QObject::connect(this, SIGNAL(fileChanged(bool)),
|
||||
this, SLOT(changed(bool)));
|
||||
}
|
||||
|
||||
@ -187,18 +194,10 @@ signals2::connection FileMonitor::connect(slot const & slot)
|
||||
}
|
||||
|
||||
|
||||
void FileMonitor::disconnect()
|
||||
{
|
||||
fileChanged_.disconnect_all_slots();
|
||||
QObject::disconnect(this, SIGNAL(fileChanged(bool)));
|
||||
}
|
||||
|
||||
|
||||
void FileMonitor::changed(bool const exists)
|
||||
{
|
||||
// emit boost signal
|
||||
fileChanged_(exists);
|
||||
Q_EMIT fileChanged(exists);
|
||||
}
|
||||
|
||||
|
||||
@ -244,7 +243,7 @@ void ActiveFileMonitor::checkModified()
|
||||
}
|
||||
}
|
||||
if (changed)
|
||||
FileMonitor::changed(exists);
|
||||
Q_EMIT FileMonitor::fileChanged(exists);
|
||||
QTimer::singleShot(interval_, this, SLOT(clearCooldown()));
|
||||
}
|
||||
|
||||
|
@ -60,10 +60,6 @@ typedef std::unique_ptr<ActiveFileMonitor> ActiveFileMonitorPtr;
|
||||
/// monitor.connect(...);
|
||||
/// (stops watching the first)
|
||||
///
|
||||
/// Reset connections:
|
||||
/// monitor.disconnect();
|
||||
/// or the disconnect method of the connection object for the boost signal.
|
||||
///
|
||||
class FileSystemWatcher
|
||||
{
|
||||
public:
|
||||
@ -137,9 +133,6 @@ public:
|
||||
typedef sig::slot_type slot;
|
||||
/// Connect and you'll be informed when the file has changed.
|
||||
signals2::connection connect(slot const &);
|
||||
/// disconnect all slots connected to the boost signal fileChanged_ or to
|
||||
/// the qt signal fileChanged()
|
||||
void disconnect();
|
||||
/// absolute path being tracked
|
||||
std::string const & filename() { return monitor_->filename(); }
|
||||
/// Make sure the good file is being monitored, after e.g. a move or a
|
||||
|
Loading…
Reference in New Issue
Block a user