Le 10/07/2016 15:49, Guillaume Munch a écrit :
Le 09/07/2016 22:23, Richard Heck a écrit :
If I do:
onePar.id() == otherPar.id()
will that do what I obviously want it to do? I.e., work as a proxy for:
onePar == otherPar
??
After reading the code, I think that:
onePar.id() == otherPar.id()
is equivalent to
onePar == otherPar || (onePar.id() == -1 && otherPar.id() == -1)
That is, unless two paragraphs have the same id following a race
condition when generating the id. I do not think this can happen
currently but I suggest the attached patch to make id generation atomic.
>From 5d240938e3a9cffea833771e2e6b783368126d10 Mon Sep 17 00:00:00 2001
From: Guillaume Munch <g...@lyx.org>
Date: Sun, 10 Jul 2016 16:50:19 +0100
Subject: [PATCH] Make paragraph id increment atomic
(Note: requires MSVC >= 2015)
---
src/Paragraph.cpp | 33 ++++++++++++++++++---------------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/src/Paragraph.cpp b/src/Paragraph.cpp
index 8ea300e..02fd23e 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,36 @@ 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.
+ static atomic_int 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);
--
2.7.4