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

Reply via email to