Skip to content

Commit

Permalink
Refs #4641 thread-safe QwtPlot replacement
Browse files Browse the repository at this point in the history
Also refs #4516, using this safeqwtPlot in SliceViewer looks to make it impossible to segfault
  • Loading branch information
Janik Zikovsky committed Jan 24, 2012
1 parent 9de3648 commit 2673799
Show file tree
Hide file tree
Showing 5 changed files with 138 additions and 2 deletions.
2 changes: 2 additions & 0 deletions Code/Mantid/MantidQt/API/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ set ( SRC_FILES
src/MantidDialog.cpp
src/MantidWidget.cpp
src/PythonRunner.cpp
src/SafeQwtPlot.cpp
src/SyncedCheckboxes.cpp
src/UserSubWindow.cpp
src/VatesViewerInterface.cpp
Expand All @@ -30,6 +31,7 @@ set ( INC_FILES
inc/MantidQtAPI/MantidDialog.h
inc/MantidQtAPI/MantidWidget.h
inc/MantidQtAPI/PythonRunner.h
inc/MantidQtAPI/SafeQwtPlot.h
inc/MantidQtAPI/SyncedCheckboxes.h
inc/MantidQtAPI/UserSubWindow.h
inc/MantidQtAPI/VatesViewerInterface.h
Expand Down
65 changes: 65 additions & 0 deletions Code/Mantid/MantidQt/API/inc/MantidQtAPI/SafeQwtPlot.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#ifndef MANTID_API_SAFEQWTPLOT_H_
#define MANTID_API_SAFEQWTPLOT_H_

#include "MantidKernel/System.h"
#include <qwt_plot.h>
#include <qpainter.h>
#include "qwt_text.h"
#include "MantidAPI/Workspace.h"


namespace MantidQt
{
namespace API
{

/** A version of QwtPlot that adds a layer of thread safety.
* Each SafeQwtPlot has a workspace associated with it.
* Before drawing, it acquires a ReadLock to prevent
* an algorithm from modifying the underlying workspace while it is
* drawing.
@date 2012-01-24
Copyright &copy; 2012 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport SafeQwtPlot : public QwtPlot
{
public:
explicit SafeQwtPlot(QWidget * parent = NULL);
explicit SafeQwtPlot(const QwtText &title, QWidget *p = NULL);

virtual ~SafeQwtPlot();

virtual void drawCanvas(QPainter * painter);

void setWorkspace(Mantid::API::Workspace_sptr ws);

private:
/// Workspace being read-locked
Mantid::API::Workspace_sptr m_ws;
};


} // namespace API
} // namespace MantidQt

#endif /* MANTID_API_SAFEQWTPLOT_H_ */
65 changes: 65 additions & 0 deletions Code/Mantid/MantidQt/API/src/SafeQwtPlot.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include "MantidQtAPI/SafeQwtPlot.h"
#include "MantidKernel/System.h"
#include "MantidKernel/ReadLock.h"

using namespace Mantid::Kernel;

namespace MantidQt
{
namespace API
{


//----------------------------------------------------------------------------------------------
/** Constructor
*/
SafeQwtPlot::SafeQwtPlot(QWidget * parent)
: QwtPlot(parent)
{
}


//----------------------------------------------------------------------------------------------
/** Constructor
*/
SafeQwtPlot::SafeQwtPlot(const QwtText &title, QWidget * parent)
: QwtPlot(title, parent)
{
}

//----------------------------------------------------------------------------------------------
/** Destructor
*/
SafeQwtPlot::~SafeQwtPlot()
{
}


//----------------------------------------------------------------------------------------------
/** Set the workspace that we read-lock when drawing.
*
* @param ws :: shared ptr to workspace
*/
void SafeQwtPlot::setWorkspace(Mantid::API::Workspace_sptr ws)
{
m_ws = ws;
}

//----------------------------------------------------------------------------------------------
/** Overridden drawCanvas() that protects the
* workspace from being overwritten while being drawn
*
* @param painter :: QPainter
*/
void SafeQwtPlot::drawCanvas(QPainter * painter)
{
// Do nothing if the workspace is not valid.
if (!m_ws) return;
// Get the scoped read lock.
ReadLock lock(*m_ws);
// Draw using the usual procedure.
QwtPlot::drawCanvas(painter);
}

} // namespace MantidQt
} // namespace API
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "MantidGeometry/MDGeometry/MDHistoDimension.h"
#include "MantidKernel/VMD.h"
#include "MantidQtAPI/MantidColorMap.h"
#include "MantidQtAPI/SafeQwtPlot.h"
#include "MantidQtAPI/SyncedCheckboxes.h"
#include "MantidQtSliceViewer/LineOverlay.h"
#include "QwtRasterDataMD.h"
Expand Down Expand Up @@ -135,7 +136,7 @@ public slots:
Ui::SliceViewerClass ui;

/// Main plot object
QwtPlot * m_plot;
MantidQt::API::SafeQwtPlot * m_plot;

/// Spectrogram plot
QwtPlotSpectrogram * m_spect;
Expand Down
5 changes: 4 additions & 1 deletion Code/Mantid/MantidQt/SliceViewer/src/SliceViewer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include <vector>
#include "MantidKernel/V3D.h"
#include "MantidKernel/ReadLock.h"
#include "MantidQtAPI/SafeQwtPlot.h"


using namespace Mantid;
Expand All @@ -63,6 +64,7 @@ using Poco::XML::Node;
using Poco::XML::NodeList;
using Poco::XML::NodeIterator;
using Poco::XML::NodeFilter;
using MantidQt::API::SafeQwtPlot;

namespace MantidQt
{
Expand All @@ -86,7 +88,7 @@ SliceViewer::SliceViewer(QWidget *parent)

// Create the plot
m_spectLayout = new QHBoxLayout(ui.frmPlot);
m_plot = new QwtPlot();
m_plot = new SafeQwtPlot();
m_plot->autoRefresh();
m_spectLayout->addWidget(m_plot, 1, 0);

Expand Down Expand Up @@ -424,6 +426,7 @@ void SliceViewer::setWorkspace(Mantid::API::IMDWorkspace_sptr ws)
{
m_ws = ws;
m_data->setWorkspace(ws);
m_plot->setWorkspace(ws);

// Emit the signal that we changed the workspace
emit workspaceChanged();
Expand Down

0 comments on commit 2673799

Please sign in to comment.