Make static counters atomic

This ensures thread-safety

(requires: gcc >= 4.6, MSVC >= 2015)
This commit is contained in:
Guillaume Munch 2016-07-10 16:50:19 +01:00
parent 2fd2e65745
commit 46d8dfc6c2
3 changed files with 24 additions and 21 deletions

View File

@ -61,6 +61,7 @@
#include "support/lstrings.h" #include "support/lstrings.h"
#include "support/textutils.h" #include "support/textutils.h"
#include <atomic>
#include <sstream> #include <sstream>
#include <vector> #include <vector>
@ -283,10 +284,11 @@ private:
class Paragraph::Private class Paragraph::Private
{ {
// Enforce our own "copy" constructor by declaring the standard one and // Enforce our own "copy" constructor
// the assignment operator private without implementing them. Private(Private const &) = delete;
Private(Private const &); Private & operator=(Private const &) = delete;
Private & operator=(Private const &); // Unique ID generator
static int make_id();
public: public:
/// ///
Private(Paragraph * owner, Layout const & layout); 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, //static
// int Paragraph::Private::make_id()
// 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 // The id is unique per session across buffers because it is used in
// in the running program. // LFUN_PARAGRAPH_GOTO to switch to a different buffer, for instance in the
// However, this per-session id is used in LFUN_PARAGRAPH_GOTO to // outliner.
// switch to a different buffer, as used in the outliner for instance. // (thread-safe)
static int paragraph_id = -1; static atomic_uint next_id(0);
return next_id++;
}
Paragraph::Private::Private(Private const & p, Paragraph * owner) Paragraph::Private::Private(Private const & p, Paragraph * owner)
: owner_(owner), inset_owner_(p.inset_owner_), fontlist_(p.fontlist_), : owner_(owner), inset_owner_(p.inset_owner_), fontlist_(p.fontlist_),
id_(make_id()),
params_(p.params_), changes_(p.changes_), insetlist_(p.insetlist_), params_(p.params_), changes_(p.changes_), insetlist_(p.insetlist_),
begin_of_body_(p.begin_of_body_), text_(p.text_), words_(p.words_), begin_of_body_(p.begin_of_body_), text_(p.text_), words_(p.words_),
layout_(p.layout_) layout_(p.layout_)
{ {
id_ = ++paragraph_id;
requestSpellCheck(p.text_.size()); requestSpellCheck(p.text_.size());
} }
Paragraph::Private::Private(Private const & p, Paragraph * owner, Paragraph::Private::Private(Private const & p, Paragraph * owner,
pos_type beg, pos_type end) 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_), params_(p.params_), changes_(p.changes_),
insetlist_(p.insetlist_, beg, end), insetlist_(p.insetlist_, beg, end),
begin_of_body_(p.begin_of_body_), words_(p.words_), begin_of_body_(p.begin_of_body_), words_(p.words_),
layout_(p.layout_) layout_(p.layout_)
{ {
id_ = ++paragraph_id;
if (beg >= pos_type(p.text_.size())) if (beg >= pos_type(p.text_.size()))
return; return;
text_ = p.text_.substr(beg, end - beg); text_ = p.text_.substr(beg, end - beg);

View File

@ -41,6 +41,7 @@
#include "support/bind.h" #include "support/bind.h"
#include "support/TempFile.h" #include "support/TempFile.h"
#include <atomic>
#include <fstream> #include <fstream>
#include <iomanip> #include <iomanip>
#include <memory> #include <memory>
@ -728,8 +729,7 @@ void PreviewLoader::Impl::startLoading(bool wait)
if (wait) { if (wait) {
ForkedCall call(buffer_.filePath(), buffer_.layoutPos()); ForkedCall call(buffer_.filePath(), buffer_.layoutPos());
int ret = call.startScript(ForkedProcess::Wait, command); int ret = call.startScript(ForkedProcess::Wait, command);
// FIXME THREAD static atomic_int fake((2^20) + 1);
static int fake = (2^20) + 1;
int pid = fake++; int pid = fake++;
inprogress.pid = pid; inprogress.pid = pid;
inprogress.command = command; inprogress.command = command;

View File

@ -27,6 +27,7 @@
#include "support/lstrings.h" #include "support/lstrings.h"
#include "support/textutils.h" #include "support/textutils.h"
#include <atomic>
#include <map> #include <map>
#include <QThreadStorage> #include <QThreadStorage>
@ -105,10 +106,8 @@ docstring sgml::escapeString(docstring const & raw)
docstring const sgml::uniqueID(docstring const & label) docstring const sgml::uniqueID(docstring const & label)
{ {
// FIXME THREAD // thread-safe
// It seems unlikely there could be a problem here, static atomic_uint seed(1000);
// but we could have concurrent access, in principle.
static unsigned int seed = 1000;
return label + convert<docstring>(++seed); return label + convert<docstring>(++seed);
} }