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/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);

View File

@ -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;

View File

@ -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);
}