cid#1659918 Data race condition

and

cid#1660133 Data race condition
cid#1660238 Data race condition
etc.

Change-Id: Ic0278e430c62abda92e8ce0e590a4726a4488b30
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190791
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolan.mcnamara@collabora.com>
This commit is contained in:
Caolán McNamara
2025-09-12 09:37:43 +02:00
parent 21f76249dc
commit dedf0c1bcb
2 changed files with 104 additions and 76 deletions
+12 -17
View File
@@ -89,9 +89,6 @@ struct SVXCORE_DLLPUBLIC AnnotationData
OUString m_Initials;
css::util::DateTime m_DateTime;
OUString m_Text;
void get(Annotation& rAnnotation);
void set(Annotation& rAnnotation);
};
/** Annotation object, responsible for handling of the annotation.
@@ -103,6 +100,11 @@ class SVXCORE_DLLPUBLIC Annotation
: public ::comphelper::WeakComponentImplHelper<css::office::XAnnotation>,
public ::cppu::PropertySetMixin<css::office::XAnnotation>
{
private:
css::uno::Reference<css::text::XText> getTextRangeImpl(const std::unique_lock<std::mutex>& g);
OUString GetTextImpl(const std::unique_lock<std::mutex>& g);
void SetTextImpl(OUString const& rText, const std::unique_lock<std::mutex>& g);
protected:
SdrPage* mpPage;
UniqueID maUniqueID;
@@ -135,20 +137,8 @@ public:
}
// Changes without triggering notification broadcast
const css::geometry::RealPoint2D& GetPosition() const { return m_Position; }
void SetPosition(const css::geometry::RealPoint2D& rValue) { m_Position = rValue; }
const css::geometry::RealSize2D& GetSize() const { return m_Size; }
void SetSize(const css::geometry::RealSize2D& rValue) { m_Size = rValue; }
const OUString& GetAuthor() const { return m_Author; }
void SetAuthor(const OUString& rValue) { m_Author = rValue; }
const OUString& GetInitials() const { return m_Initials; }
void SetInitials(const OUString& rValue) { m_Initials = rValue; }
const css::util::DateTime& GetDateTime() const { return m_DateTime; }
void SetDateTime(const css::util::DateTime& rValue) { m_DateTime = rValue; }
void SetPosition(const css::geometry::RealPoint2D& rValue);
void SetSize(const css::geometry::RealSize2D& rValue);
virtual css::uno::Reference<css::text::XText> SAL_CALL getTextRange() override;
@@ -160,6 +150,11 @@ public:
OUString GetText();
void SetText(OUString const& rText);
OString ToJSON(CommentNotificationType nType);
void toData(AnnotationData& rData);
void fromData(const AnnotationData& rData);
const rtl::Reference<sdr::annotation::TextApiObject>& getTextApiObject() { return m_TextRange; }
SdrModel* GetModel() const;
+92 -59
View File
@@ -22,42 +22,6 @@ namespace sdr::annotation
{
namespace
{
OString lcl_LOKGetCommentPayload(CommentNotificationType nType, Annotation& rAnnotation)
{
tools::JsonWriter aJsonWriter;
{
auto aCommentNode = aJsonWriter.startNode("comment");
aJsonWriter.put(
"action",
(nType == CommentNotificationType::Add
? "Add"
: (nType == CommentNotificationType::Remove
? "Remove"
: (nType == CommentNotificationType::Modify ? "Modify" : "???"))));
aJsonWriter.put("id", rAnnotation.GetId());
if (nType != CommentNotificationType::Remove)
{
aJsonWriter.put("id", rAnnotation.GetId());
aJsonWriter.put("author", rAnnotation.GetAuthor());
aJsonWriter.put("dateTime", utl::toISO8601(rAnnotation.GetDateTime()));
aJsonWriter.put("text", rAnnotation.GetText());
SdrPage const* pPage = rAnnotation.getPage();
aJsonWriter.put("parthash", pPage ? OString::number(pPage->GetUniqueID()) : OString());
geometry::RealPoint2D const aPoint = rAnnotation.GetPosition();
geometry::RealSize2D const aSize = rAnnotation.GetSize();
tools::Rectangle aRectangle(
Point(std::round(o3tl::toTwips(aPoint.X, o3tl::Length::mm)),
std::round(o3tl::toTwips(aPoint.Y, o3tl::Length::mm))),
Size(std::round(o3tl::toTwips(aSize.Width, o3tl::Length::mm)),
std::round(o3tl::toTwips(aSize.Height, o3tl::Length::mm))));
aJsonWriter.put("rectangle", aRectangle.toString());
}
}
return aJsonWriter.finishAndGetAsOString();
}
/** Undo/redo a modification of an annotation - change of annotation data */
class UndoAnnotation : public SdrUndoAction
{
@@ -66,20 +30,20 @@ public:
: SdrUndoAction(*rAnnotation.GetModel())
, mrAnnotation(rAnnotation)
{
maUndoData.get(mrAnnotation);
mrAnnotation.toData(maUndoData);
}
void Undo() override
{
maRedoData.get(mrAnnotation);
maUndoData.set(mrAnnotation);
mrAnnotation.toData(maRedoData);
mrAnnotation.fromData(maUndoData);
LOKCommentNotifyAll(CommentNotificationType::Modify, mrAnnotation);
}
void Redo() override
{
maUndoData.get(mrAnnotation);
maRedoData.set(mrAnnotation);
mrAnnotation.toData(maUndoData);
mrAnnotation.fromData(maRedoData);
LOKCommentNotifyAll(CommentNotificationType::Modify, mrAnnotation);
}
@@ -98,7 +62,7 @@ void LOKCommentNotify(CommentNotificationType nType, const SfxViewShell* pViewSh
if (!comphelper::LibreOfficeKit::isActive() || comphelper::LibreOfficeKit::isTiledAnnotations())
return;
OString aPayload = lcl_LOKGetCommentPayload(nType, rAnnotation);
OString aPayload = rAnnotation.ToJSON(nType);
pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_COMMENT, aPayload);
}
@@ -108,7 +72,7 @@ void LOKCommentNotifyAll(CommentNotificationType nType, Annotation& rAnnotation)
if (!comphelper::LibreOfficeKit::isActive() || comphelper::LibreOfficeKit::isTiledAnnotations())
return;
OString aPayload = lcl_LOKGetCommentPayload(nType, rAnnotation);
OString aPayload = rAnnotation.ToJSON(nType);
const SfxViewShell* pViewShell = SfxViewShell::GetFirst();
while (pViewShell)
@@ -118,24 +82,26 @@ void LOKCommentNotifyAll(CommentNotificationType nType, Annotation& rAnnotation)
}
}
void AnnotationData::get(Annotation& rAnnotation)
void Annotation::toData(AnnotationData& rData)
{
m_Position = rAnnotation.GetPosition();
m_Size = rAnnotation.GetSize();
m_Author = rAnnotation.GetAuthor();
m_Initials = rAnnotation.GetInitials();
m_DateTime = rAnnotation.GetDateTime();
m_Text = rAnnotation.GetText();
std::unique_lock g(m_aMutex);
rData.m_Position = m_Position;
rData.m_Size = m_Size;
rData.m_Author = m_Author;
rData.m_Initials = m_Initials;
rData.m_DateTime = m_DateTime;
rData.m_Text = GetTextImpl(g);
}
void AnnotationData::set(Annotation& rAnnotation)
void Annotation::fromData(const AnnotationData& rData)
{
rAnnotation.SetPosition(m_Position);
rAnnotation.SetSize(m_Size);
rAnnotation.SetAuthor(m_Author);
rAnnotation.SetInitials(m_Initials);
rAnnotation.SetDateTime(m_DateTime);
rAnnotation.SetText(m_Text);
std::unique_lock g(m_aMutex);
m_Position = rData.m_Position;
m_Size = rData.m_Size;
m_Author = rData.m_Author;
m_Initials = rData.m_Initials;
m_DateTime = rData.m_DateTime;
SetTextImpl(rData.m_Text, g);
}
Annotation::Annotation(const css::uno::Reference<css::uno::XComponentContext>& rxContext,
@@ -163,19 +129,36 @@ std::unique_ptr<SdrUndoAction> Annotation::createUndoAnnotation()
OUString Annotation::GetText()
{
uno::Reference<text::XText> xText(getTextRange());
std::unique_lock g(m_aMutex);
return GetTextImpl(g);
}
OUString Annotation::GetTextImpl(const std::unique_lock<std::mutex>& g)
{
uno::Reference<text::XText> xText(getTextRangeImpl(g));
return xText->getString();
}
void Annotation::SetText(OUString const& rText)
{
uno::Reference<text::XText> xText(getTextRange());
std::unique_lock g(m_aMutex);
SetTextImpl(rText, g);
}
void Annotation::SetTextImpl(OUString const& rText, const std::unique_lock<std::mutex>& g)
{
uno::Reference<text::XText> xText(getTextRangeImpl(g));
return xText->setString(rText);
}
uno::Reference<text::XText> SAL_CALL Annotation::getTextRange()
{
std::unique_lock g(m_aMutex);
return getTextRangeImpl(g);
}
uno::Reference<text::XText> Annotation::getTextRangeImpl(const std::unique_lock<std::mutex>& /*g*/)
{
if (!m_TextRange.is() && mpPage != nullptr)
{
m_TextRange = sdr::annotation::TextApiObject::create(&mpPage->getSdrModelFromSdrPage());
@@ -183,6 +166,18 @@ uno::Reference<text::XText> SAL_CALL Annotation::getTextRange()
return m_TextRange;
}
void Annotation::SetPosition(const css::geometry::RealPoint2D& rValue)
{
std::unique_lock g(m_aMutex);
m_Position = rValue;
}
void Annotation::SetSize(const css::geometry::RealSize2D& rValue)
{
std::unique_lock g(m_aMutex);
m_Size = rValue;
}
void Annotation::disposing(std::unique_lock<std::mutex>& /*rGuard*/)
{
mpPage = nullptr;
@@ -210,6 +205,44 @@ SdrObject* Annotation::findAnnotationObject()
return nullptr;
}
OString Annotation::ToJSON(CommentNotificationType nType)
{
tools::JsonWriter aJsonWriter;
{
auto aCommentNode = aJsonWriter.startNode("comment");
aJsonWriter.put(
"action",
(nType == CommentNotificationType::Add
? "Add"
: (nType == CommentNotificationType::Remove
? "Remove"
: (nType == CommentNotificationType::Modify ? "Modify" : "???"))));
std::unique_lock g(m_aMutex);
sal_uInt64 id = maUniqueID.getID();
aJsonWriter.put("id", id);
if (nType != CommentNotificationType::Remove)
{
aJsonWriter.put("id", id);
aJsonWriter.put("author", m_Author);
aJsonWriter.put("dateTime", utl::toISO8601(m_DateTime));
aJsonWriter.put("text", GetTextImpl(g));
aJsonWriter.put("parthash",
mpPage ? OString::number(mpPage->GetUniqueID()) : OString());
tools::Rectangle aRectangle(
Point(std::round(o3tl::toTwips(m_Position.X, o3tl::Length::mm)),
std::round(o3tl::toTwips(m_Position.Y, o3tl::Length::mm))),
Size(std::round(o3tl::toTwips(m_Size.Width, o3tl::Length::mm)),
std::round(o3tl::toTwips(m_Size.Height, o3tl::Length::mm))));
aJsonWriter.put("rectangle", aRectangle.toString());
}
}
return aJsonWriter.finishAndGetAsOString();
}
} // namespace sdr::annotation
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */