commit 46d8dfc6c2fe3c75687bee773933a9fc7aec95c2
Author: Guillaume Munch <[email protected]>
Date: Sun Jul 10 16:50:19 2016 +0100
Make static counters atomic
This ensures thread-safety
(requires: gcc >= 4.6, MSVC >= 2015)
---
src/Paragraph.cpp | 34 +++++++++++++++++++---------------
src/graphics/PreviewLoader.cpp | 4 ++--
src/sgml.cpp | 7 +++----
3 files changed, 24 insertions(+), 21 deletions(-)
diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp
index d1faa43..f9d942e 100644
--- a/src/Paragraph.cpp
+++ b/src/Paragraph.cpp
@@ -61,6 +61,7 @@
#include "support/lstrings.h"
#include "support/textutils.h"
+#include <atomic>
#include <sstream>
#include <vector>
@@ -283,10 +284,11 @@ private:
class Paragraph::Private
{
- // Enforce our own "copy" constructor by declaring the standard one and
- // the assignment operator private without implementing them.
- Private(Private const &);
- Private & operator=(Private const &);
+ // Enforce our own "copy" constructor
+ Private(Private const &) = delete;
+ Private & operator=(Private const &) = delete;
+ // Unique ID generator
+ static int make_id();
public:
///
Private(Paragraph * owner, Layout const & layout);
@@ -506,35 +508,37 @@ Paragraph::Private::Private(Paragraph * owner, Layout
const & layout)
}
-// Initialization of the counter for the paragraph id's,
-//
-// FIXME: There should be a more intelligent way to generate and use the
-// paragraph ids per buffer instead a global static counter for all InsetText
-// in the running program.
-// However, this per-session id is used in LFUN_PARAGRAPH_GOTO to
-// switch to a different buffer, as used in the outliner for instance.
-static int paragraph_id = -1;
+//static
+int Paragraph::Private::make_id()
+{
+ // The id is unique per session across buffers because it is used in
+ // LFUN_PARAGRAPH_GOTO to switch to a different buffer, for instance in
the
+ // outliner.
+ // (thread-safe)
+ static atomic_uint next_id(0);
+ return next_id++;
+}
+
Paragraph::Private::Private(Private const & p, Paragraph * owner)
: owner_(owner), inset_owner_(p.inset_owner_), fontlist_(p.fontlist_),
+ id_(make_id()),
params_(p.params_), changes_(p.changes_), insetlist_(p.insetlist_),
begin_of_body_(p.begin_of_body_), text_(p.text_), words_(p.words_),
layout_(p.layout_)
{
- id_ = ++paragraph_id;
requestSpellCheck(p.text_.size());
}
Paragraph::Private::Private(Private const & p, Paragraph * owner,
pos_type beg, pos_type end)
- : owner_(owner), inset_owner_(p.inset_owner_),
+ : owner_(owner), inset_owner_(p.inset_owner_), id_(make_id()),
params_(p.params_), changes_(p.changes_),
insetlist_(p.insetlist_, beg, end),
begin_of_body_(p.begin_of_body_), words_(p.words_),
layout_(p.layout_)
{
- id_ = ++paragraph_id;
if (beg >= pos_type(p.text_.size()))
return;
text_ = p.text_.substr(beg, end - beg);
diff --git a/src/graphics/PreviewLoader.cpp b/src/graphics/PreviewLoader.cpp
index 1f78d77..1240771 100644
--- a/src/graphics/PreviewLoader.cpp
+++ b/src/graphics/PreviewLoader.cpp
@@ -41,6 +41,7 @@
#include "support/bind.h"
#include "support/TempFile.h"
+#include <atomic>
#include <fstream>
#include <iomanip>
#include <memory>
@@ -728,8 +729,7 @@ void PreviewLoader::Impl::startLoading(bool wait)
if (wait) {
ForkedCall call(buffer_.filePath(), buffer_.layoutPos());
int ret = call.startScript(ForkedProcess::Wait, command);
- // FIXME THREAD
- static int fake = (2^20) + 1;
+ static atomic_int fake((2^20) + 1);
int pid = fake++;
inprogress.pid = pid;
inprogress.command = command;
diff --git a/src/sgml.cpp b/src/sgml.cpp
index 75802c2..2facb3e 100644
--- a/src/sgml.cpp
+++ b/src/sgml.cpp
@@ -27,6 +27,7 @@
#include "support/lstrings.h"
#include "support/textutils.h"
+#include <atomic>
#include <map>
#include <QThreadStorage>
@@ -105,10 +106,8 @@ docstring sgml::escapeString(docstring const & raw)
docstring const sgml::uniqueID(docstring const & label)
{
- // FIXME THREAD
- // It seems unlikely there could be a problem here,
- // but we could have concurrent access, in principle.
- static unsigned int seed = 1000;
+ // thread-safe
+ static atomic_uint seed(1000);
return label + convert<docstring>(++seed);
}