tsan: fix data race in o3tl::cow_wrapper
where the use_count() call was happening without any kind of synchronisation - switch to use std::atomic which does the right thing for us Change-Id: I79a6452f42bd425ea494bb0298dc134de5678813 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170217 Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk> Tested-by: Jenkins
This commit is contained in:
parent
02786af7ea
commit
c04de7a6f2
3 changed files with 15 additions and 12 deletions
|
@ -20,8 +20,7 @@
|
|||
#ifndef INCLUDED_O3TL_COW_WRAPPER_HXX
|
||||
#define INCLUDED_O3TL_COW_WRAPPER_HXX
|
||||
|
||||
#include <osl/interlck.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <optional>
|
||||
#include <cstddef>
|
||||
|
||||
|
@ -38,6 +37,7 @@ namespace o3tl
|
|||
typedef std::size_t ref_count_t;
|
||||
static void incrementCount( ref_count_t& rCount ) { ++rCount; }
|
||||
static bool decrementCount( ref_count_t& rCount ) { return --rCount != 0; }
|
||||
static std::size_t getCount( ref_count_t& rCount) { return rCount; }
|
||||
};
|
||||
|
||||
/** Thread-safe refcounting
|
||||
|
@ -47,12 +47,13 @@ namespace o3tl
|
|||
*/
|
||||
struct ThreadSafeRefCountingPolicy
|
||||
{
|
||||
typedef oslInterlockedCount ref_count_t;
|
||||
static void incrementCount( ref_count_t& rCount ) { osl_atomic_increment(&rCount); }
|
||||
typedef std::atomic<int> ref_count_t;
|
||||
static void incrementCount( ref_count_t& rCount ) { rCount++; }
|
||||
static bool decrementCount( ref_count_t& rCount )
|
||||
{
|
||||
return osl_atomic_decrement(&rCount) != 0;
|
||||
return (--rCount) != 0;
|
||||
}
|
||||
static std::size_t getCount( ref_count_t& rCount) { return rCount; }
|
||||
};
|
||||
|
||||
/** Copy-on-write wrapper.
|
||||
|
@ -315,9 +316,9 @@ int cow_wrapper_client::queryUnmodified() const
|
|||
}
|
||||
|
||||
/// return number of shared instances (1 for unique object)
|
||||
typename MTPolicy::ref_count_t use_count() const // nothrow
|
||||
size_t use_count() const // nothrow
|
||||
{
|
||||
return m_pimpl ? m_pimpl->m_ref_count : 0;
|
||||
return m_pimpl ? MTPolicy::getCount(m_pimpl->m_ref_count) : 0;
|
||||
}
|
||||
|
||||
void swap(cow_wrapper& r) // never throws
|
||||
|
|
|
@ -93,7 +93,7 @@ bool cow_wrapper_client2::is_unique() const
|
|||
{
|
||||
return maImpl.is_unique();
|
||||
}
|
||||
oslInterlockedCount cow_wrapper_client2::use_count() const
|
||||
int cow_wrapper_client2::use_count() const
|
||||
{
|
||||
return maImpl.use_count();
|
||||
}
|
||||
|
@ -171,7 +171,7 @@ bool cow_wrapper_client3::is_unique() const
|
|||
{
|
||||
return maImpl.is_unique();
|
||||
}
|
||||
oslInterlockedCount cow_wrapper_client3::use_count() const
|
||||
int cow_wrapper_client3::use_count() const
|
||||
{
|
||||
return maImpl.use_count();
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#ifndef INCLUDED_O3TL_QA_COW_WRAPPER_CLIENTS_HXX
|
||||
#define INCLUDED_O3TL_QA_COW_WRAPPER_CLIENTS_HXX
|
||||
|
||||
#include <sal/types.h>
|
||||
#include <o3tl/cow_wrapper.hxx>
|
||||
#include <assert.h>
|
||||
#include <iostream>
|
||||
|
@ -45,7 +46,7 @@ public:
|
|||
|
||||
void makeUnique() { maImpl.make_unique(); }
|
||||
bool is_unique() const { return maImpl.is_unique(); }
|
||||
oslInterlockedCount use_count() const { return maImpl.use_count(); }
|
||||
int use_count() const { return maImpl.use_count(); }
|
||||
void swap( cow_wrapper_client1& r ) { o3tl::swap(maImpl, r.maImpl); }
|
||||
|
||||
bool operator==( const cow_wrapper_client1& rRHS ) const { return maImpl == rRHS.maImpl; }
|
||||
|
@ -79,7 +80,7 @@ public:
|
|||
|
||||
void makeUnique();
|
||||
bool is_unique() const;
|
||||
oslInterlockedCount use_count() const;
|
||||
int use_count() const;
|
||||
void swap( cow_wrapper_client2& r );
|
||||
|
||||
bool operator==( const cow_wrapper_client2& rRHS ) const;
|
||||
|
@ -110,7 +111,7 @@ public:
|
|||
|
||||
void makeUnique();
|
||||
bool is_unique() const;
|
||||
oslInterlockedCount use_count() const;
|
||||
int use_count() const;
|
||||
void swap( cow_wrapper_client3& r );
|
||||
|
||||
bool operator==( const cow_wrapper_client3& rRHS ) const;
|
||||
|
@ -172,6 +173,7 @@ struct BogusRefCountPolicy
|
|||
}
|
||||
return rCount != 0;
|
||||
}
|
||||
static std::size_t getCount( ref_count_t& rCount) { return rCount; }
|
||||
};
|
||||
|
||||
class cow_wrapper_client5
|
||||
|
|
Loading…
Reference in a new issue