Author: kuemmel
Date: Sat Jan 15 22:06:28 2011
New Revision: 37222
URL: http://www.lyx.org/trac/changeset/37222

Log:
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.

Added:
   lyx-devel/trunk/src/support/mutex.cpp   (contents, props changed)
   lyx-devel/trunk/src/support/mutex.h   (contents, props changed)
Modified:
   lyx-devel/trunk/src/Graph.cpp
   lyx-devel/trunk/src/Graph.h

Modified: lyx-devel/trunk/src/Graph.cpp
==============================================================================
--- lyx-devel/trunk/src/Graph.cpp       Sat Jan 15 21:51:20 2011        (r37221)
+++ lyx-devel/trunk/src/Graph.cpp       Sat Jan 15 22:06:28 2011        (r37222)
@@ -57,6 +57,8 @@
 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 @@
        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 @@
 
 bool Graph::isReachable(int from, int to)
 {
+       Mutex::Locker lock(&mutex_);
+
        if (from == to)
                return true;
 
@@ -159,6 +165,8 @@
 
 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 @@
 
 void Graph::init(int size)
 {
+       Mutex::Locker lock(&mutex_);
+
        vertices_ = vector<Vertex>(size);
        arrows_.clear();
        numedges_ = 0;
@@ -207,6 +217,8 @@
 
 void Graph::addEdge(int from, int to)
 {
+       Mutex::Locker lock(&mutex_);
+
        arrows_.push_back(Arrow(from, to, numedges_));
        numedges_++;
        Arrow * ar = &(arrows_.back());

Modified: lyx-devel/trunk/src/Graph.h
==============================================================================
--- lyx-devel/trunk/src/Graph.h Sat Jan 15 21:51:20 2011        (r37221)
+++ lyx-devel/trunk/src/Graph.h Sat Jan 15 22:06:28 2011        (r37222)
@@ -13,6 +13,8 @@
 #ifndef GRAPH_H
 #define GRAPH_H
 
+#include "support/mutex.h"
+
 #include <list>
 #include <queue>
 #include <vector>
@@ -100,6 +102,9 @@
        /// 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_;
 };
 
 

Added: lyx-devel/trunk/src/support/mutex.cpp
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ lyx-devel/trunk/src/support/mutex.cpp       Sat Jan 15 22:06:28 2011        
(r37222)
@@ -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

Added: lyx-devel/trunk/src/support/mutex.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ lyx-devel/trunk/src/support/mutex.h Sat Jan 15 22:06:28 2011        (r37222)
@@ -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

Reply via email to