Fix crash on Windows:

1. open LYX
2. CRTL-N
3. CRTL-D hold D --> crash

Graph must be thread save to fix this.

And for sure, we need a mutex also later.

Mutex is a simple wrapper around QMutex, with
pseudo-value semantic.


git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@37222 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
Peter Kümmel 2011-01-15 21:06:28 +00:00
parent aac2310ea0
commit 06f26e85df
4 changed files with 152 additions and 0 deletions

View File

@ -57,6 +57,8 @@ void Graph::clearPaths()
vector<int> const
Graph::getReachableTo(int target, bool clear_visited)
{
Mutex::Locker lock(&mutex_);
vector<int> result;
if (!bfs_init(target, clear_visited))
return result;
@ -92,6 +94,8 @@ vector<int> const
Graph::getReachable(int from, bool only_viewable,
bool clear_visited)
{
Mutex::Locker lock(&mutex_);
vector<int> result;
if (!bfs_init(from, clear_visited))
return result;
@ -128,6 +132,8 @@ vector<int> const
bool Graph::isReachable(int from, int to)
{
Mutex::Locker lock(&mutex_);
if (from == to)
return true;
@ -159,6 +165,8 @@ bool Graph::isReachable(int from, int to)
Graph::EdgePath const Graph::getPath(int from, int to)
{
Mutex::Locker lock(&mutex_);
static const EdgePath path;
if (from == to)
return path;
@ -199,6 +207,8 @@ Graph::EdgePath const Graph::getPath(int from, int to)
void Graph::init(int size)
{
Mutex::Locker lock(&mutex_);
vertices_ = vector<Vertex>(size);
arrows_.clear();
numedges_ = 0;
@ -207,6 +217,8 @@ void Graph::init(int size)
void Graph::addEdge(int from, int to)
{
Mutex::Locker lock(&mutex_);
arrows_.push_back(Arrow(from, to, numedges_));
numedges_++;
Arrow * ar = &(arrows_.back());

View File

@ -13,6 +13,8 @@
#ifndef GRAPH_H
#define GRAPH_H
#include "support/mutex.h"
#include <list>
#include <queue>
#include <vector>
@ -100,6 +102,9 @@ private:
/// seems kind of fragile. Perhaps a better solution would be
/// to pass the ids as we create the arrows.
int numedges_;
/// make public functions thread save
Mutex mutex_;
};

72
src/support/mutex.cpp Normal file
View File

@ -0,0 +1,72 @@
/**
* \file mutex.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Peter Kümmel
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "mutex.h"
#include <QMutex>
namespace lyx {
struct Mutex::Private
{
// QMutex::Recursive: less risks for dead-locks
Private() : qmutex_(QMutex::Recursive)
{
}
QMutex qmutex_;
};
Mutex::Mutex() : d(new Private)
{
}
Mutex::~Mutex()
{
delete d;
}
// It makes no sense to copy the mutex,
// each instance has its own QMutex,
// therefore nothing to copy!
// TODO review
Mutex::Mutex(const Mutex&) : d(new Private)
{
}
Mutex& Mutex::operator=(const Mutex&)
{
return *this;
}
Mutex::Locker::Locker(Mutex* mtx) : mutex_(mtx)
{
mutex_->d->qmutex_.lock();
}
Mutex::Locker::~Locker()
{
mutex_->d->qmutex_.unlock();
}
} // namespace lyx

63
src/support/mutex.h Normal file
View File

@ -0,0 +1,63 @@
// -*- C++ -*-
/**
* \file mutex.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Peter Kümmel
*
* Full author contact details are available in file CREDITS.
*
* A collection of string helper functions that works with string.
* Some of these would certainly benefit from a rewrite/optimization.
*/
#ifndef MUTEX_H
#define MUTEX_H
namespace lyx {
class Mutex
{
public:
Mutex();
~Mutex();
/// Scope based locking:
/// Usage:
/// >>> unlocked
/// {
/// Mutex::Locker locker(a_Mutex_ptr);
/// >>> locked
/// }
/// >>> unlocked
class Locker
{
public:
Locker(Mutex*);
~Locker();
private:
Locker();
Locker(const Locker& rhs);
Locker& operator=(const Locker& rhs);
Mutex* mutex_;
};
// pseude-value semantic
// needed by GuiPrefs which makes a copy
Mutex(const Mutex&);
Mutex& operator=(const Mutex&);
private:
struct Private;
Private* d;
};
} // namespace lyx
#endif