include/salhelper/simplereferenceobject.hxx | 29 ++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-)
New commits: commit 914e79524cdd9c4176e6508d1401fb7dca6264e2 Author: Michael Meeks <michael.me...@collabora.com> AuthorDate: Thu Oct 17 07:24:10 2024 +0200 Commit: Noel Grandin <noel.gran...@collabora.co.uk> CommitDate: Mon Oct 21 09:47:28 2024 +0200 SimpleReferenceObject: add ability to staticize the ref-count. Useful for when we allocate data at startup and want to share it across multiple threads. Also potentiall useful for turning extreme cases of ref-count wrap-around into a more benign leak. Change-Id: I04e6a62dbd366d294d86ab72036c3498402357f0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175196 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk> diff --git a/include/salhelper/simplereferenceobject.hxx b/include/salhelper/simplereferenceobject.hxx index ac721ad3da98..59a2baf83bc6 100644 --- a/include/salhelper/simplereferenceobject.hxx +++ b/include/salhelper/simplereferenceobject.hxx @@ -60,20 +60,28 @@ namespace salhelper { */ class SALHELPER_DLLPUBLIC SimpleReferenceObject { + static const size_t nStaticFlag = 0x80000000; + public: SimpleReferenceObject(): m_nCount(0) {} /** @attention - The results are undefined if, for any individual instance of - SimpleReferenceObject, the total number of calls to acquire() exceeds - the total number of calls to release() by a platform dependent amount - (which, hopefully, is quite large). + If, for any individual instance of SimpleReferenceObject, the total + number of calls to acquire() exceeds the total number of calls to + release() by 2^31 - the object will never subsequently be released. */ void acquire() - { osl_atomic_increment(&m_nCount); } + { + if (!(m_nCount & nStaticFlag)) + osl_atomic_increment(&m_nCount); + } void release() - { if (osl_atomic_decrement(&m_nCount) == 0) delete this; } + { + if (!(m_nCount & nStaticFlag) && + osl_atomic_decrement(&m_nCount) == 0) + delete this; + } /** see general class documentation */ @@ -95,6 +103,15 @@ public: protected: virtual ~SimpleReferenceObject() COVERITY_NOEXCEPT_FALSE; + /** mark reference count as not to be touched, and the + * related object as having an indefinite lifespan. + * NB. do not use if you have a non-empty destructor. + */ + void staticize() + { + m_nCount |= nStaticFlag; + } + oslInterlockedCount m_nCount; private: