mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 13:18:28 +00:00
Properly track the lifetime of signals2::slots (#8261)
Starting at 61b2bd5e
, boost::bind was progressively replaced with
std::bind. They are not interchangeable though. boost::bind implements
the tracking of boost::signals{,2}::trackable objects. Now that
std::bind has completely replaced boost::bind, tracking never occurred.
This commit replaces boost::signals2::trackable with the new preferred
boost::signals2 methods: scoped_connections or slot::track_foreign. The
support::Trackable class introduced is less safe but easier for transitioning
old code.
Fixes the crash at #8261.
This commit is contained in:
parent
3f61375bc3
commit
db58111360
@ -693,20 +693,6 @@ bool Converters::scanLog(Buffer const & buffer, string const & /*command*/,
|
||||
}
|
||||
|
||||
|
||||
namespace {
|
||||
|
||||
class ShowMessage
|
||||
: public boost::signals2::trackable {
|
||||
public:
|
||||
ShowMessage(Buffer const & b) : buffer_(b) {}
|
||||
void operator()(docstring const & msg) const { buffer_.message(msg); }
|
||||
private:
|
||||
Buffer const & buffer_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
bool Converters::runLaTeX(Buffer const & buffer, string const & command,
|
||||
OutputParams const & runparams, ErrorList & errorList)
|
||||
{
|
||||
@ -719,8 +705,12 @@ bool Converters::runLaTeX(Buffer const & buffer, string const & command,
|
||||
buffer.filePath(), buffer.layoutPos(),
|
||||
buffer.lastPreviewError());
|
||||
TeXErrors terr;
|
||||
ShowMessage show(buffer);
|
||||
latex.message.connect(show);
|
||||
// The connection closes itself at the end of the scope when latex is
|
||||
// destroyed. One cannot close (and destroy) buffer while the converter is
|
||||
// running.
|
||||
latex.message.connect([&buffer](docstring const & msg){
|
||||
buffer.message(msg);
|
||||
});
|
||||
int const result = latex.run(terr);
|
||||
|
||||
if (result & LaTeX::ERRORS)
|
||||
|
@ -18,8 +18,7 @@
|
||||
|
||||
#include "support/docstring.h"
|
||||
#include "support/FileName.h"
|
||||
|
||||
#include <boost/signals2.hpp>
|
||||
#include "support/signals.h"
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
@ -148,7 +147,7 @@ public:
|
||||
};
|
||||
|
||||
/// This signal emits an informative message
|
||||
boost::signals2::signal<void(docstring)> message;
|
||||
signals2::signal<void(docstring)> message;
|
||||
|
||||
|
||||
/**
|
||||
|
@ -55,8 +55,7 @@
|
||||
#include "support/lassert.h"
|
||||
#include "support/lstrings.h"
|
||||
#include "support/os.h"
|
||||
|
||||
#include "support/bind.h"
|
||||
#include "support/signals.h"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
@ -859,8 +858,12 @@ int LyXComm::startPipe(string const & file, bool write)
|
||||
}
|
||||
|
||||
if (!write) {
|
||||
theApp()->registerSocketCallback(fd,
|
||||
bind(&LyXComm::read_ready, this));
|
||||
// Make sure not to call read_ready after destruction.
|
||||
weak_ptr<void> tracker = tracker_.p();
|
||||
theApp()->registerSocketCallback(fd, [=](){
|
||||
if (!tracker.expired())
|
||||
read_ready();
|
||||
});
|
||||
}
|
||||
|
||||
return fd;
|
||||
|
@ -14,7 +14,7 @@
|
||||
#ifndef SERVER_H
|
||||
#define SERVER_H
|
||||
|
||||
#include <boost/signals2/trackable.hpp>
|
||||
#include "support/signals.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
@ -30,7 +30,7 @@ namespace lyx {
|
||||
class Server;
|
||||
|
||||
|
||||
/** This class managed the pipes used for communicating with clients.
|
||||
/** This class manages the pipes used for communicating with clients.
|
||||
Usage: Initialize with pipe-filename-base, client class to receive
|
||||
messages, and callback-function that will be called with the messages.
|
||||
When you want to send, use "send()".
|
||||
@ -38,7 +38,7 @@ class Server;
|
||||
a clean string interface.
|
||||
*/
|
||||
#ifndef _WIN32
|
||||
class LyXComm : public boost::signals2::trackable {
|
||||
class LyXComm {
|
||||
#else
|
||||
class LyXComm : public QObject {
|
||||
Q_OBJECT
|
||||
@ -189,6 +189,9 @@ private:
|
||||
|
||||
/// Did we defer loading of files to another instance?
|
||||
bool deferred_loading_;
|
||||
|
||||
/// Track object's liveness
|
||||
support::Trackable tracker_;
|
||||
};
|
||||
|
||||
|
||||
|
@ -529,7 +529,8 @@ GuiView::GuiView(int id)
|
||||
|
||||
// Start autosave timer
|
||||
if (lyxrc.autosave) {
|
||||
d.autosave_timeout_.timeout.connect(bind(&GuiView::autoSave, this));
|
||||
// The connection is closed when this is destroyed.
|
||||
d.autosave_timeout_.timeout.connect([this](){ autoSave();});
|
||||
d.autosave_timeout_.setTimeout(lyxrc.autosave * 1000);
|
||||
d.autosave_timeout_.start();
|
||||
}
|
||||
|
@ -320,9 +320,10 @@ void GuiWorkArea::init()
|
||||
|
||||
d->setCursorShape(Qt::IBeamCursor);
|
||||
|
||||
d->synthetic_mouse_event_.timeout.timeout.connect(
|
||||
bind(&GuiWorkArea::generateSyntheticMouseEvent,
|
||||
this));
|
||||
// This connection is closed at the same time as this is destroyed.
|
||||
d->synthetic_mouse_event_.timeout.timeout.connect([this](){
|
||||
generateSyntheticMouseEvent();
|
||||
});
|
||||
|
||||
// Initialize the vertical Scroll Bar
|
||||
QObject::connect(verticalScrollBar(), SIGNAL(valueChanged(int)),
|
||||
|
@ -29,7 +29,6 @@
|
||||
#include "support/lassert.h"
|
||||
#include "support/unique_ptr.h"
|
||||
|
||||
#include "support/bind.h"
|
||||
#include "support/TempFile.h"
|
||||
|
||||
using namespace std;
|
||||
@ -39,7 +38,7 @@ namespace lyx {
|
||||
|
||||
namespace graphics {
|
||||
|
||||
class CacheItem::Impl : public boost::signals2::trackable {
|
||||
class CacheItem::Impl {
|
||||
public:
|
||||
|
||||
///
|
||||
@ -50,7 +49,7 @@ public:
|
||||
/**
|
||||
* If no file conversion is needed, then tryDisplayFormat() calls
|
||||
* loadImage() directly.
|
||||
* \return true if a conversion is necessary and no error occurred.
|
||||
* \return true if a conversion is necessary and no error occurred.
|
||||
*/
|
||||
bool tryDisplayFormat(FileName & filename, string & from);
|
||||
|
||||
@ -120,10 +119,7 @@ public:
|
||||
ImageStatus status_;
|
||||
|
||||
/// This signal is emitted when the image loading status changes.
|
||||
boost::signals2::signal<void()> statusChanged;
|
||||
|
||||
/// The connection of the signal ConvProcess::finishedConversion,
|
||||
boost::signals2::connection cc_;
|
||||
signals2::signal<void()> statusChanged;
|
||||
|
||||
///
|
||||
unique_ptr<Converter> converter_;
|
||||
@ -199,7 +195,7 @@ ImageStatus CacheItem::status() const
|
||||
}
|
||||
|
||||
|
||||
boost::signals2::connection CacheItem::connect(slot_type const & slot) const
|
||||
signals2::connection CacheItem::connect(slot_type const & slot) const
|
||||
{
|
||||
return pimpl_->statusChanged.connect(slot);
|
||||
}
|
||||
@ -223,6 +219,7 @@ void CacheItem::Impl::startMonitor()
|
||||
if (monitor_)
|
||||
return;
|
||||
monitor_ = FileSystemWatcher::activeMonitor(filename_);
|
||||
// Disconnected at the same time as this is destroyed.
|
||||
monitor_->connect([=](){ startLoading(); });
|
||||
}
|
||||
|
||||
@ -254,9 +251,6 @@ void CacheItem::Impl::reset()
|
||||
|
||||
status_ = WaitingToLoad;
|
||||
|
||||
if (cc_.connected())
|
||||
cc_.disconnect();
|
||||
|
||||
if (converter_)
|
||||
converter_.reset();
|
||||
}
|
||||
@ -280,7 +274,6 @@ void CacheItem::Impl::imageConverted(bool success)
|
||||
file_to_load_ = converter_ ? FileName(converter_->convertedFile())
|
||||
: FileName();
|
||||
converter_.reset();
|
||||
cc_.disconnect();
|
||||
|
||||
success = !file_to_load_.empty() && file_to_load_.isReadableFile();
|
||||
|
||||
@ -449,9 +442,13 @@ void CacheItem::Impl::convertToDisplayFormat()
|
||||
// Connect a signal to this->imageConverted and pass this signal to
|
||||
// the graphics converter so that we can load the modified file
|
||||
// on completion of the conversion process.
|
||||
converter_ = make_unique<Converter>(doc_file_, filename, to_file_base.absFileName(),
|
||||
converter_ = make_unique<Converter>(doc_file_, filename,
|
||||
to_file_base.absFileName(),
|
||||
from, to_);
|
||||
converter_->connect(bind(&Impl::imageConverted, this, _1));
|
||||
// Connection is closed at the same time as *this is destroyed.
|
||||
converter_->connect([this](bool success){
|
||||
imageConverted(success);
|
||||
});
|
||||
converter_->startConversion();
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
#include "GraphicsTypes.h"
|
||||
|
||||
#include <boost/signals2.hpp>
|
||||
#include "support/signals.h"
|
||||
|
||||
|
||||
namespace lyx {
|
||||
@ -82,9 +82,9 @@ public:
|
||||
/** Connect and you'll be informed when the loading status of the image
|
||||
* changes.
|
||||
*/
|
||||
typedef boost::signals2::signal<void()>::slot_type slot_type;
|
||||
typedef signals2::signal<void()>::slot_type slot_type;
|
||||
///
|
||||
boost::signals2::connection connect(slot_type const &) const;
|
||||
signals2::connection connect(slot_type const &) const;
|
||||
|
||||
private:
|
||||
/// noncopyable
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "support/lstrings.h"
|
||||
#include "support/os.h"
|
||||
|
||||
#include "support/bind.h"
|
||||
#include "support/TempFile.h"
|
||||
|
||||
#include <sstream>
|
||||
@ -40,10 +39,12 @@ namespace lyx {
|
||||
|
||||
namespace graphics {
|
||||
|
||||
class Converter::Impl : public boost::signals2::trackable {
|
||||
class Converter::Impl {
|
||||
public:
|
||||
///
|
||||
Impl(FileName const &, FileName const &, string const &, string const &, string const &);
|
||||
Impl(FileName const & doc_fname,
|
||||
FileName const & from_file, string const & to_file_base,
|
||||
string const & from_format, string const & to_format);
|
||||
|
||||
///
|
||||
void startConversion();
|
||||
@ -58,9 +59,9 @@ public:
|
||||
/** At the end of the conversion process inform the outside world
|
||||
* by emitting a signal.
|
||||
*/
|
||||
typedef boost::signals2::signal<void(bool)> SignalType;
|
||||
typedef signals2::signal<void(bool)> sig;
|
||||
///
|
||||
SignalType finishedConversion;
|
||||
sig finishedConversion;
|
||||
|
||||
///
|
||||
FileName const doc_fname_;
|
||||
@ -74,6 +75,8 @@ public:
|
||||
bool valid_process_;
|
||||
///
|
||||
bool finished_;
|
||||
///
|
||||
Trackable tracker_;
|
||||
};
|
||||
|
||||
|
||||
@ -85,8 +88,8 @@ bool Converter::isReachable(string const & from_format_name,
|
||||
|
||||
|
||||
Converter::Converter(FileName const & doc_fname,
|
||||
FileName const & from_file, string const & to_file_base,
|
||||
string const & from_format, string const & to_format)
|
||||
FileName const & from_file, string const & to_file_base,
|
||||
string const & from_format, string const & to_format)
|
||||
: pimpl_(new Impl(doc_fname, from_file, to_file_base, from_format, to_format))
|
||||
{}
|
||||
|
||||
@ -103,7 +106,7 @@ void Converter::startConversion() const
|
||||
}
|
||||
|
||||
|
||||
boost::signals2::connection Converter::connect(slot_type const & slot) const
|
||||
signals2::connection Converter::connect(slot_type const & slot) const
|
||||
{
|
||||
return pimpl_->finishedConversion.connect(slot);
|
||||
}
|
||||
@ -188,9 +191,10 @@ void Converter::Impl::startConversion()
|
||||
return;
|
||||
}
|
||||
|
||||
ForkedCall::SignalTypePtr ptr =
|
||||
ForkedCallQueue::add(script_command_);
|
||||
ptr->connect(bind(&Impl::converted, this, _1, _2));
|
||||
ForkedCall::sigPtr ptr = ForkedCallQueue::add(script_command_);
|
||||
ptr->connect(ForkedCall::slot([this](pid_t pid, int retval){
|
||||
converted(pid, retval);
|
||||
}).track_foreign(tracker_.p()));
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,7 +17,8 @@
|
||||
#ifndef GRAPHICSCONVERTER_H
|
||||
#define GRAPHICSCONVERTER_H
|
||||
|
||||
#include <boost/signals2.hpp>
|
||||
#include "support/signals.h"
|
||||
|
||||
|
||||
namespace lyx {
|
||||
|
||||
@ -47,11 +48,12 @@ public:
|
||||
/** Connect and you'll be informed when the conversion process has
|
||||
* finished.
|
||||
* If the conversion is successful, then the listener is passed \c true.
|
||||
* The connection is closed when this is destroyed.
|
||||
*/
|
||||
typedef boost::signals2::signal<void(bool)> sig_type;
|
||||
typedef signals2::signal<void(bool)> sig_type;
|
||||
typedef sig_type::slot_type slot_type;
|
||||
///
|
||||
boost::signals2::connection connect(slot_type const &) const;
|
||||
signals2::connection connect(slot_type const &) const;
|
||||
|
||||
/** If the conversion is successful, this returns the name of the
|
||||
* resulting file.
|
||||
|
@ -107,16 +107,17 @@ void LoaderQueue::loadNext()
|
||||
|
||||
|
||||
LoaderQueue::LoaderQueue() : timer(s_millisecs_, Timeout::ONETIME),
|
||||
running_(false)
|
||||
running_(false)
|
||||
{
|
||||
timer.timeout.connect(bind(&LoaderQueue::loadNext, this));
|
||||
// Disconnected when this is destroyed
|
||||
timer.timeout.connect([this](){ loadNext(); });
|
||||
}
|
||||
|
||||
|
||||
void LoaderQueue::startLoader()
|
||||
{
|
||||
LYXERR(Debug::GRAPHICS, "LoaderQueue: waking up");
|
||||
running_ = true ;
|
||||
running_ = true;
|
||||
timer.setTimeout(s_millisecs_);
|
||||
timer.start();
|
||||
}
|
||||
@ -163,7 +164,7 @@ void LoaderQueue::touch(Cache::ItemPtr const & item)
|
||||
|
||||
typedef std::shared_ptr<Image> ImagePtr;
|
||||
|
||||
class Loader::Impl : public boost::signals2::trackable {
|
||||
class Loader::Impl {
|
||||
friend class Loader;
|
||||
public:
|
||||
///
|
||||
@ -192,9 +193,9 @@ public:
|
||||
/// We modify a local copy of the image once it is loaded.
|
||||
ImagePtr image_;
|
||||
/// This signal is emitted when the image loading status changes.
|
||||
boost::signals2::signal<void()> signal_;
|
||||
/// The connection of the signal StatusChanged
|
||||
boost::signals2::connection sc_;
|
||||
signals2::signal<void()> signal_;
|
||||
/// The connection of the signal statusChanged
|
||||
signals2::scoped_connection connection_;
|
||||
|
||||
double displayPixelRatio() const
|
||||
{
|
||||
@ -363,7 +364,7 @@ void Loader::setDisplayPixelRatio(double scale)
|
||||
}
|
||||
|
||||
|
||||
boost::signals2::connection Loader::connect(slot_type const & slot) const
|
||||
signals2::connection Loader::connect(slot const & slot) const
|
||||
{
|
||||
return pimpl_->signal_.connect(slot);
|
||||
}
|
||||
@ -405,7 +406,7 @@ void Loader::Impl::resetFile(FileName const & file)
|
||||
// signal needs to be disconnected.
|
||||
try {
|
||||
// This can in theory throw a BufferException
|
||||
sc_.disconnect();
|
||||
connection_.disconnect();
|
||||
} catch (...) {
|
||||
LYXERR(Debug::GRAPHICS, "Unable to disconnect signal.");
|
||||
}
|
||||
@ -434,7 +435,8 @@ void Loader::Impl::resetFile(FileName const & file)
|
||||
if (continue_monitoring && !cached_item_->monitoring())
|
||||
cached_item_->startMonitoring();
|
||||
|
||||
sc_ = cached_item_->connect(bind(&Impl::statusChanged, this));
|
||||
// This is a scoped connection
|
||||
connection_ = cached_item_->connect([this](){ statusChanged(); });
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
#include "GraphicsTypes.h"
|
||||
|
||||
#include <boost/signals2.hpp>
|
||||
#include "support/signals.h"
|
||||
|
||||
namespace lyx {
|
||||
|
||||
@ -70,7 +70,7 @@ public:
|
||||
*/
|
||||
void startLoading() const;
|
||||
|
||||
/** Tries to reload the image.
|
||||
/** Tries to reload the image.
|
||||
*/
|
||||
void reload() const;
|
||||
|
||||
@ -90,10 +90,10 @@ public:
|
||||
/** Connect and you'll be informed when the loading status of the image
|
||||
* changes.
|
||||
*/
|
||||
typedef boost::signals2::signal<void()> sig_type;
|
||||
typedef sig_type::slot_type slot_type;
|
||||
typedef signals2::signal<void()> sig;
|
||||
typedef sig::slot_type slot;
|
||||
///
|
||||
boost::signals2::connection connect(slot_type const &) const;
|
||||
signals2::connection connect(slot const &) const;
|
||||
|
||||
/** The loaded image with Pixmap set.
|
||||
* If the Pixmap is not yet set (see status() for why...), returns 0.
|
||||
|
@ -20,7 +20,6 @@
|
||||
|
||||
#include "support/FileName.h"
|
||||
|
||||
#include "support/bind.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace lyx::support;
|
||||
@ -28,7 +27,7 @@ using namespace lyx::support;
|
||||
namespace lyx {
|
||||
namespace graphics {
|
||||
|
||||
class PreviewImage::Impl : public boost::signals2::trackable {
|
||||
class PreviewImage::Impl {
|
||||
public:
|
||||
///
|
||||
Impl(PreviewImage & p, PreviewLoader & l,
|
||||
@ -105,15 +104,14 @@ PreviewLoader & PreviewImage::previewLoader() const
|
||||
}
|
||||
|
||||
|
||||
PreviewImage::Impl::Impl(PreviewImage & p, PreviewLoader & l,
|
||||
string const & s,
|
||||
FileName const & bf,
|
||||
double af)
|
||||
PreviewImage::Impl::Impl(PreviewImage & p, PreviewLoader & l, string const & s,
|
||||
FileName const & bf, double af)
|
||||
: parent_(p), ploader_(l), iloader_(l.buffer().fileName(), bf),
|
||||
snippet_(s), ascent_frac_(af)
|
||||
{
|
||||
iloader_.setDisplayPixelRatio(l.displayPixelRatio());
|
||||
iloader_.connect(bind(&Impl::statusChanged, this));
|
||||
// This connection is destroyed at the same time as this.
|
||||
iloader_.connect([this](){ statusChanged(); });
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include "support/ForkedCalls.h"
|
||||
#include "support/lstrings.h"
|
||||
|
||||
#include "support/bind.h"
|
||||
#include "support/TempFile.h"
|
||||
|
||||
#include <atomic>
|
||||
@ -168,7 +167,7 @@ typedef InProgressProcesses::value_type InProgressProcess;
|
||||
namespace lyx {
|
||||
namespace graphics {
|
||||
|
||||
class PreviewLoader::Impl : public boost::signals2::trackable {
|
||||
class PreviewLoader::Impl {
|
||||
public:
|
||||
///
|
||||
Impl(PreviewLoader & p, Buffer const & b);
|
||||
@ -189,7 +188,7 @@ public:
|
||||
void refreshPreviews();
|
||||
|
||||
/// Emit this signal when an image is ready for display.
|
||||
boost::signals2::signal<void(PreviewImage const &)> imageReady;
|
||||
signals2::signal<void(PreviewImage const &)> imageReady;
|
||||
|
||||
Buffer const & buffer() const { return buffer_; }
|
||||
|
||||
@ -240,6 +239,8 @@ private:
|
||||
|
||||
/// We don't own this
|
||||
static lyx::Converter const * pconverter_;
|
||||
|
||||
signals2::scoped_connection connection_;
|
||||
};
|
||||
|
||||
|
||||
@ -297,7 +298,7 @@ void PreviewLoader::refreshPreviews()
|
||||
}
|
||||
|
||||
|
||||
boost::signals2::connection PreviewLoader::connect(slot_type const & slot) const
|
||||
signals2::connection PreviewLoader::connect(slot const & slot) const
|
||||
{
|
||||
return pimpl_->imageReady.connect(slot);
|
||||
}
|
||||
@ -708,12 +709,12 @@ void PreviewLoader::Impl::startLoading(bool wait)
|
||||
<< " " << quoteName(latexfile.toFilesystemEncoding())
|
||||
<< " --dpi " << font_scaling_factor_;
|
||||
|
||||
// FIXME XHTML
|
||||
// FIXME XHTML
|
||||
// The colors should be customizable.
|
||||
if (!buffer_.isExporting()) {
|
||||
ColorCode const fg = PreviewLoader::foregroundColor();
|
||||
ColorCode const bg = PreviewLoader::backgroundColor();
|
||||
cs << " --fg " << theApp()->hexName(fg)
|
||||
cs << " --fg " << theApp()->hexName(fg)
|
||||
<< " --bg " << theApp()->hexName(bg);
|
||||
}
|
||||
|
||||
@ -737,9 +738,11 @@ void PreviewLoader::Impl::startLoading(bool wait)
|
||||
}
|
||||
|
||||
// Initiate the conversion from LaTeX to bitmap images files.
|
||||
ForkedCall::SignalTypePtr
|
||||
convert_ptr(new ForkedCall::SignalType);
|
||||
convert_ptr->connect(bind(&Impl::finishedGenerating, this, _1, _2));
|
||||
ForkedCall::sigPtr convert_ptr = make_shared<ForkedCall::sig>();
|
||||
// This is a scoped connection
|
||||
connection_ = convert_ptr->connect([this](pid_t pid, int retval){
|
||||
finishedGenerating(pid, retval);
|
||||
});
|
||||
|
||||
ForkedCall call(buffer_.filePath());
|
||||
int ret = call.startScript(command, convert_ptr);
|
||||
|
@ -18,7 +18,8 @@
|
||||
#ifndef PREVIEWLOADER_H
|
||||
#define PREVIEWLOADER_H
|
||||
|
||||
#include <boost/signals2.hpp>
|
||||
#include "support/signals.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "ColorCode.h"
|
||||
@ -76,10 +77,10 @@ public:
|
||||
* has been created and is ready for loading through
|
||||
* lyx::graphics::PreviewImage::image().
|
||||
*/
|
||||
typedef boost::signals2::signal<void(PreviewImage const &)> sig_type;
|
||||
typedef sig_type::slot_type slot_type;
|
||||
typedef signals2::signal<void(PreviewImage const &)> sig;
|
||||
typedef sig::slot_type slot;
|
||||
///
|
||||
boost::signals2::connection connect(slot_type const &) const;
|
||||
signals2::connection connect(slot const &) const;
|
||||
|
||||
/** When PreviewImage has finished loading the image file into memory,
|
||||
* it tells the PreviewLoader to tell the outside world
|
||||
|
@ -39,7 +39,6 @@
|
||||
|
||||
#include "graphics/PreviewLoader.h"
|
||||
|
||||
#include "support/bind.h"
|
||||
#include "support/convert.h"
|
||||
#include "support/debug.h"
|
||||
#include "support/ExceptionMessage.h"
|
||||
@ -428,7 +427,6 @@ InsetExternal::InsetExternal(Buffer * buf)
|
||||
// Mouse hover is not copied and remains empty
|
||||
InsetExternal::InsetExternal(InsetExternal const & other)
|
||||
: Inset(other),
|
||||
boost::signals2::trackable(),
|
||||
params_(other.params_),
|
||||
renderer_(other.renderer_->clone(this))
|
||||
{}
|
||||
@ -635,6 +633,7 @@ void InsetExternal::setParams(InsetExternalParams const & p)
|
||||
case PREVIEW_INSTANT: {
|
||||
renderer_ = make_unique<RenderMonitoredPreview>(this);
|
||||
RenderMonitoredPreview * preview_ptr = renderer_->asMonitoredPreview();
|
||||
// This connection is closed at the same time as this is destroyed.
|
||||
preview_ptr->connect([=]() { fileChanged(); });
|
||||
add_preview_and_start_loading(*preview_ptr, *this, buffer());
|
||||
break;
|
||||
|
@ -19,8 +19,6 @@
|
||||
#include "support/FileName.h"
|
||||
#include "support/unique_ptr.h"
|
||||
|
||||
#include <boost/signals2/trackable.hpp>
|
||||
|
||||
|
||||
namespace lyx {
|
||||
|
||||
@ -90,7 +88,7 @@ private:
|
||||
class RenderBase;
|
||||
|
||||
///
|
||||
class InsetExternal : public Inset, public boost::signals2::trackable
|
||||
class InsetExternal : public Inset
|
||||
{
|
||||
// Disable assignment operator, since it is not used, and it is too
|
||||
// complicated to implement it consistently with the copy constructor
|
||||
|
@ -31,8 +31,6 @@
|
||||
#include "support/lassert.h"
|
||||
#include "support/lstrings.h"
|
||||
|
||||
#include "support/bind.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace lyx::support;
|
||||
|
||||
@ -77,19 +75,11 @@ RenderPreview::RenderPreview(Inset const * inset)
|
||||
RenderPreview::RenderPreview(RenderPreview const & other,
|
||||
Inset const * inset)
|
||||
: RenderBase(other),
|
||||
boost::signals2::trackable(),
|
||||
snippet_(other.snippet_),
|
||||
parent_(inset)
|
||||
{}
|
||||
|
||||
|
||||
RenderPreview::~RenderPreview()
|
||||
{
|
||||
if (ploader_connection_.connected())
|
||||
ploader_connection_.disconnect();
|
||||
}
|
||||
|
||||
|
||||
RenderBase * RenderPreview::clone(Inset const * inset) const
|
||||
{
|
||||
return new RenderPreview(*this, inset);
|
||||
@ -241,10 +231,12 @@ void RenderPreview::addPreview(docstring const & latex_snippet,
|
||||
// If this is the first time of calling, connect to the
|
||||
// PreviewLoader signal that'll inform us when the preview image
|
||||
// is ready for loading.
|
||||
if (!ploader_connection_.connected()) {
|
||||
ploader_connection_ = ploader.connect(
|
||||
bind(&RenderPreview::imageReady, this, _1));
|
||||
}
|
||||
if (!ploader_connection_.connected())
|
||||
// This is a scoped connection.
|
||||
ploader_connection_ =
|
||||
ploader.connect([this](graphics::PreviewImage const & pi){
|
||||
imageReady(pi);
|
||||
});
|
||||
|
||||
ploader.add(snippet_);
|
||||
}
|
||||
@ -296,8 +288,7 @@ void RenderMonitoredPreview::draw(PainterInfo & pi, int x, int y) const
|
||||
}
|
||||
|
||||
|
||||
boost::signals2::connection
|
||||
RenderMonitoredPreview::connect(ChangedSig::slot_type const & slot)
|
||||
signals2::connection RenderMonitoredPreview::connect(slot const & slot)
|
||||
{
|
||||
return changed_.connect(slot);
|
||||
}
|
||||
|
@ -21,10 +21,8 @@
|
||||
#include "support/docstring.h"
|
||||
#include "support/FileMonitor.h"
|
||||
#include "support/FileName.h"
|
||||
#include "support/signals.h"
|
||||
|
||||
#include <boost/signals2.hpp>
|
||||
#include <boost/signals2/trackable.hpp>
|
||||
#include <boost/signals2/connection.hpp>
|
||||
|
||||
namespace lyx {
|
||||
|
||||
@ -40,7 +38,7 @@ class PreviewLoader;
|
||||
} // namespace graphics
|
||||
|
||||
|
||||
class RenderPreview : public RenderBase, public boost::signals2::trackable {
|
||||
class RenderPreview : public RenderBase {
|
||||
public:
|
||||
/// Return true if preview is enabled in text (from LyXRC::preview)
|
||||
static bool previewText();
|
||||
@ -49,7 +47,6 @@ public:
|
||||
|
||||
RenderPreview(Inset const *);
|
||||
RenderPreview(RenderPreview const &, Inset const *);
|
||||
~RenderPreview();
|
||||
RenderBase * clone(Inset const *) const;
|
||||
|
||||
/// Compute the size of the object, returned in dim
|
||||
@ -104,7 +101,7 @@ private:
|
||||
/** Store the connection to the preview loader so that we connect
|
||||
* only once.
|
||||
*/
|
||||
boost::signals2::connection ploader_connection_;
|
||||
signals2::scoped_connection ploader_connection_;
|
||||
|
||||
/// Inform the core that the inset has changed.
|
||||
Inset const * parent_;
|
||||
@ -124,15 +121,17 @@ public:
|
||||
void stopMonitoring() const;
|
||||
|
||||
/// Connect and you'll be informed when the file changes.
|
||||
typedef boost::signals2::signal<void()> ChangedSig;
|
||||
boost::signals2::connection connect(ChangedSig::slot_type const &);
|
||||
/// Do not forget to track objects used by the slot.
|
||||
typedef signals2::signal<void()> sig;
|
||||
typedef sig::slot_type slot;
|
||||
signals2::connection connect(slot const & slot);
|
||||
|
||||
/// equivalent to dynamic_cast
|
||||
virtual RenderMonitoredPreview * asMonitoredPreview() { return this; }
|
||||
|
||||
private:
|
||||
/// This signal is emitted if the file is modified
|
||||
ChangedSig changed_;
|
||||
sig changed_;
|
||||
///
|
||||
mutable support::ActiveFileMonitorPtr monitor_;
|
||||
///
|
||||
|
@ -176,8 +176,7 @@ void FileMonitor::reconnectToFileMonitorGuard()
|
||||
}
|
||||
|
||||
|
||||
boost::signals2::connection
|
||||
FileMonitor::connect(sig::slot_type const & slot)
|
||||
signals2::connection FileMonitor::connect(slot const & slot)
|
||||
{
|
||||
return fileChanged_.connect(slot);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define FILEMONITOR_H
|
||||
|
||||
#include "support/FileName.h"
|
||||
#include "support/signals.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
@ -24,8 +25,6 @@
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
|
||||
namespace lyx {
|
||||
namespace support {
|
||||
@ -158,9 +157,10 @@ class FileMonitor : public QObject
|
||||
public:
|
||||
FileMonitor(std::shared_ptr<FileMonitorGuard> monitor);
|
||||
|
||||
typedef boost::signals2::signal<void()> sig;
|
||||
typedef signals2::signal<void()> sig;
|
||||
typedef sig::slot_type slot;
|
||||
/// Connect and you'll be informed when the file has changed.
|
||||
boost::signals2::connection connect(sig::slot_type const &);
|
||||
signals2::connection connect(slot const &);
|
||||
/// disconnect all slots connected to the boost signal fileChanged_ or to
|
||||
/// the qt signal fileChanged()
|
||||
void disconnect();
|
||||
|
@ -58,7 +58,7 @@ namespace {
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
class Murder : public boost::signals2::trackable {
|
||||
class Murder {
|
||||
public:
|
||||
//
|
||||
static void killItDead(int secs, pid_t pid)
|
||||
@ -83,7 +83,8 @@ private:
|
||||
Murder(int secs, pid_t pid)
|
||||
: timeout_(1000*secs, Timeout::ONETIME), pid_(pid)
|
||||
{
|
||||
timeout_.timeout.connect(lyx::bind(&Murder::kill, this));
|
||||
// Connection is closed with this.
|
||||
timeout_.timeout.connect([this](){ kill(); });
|
||||
timeout_.start();
|
||||
}
|
||||
|
||||
@ -277,7 +278,7 @@ ForkedCall::ForkedCall(string const & path, string const & lpath)
|
||||
int ForkedCall::startScript(Starttype wait, string const & what)
|
||||
{
|
||||
if (wait != Wait) {
|
||||
retval_ = startScript(what, SignalTypePtr());
|
||||
retval_ = startScript(what, sigPtr());
|
||||
return retval_;
|
||||
}
|
||||
|
||||
@ -287,7 +288,7 @@ int ForkedCall::startScript(Starttype wait, string const & what)
|
||||
}
|
||||
|
||||
|
||||
int ForkedCall::startScript(string const & what, SignalTypePtr signal)
|
||||
int ForkedCall::startScript(string const & what, sigPtr signal)
|
||||
{
|
||||
command_ = commandPrep(trim(what));
|
||||
signal_ = signal;
|
||||
@ -435,13 +436,13 @@ int ForkedCall::generateChild()
|
||||
namespace ForkedCallQueue {
|
||||
|
||||
/// A process in the queue
|
||||
typedef pair<string, ForkedCall::SignalTypePtr> Process;
|
||||
typedef pair<string, ForkedCall::sigPtr> Process;
|
||||
/** Add a process to the queue. Processes are forked sequentially
|
||||
* only one is running at a time.
|
||||
* Connect to the returned signal and you'll be informed when
|
||||
* the process has ended.
|
||||
*/
|
||||
ForkedCall::SignalTypePtr add(string const & process);
|
||||
ForkedCall::sigPtr add(string const & process);
|
||||
|
||||
/// in-progress queue
|
||||
static queue<Process> callQueue_;
|
||||
@ -456,10 +457,10 @@ void stopCaller();
|
||||
///
|
||||
void callback(pid_t, int);
|
||||
|
||||
ForkedCall::SignalTypePtr add(string const & process)
|
||||
ForkedCall::sigPtr add(string const & process)
|
||||
{
|
||||
ForkedCall::SignalTypePtr ptr;
|
||||
ptr.reset(new ForkedCall::SignalType);
|
||||
ForkedCall::sigPtr ptr;
|
||||
ptr.reset(new ForkedCall::sig);
|
||||
callQueue_.push(Process(process, ptr));
|
||||
if (!running_)
|
||||
startCaller();
|
||||
|
@ -14,8 +14,8 @@
|
||||
#ifndef FORKEDCALLS_H
|
||||
#define FORKEDCALLS_H
|
||||
|
||||
#include "support/signals.h"
|
||||
#include "support/strfwd.h"
|
||||
#include <boost/signals2.hpp>
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
@ -44,7 +44,7 @@ public:
|
||||
///
|
||||
virtual std::shared_ptr<ForkedProcess> clone() const = 0;
|
||||
|
||||
/** A SignalType signal can be emitted once the forked process
|
||||
/** A Signal signal can be emitted once the forked process
|
||||
* has finished. It passes:
|
||||
* the PID of the child and;
|
||||
* the return value from the child.
|
||||
@ -53,7 +53,8 @@ public:
|
||||
* we can return easily to C++ methods, rather than just globally
|
||||
* accessible functions.
|
||||
*/
|
||||
typedef boost::signals2::signal<void(pid_t, int)> SignalType;
|
||||
typedef signals2::signal<void(pid_t, int)> sig;
|
||||
typedef sig::slot_type slot;
|
||||
|
||||
/** The signal is connected in the calling routine to the desired
|
||||
* slot. We pass a shared_ptr rather than a reference to the signal
|
||||
@ -61,9 +62,10 @@ public:
|
||||
* class (and hence the signal) to be destructed before the forked
|
||||
* call is complete.
|
||||
*
|
||||
* It doesn't matter if the slot disappears, SigC takes care of that.
|
||||
* Use Slot::track or Signal::scoped_connection to ensure that the
|
||||
* connection is closed before the slot expires.
|
||||
*/
|
||||
typedef std::shared_ptr<SignalType> SignalTypePtr;
|
||||
typedef std::shared_ptr<sig> sigPtr;
|
||||
|
||||
/** Invoking the following methods makes sense only if the command
|
||||
* is running asynchronously!
|
||||
@ -114,7 +116,7 @@ protected:
|
||||
pid_t fork();
|
||||
|
||||
/// Callback function
|
||||
SignalTypePtr signal_;
|
||||
sigPtr signal_;
|
||||
|
||||
/// identifying command (for display in the GUI perhaps).
|
||||
std::string command_;
|
||||
@ -136,7 +138,7 @@ private:
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
/**
|
||||
* An instance of class ForkedCall represents a single child process.
|
||||
*
|
||||
* Class ForkedCall uses fork() and execvp() to lauch the child process.
|
||||
@ -175,7 +177,7 @@ public:
|
||||
int startScript(Starttype, std::string const & what);
|
||||
|
||||
///
|
||||
int startScript(std::string const & what, SignalTypePtr);
|
||||
int startScript(std::string const & what, sigPtr ptr);
|
||||
|
||||
private:
|
||||
///
|
||||
@ -195,7 +197,7 @@ private:
|
||||
|
||||
namespace ForkedCallQueue {
|
||||
|
||||
ForkedCall::SignalTypePtr add(std::string const & process);
|
||||
ForkedCall::sigPtr add(std::string const & process);
|
||||
/// Query whether the queue is running a forked process now.
|
||||
bool running();
|
||||
|
||||
|
@ -93,6 +93,7 @@ liblyxsupport_a_SOURCES = \
|
||||
qstring_helpers.h \
|
||||
regex.h \
|
||||
RefChanger.h \
|
||||
signals.h \
|
||||
socktools.cpp \
|
||||
socktools.h \
|
||||
strfwd.h \
|
||||
|
@ -12,7 +12,7 @@
|
||||
#ifndef TIMEOUT_H
|
||||
#define TIMEOUT_H
|
||||
|
||||
#include <boost/signals2.hpp>
|
||||
#include "support/signals.h"
|
||||
|
||||
|
||||
namespace lyx {
|
||||
@ -40,7 +40,7 @@ public:
|
||||
/// restart the timer
|
||||
void restart();
|
||||
/// signal emitted on timer expiry
|
||||
boost::signals2::signal<void()> timeout;
|
||||
signals2::signal<void()> timeout;
|
||||
/// emit the signal
|
||||
void emit();
|
||||
/// set the timer type
|
||||
|
49
src/support/signals.h
Normal file
49
src/support/signals.h
Normal file
@ -0,0 +1,49 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file signals.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Guillaume Munch
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#ifndef LYX_SIGNALS_H
|
||||
#define LYX_SIGNALS_H
|
||||
|
||||
#include "boost/signals2.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace lyx {
|
||||
|
||||
namespace signals2 = ::boost::signals2;
|
||||
|
||||
namespace support {
|
||||
|
||||
/// A small utility to use with signals2::slot_type::track_foreign when the
|
||||
/// parent object is not handled by a shared_ptr, or to track the lifetime of an
|
||||
/// object. Using Trackable to track lifetimes is less thread-safe than tracking
|
||||
/// their parents directly with a shared_ptr as recommended by signals2, but it
|
||||
/// makes it easier for transitioning old code. (Essentially because Trackable
|
||||
/// will not prevent the deletion of the parent by a concurrent thread.)
|
||||
class Trackable {
|
||||
public:
|
||||
Trackable() : p_(std::make_shared<int>(0)) {}
|
||||
Trackable(Trackable const &) : Trackable() {}
|
||||
Trackable(Trackable &&) : Trackable() {}
|
||||
Trackable & operator=(Trackable const &) { return *this; }
|
||||
Trackable & operator=(Trackable &&) { return *this; }
|
||||
// This weak pointer lets you know if the parent object has been destroyed
|
||||
std::weak_ptr<void> p() const { return p_; }
|
||||
private:
|
||||
std::shared_ptr<void> const p_;
|
||||
};
|
||||
|
||||
} // namespace support
|
||||
|
||||
} // namespace lyx
|
||||
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user