aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/icu/common/umutex.h
diff options
context:
space:
mode:
authorneksard <neksard@yandex-team.ru>2022-02-10 16:45:23 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:45:23 +0300
commit8f7cf138264e0caa318144bf8a2c950e0b0a8593 (patch)
tree83bf5c8c8047c42d8475e6095df90ccdc3d1b57f /contrib/libs/icu/common/umutex.h
parentd3a398281c6fd1d3672036cb2d63f842d2cb28c5 (diff)
downloadydb-8f7cf138264e0caa318144bf8a2c950e0b0a8593.tar.gz
Restoring authorship annotation for <neksard@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/icu/common/umutex.h')
-rw-r--r--contrib/libs/icu/common/umutex.h356
1 files changed, 178 insertions, 178 deletions
diff --git a/contrib/libs/icu/common/umutex.h b/contrib/libs/icu/common/umutex.h
index 2503aa4a29..22efae1b51 100644
--- a/contrib/libs/icu/common/umutex.h
+++ b/contrib/libs/icu/common/umutex.h
@@ -1,42 +1,42 @@
// © 2016 and later: Unicode, Inc. and others.
-// License & terms of use: http://www.unicode.org/copyright.html
-/*
-**********************************************************************
-* Copyright (C) 1997-2015, International Business Machines
-* Corporation and others. All Rights Reserved.
-**********************************************************************
-*
-* File UMUTEX.H
-*
-* Modification History:
-*
-* Date Name Description
-* 04/02/97 aliu Creation.
-* 04/07/99 srl rewrite - C interface, multiple mutices
-* 05/13/99 stephen Changed to umutex (from cmutex)
-******************************************************************************
-*/
-
-#ifndef UMUTEX_H
-#define UMUTEX_H
-
+// License & terms of use: http://www.unicode.org/copyright.html
+/*
+**********************************************************************
+* Copyright (C) 1997-2015, International Business Machines
+* Corporation and others. All Rights Reserved.
+**********************************************************************
+*
+* File UMUTEX.H
+*
+* Modification History:
+*
+* Date Name Description
+* 04/02/97 aliu Creation.
+* 04/07/99 srl rewrite - C interface, multiple mutices
+* 05/13/99 stephen Changed to umutex (from cmutex)
+******************************************************************************
+*/
+
+#ifndef UMUTEX_H
+#define UMUTEX_H
+
#include <atomic>
#include <condition_variable>
#include <mutex>
#include <type_traits>
-#include "unicode/utypes.h"
-#include "unicode/uclean.h"
+#include "unicode/utypes.h"
+#include "unicode/uclean.h"
#include "unicode/uobject.h"
-#include "putilimp.h"
-
+#include "putilimp.h"
+
#if defined(U_USER_ATOMICS_H) || defined(U_USER_MUTEX_H)
// Support for including an alternate implementation of atomic & mutex operations has been withdrawn.
// See issue ICU-20185.
#error U_USER_ATOMICS and U_USER_MUTEX_H are not supported
#endif
-
+
// Export an explicit template instantiation of std::atomic<int32_t>.
// When building DLLs for Windows this is required as it is used as a data member of the exported SharedObject class.
// See digitlst.h, pluralaffix.h, datefmt.h, and others for similar examples.
@@ -60,130 +60,130 @@ template struct std::atomic<int32_t>;
template struct std::atomic<std::mutex *>;
#endif
#endif
-
-
-U_NAMESPACE_BEGIN
-
-/****************************************************************************
- *
+
+
+U_NAMESPACE_BEGIN
+
+/****************************************************************************
+ *
* Low Level Atomic Operations, ICU wrappers for.
- *
- ****************************************************************************/
-
-typedef std::atomic<int32_t> u_atomic_int32_t;
-#define ATOMIC_INT32_T_INITIALIZER(val) ATOMIC_VAR_INIT(val)
-
-inline int32_t umtx_loadAcquire(u_atomic_int32_t &var) {
- return var.load(std::memory_order_acquire);
-}
-
-inline void umtx_storeRelease(u_atomic_int32_t &var, int32_t val) {
- var.store(val, std::memory_order_release);
-}
-
-inline int32_t umtx_atomic_inc(u_atomic_int32_t *var) {
- return var->fetch_add(1) + 1;
-}
-
-inline int32_t umtx_atomic_dec(u_atomic_int32_t *var) {
- return var->fetch_sub(1) - 1;
-}
-
-
-/*************************************************************************************************
- *
- * UInitOnce Definitions.
- *
- *************************************************************************************************/
-
-struct UInitOnce {
- u_atomic_int32_t fState;
- UErrorCode fErrCode;
+ *
+ ****************************************************************************/
+
+typedef std::atomic<int32_t> u_atomic_int32_t;
+#define ATOMIC_INT32_T_INITIALIZER(val) ATOMIC_VAR_INIT(val)
+
+inline int32_t umtx_loadAcquire(u_atomic_int32_t &var) {
+ return var.load(std::memory_order_acquire);
+}
+
+inline void umtx_storeRelease(u_atomic_int32_t &var, int32_t val) {
+ var.store(val, std::memory_order_release);
+}
+
+inline int32_t umtx_atomic_inc(u_atomic_int32_t *var) {
+ return var->fetch_add(1) + 1;
+}
+
+inline int32_t umtx_atomic_dec(u_atomic_int32_t *var) {
+ return var->fetch_sub(1) - 1;
+}
+
+
+/*************************************************************************************************
+ *
+ * UInitOnce Definitions.
+ *
+ *************************************************************************************************/
+
+struct UInitOnce {
+ u_atomic_int32_t fState;
+ UErrorCode fErrCode;
void reset() {fState = 0;}
UBool isReset() {return umtx_loadAcquire(fState) == 0;}
-// Note: isReset() is used by service registration code.
-// Thread safety of this usage needs review.
-};
-
-#define U_INITONCE_INITIALIZER {ATOMIC_INT32_T_INITIALIZER(0), U_ZERO_ERROR}
-
-
-U_COMMON_API UBool U_EXPORT2 umtx_initImplPreInit(UInitOnce &);
-U_COMMON_API void U_EXPORT2 umtx_initImplPostInit(UInitOnce &);
-
-template<class T> void umtx_initOnce(UInitOnce &uio, T *obj, void (U_CALLCONV T::*fp)()) {
- if (umtx_loadAcquire(uio.fState) == 2) {
- return;
- }
- if (umtx_initImplPreInit(uio)) {
- (obj->*fp)();
- umtx_initImplPostInit(uio);
- }
-}
-
-
-// umtx_initOnce variant for plain functions, or static class functions.
-// No context parameter.
-inline void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)()) {
- if (umtx_loadAcquire(uio.fState) == 2) {
- return;
- }
- if (umtx_initImplPreInit(uio)) {
- (*fp)();
- umtx_initImplPostInit(uio);
- }
-}
-
-// umtx_initOnce variant for plain functions, or static class functions.
-// With ErrorCode, No context parameter.
-inline void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)(UErrorCode &), UErrorCode &errCode) {
- if (U_FAILURE(errCode)) {
- return;
- }
- if (umtx_loadAcquire(uio.fState) != 2 && umtx_initImplPreInit(uio)) {
- // We run the initialization.
- (*fp)(errCode);
- uio.fErrCode = errCode;
- umtx_initImplPostInit(uio);
- } else {
- // Someone else already ran the initialization.
- if (U_FAILURE(uio.fErrCode)) {
- errCode = uio.fErrCode;
- }
- }
-}
-
-// umtx_initOnce variant for plain functions, or static class functions,
-// with a context parameter.
-template<class T> void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)(T), T context) {
- if (umtx_loadAcquire(uio.fState) == 2) {
- return;
- }
- if (umtx_initImplPreInit(uio)) {
- (*fp)(context);
- umtx_initImplPostInit(uio);
- }
-}
-
-// umtx_initOnce variant for plain functions, or static class functions,
-// with a context parameter and an error code.
-template<class T> void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)(T, UErrorCode &), T context, UErrorCode &errCode) {
- if (U_FAILURE(errCode)) {
- return;
- }
- if (umtx_loadAcquire(uio.fState) != 2 && umtx_initImplPreInit(uio)) {
- // We run the initialization.
- (*fp)(context, errCode);
- uio.fErrCode = errCode;
- umtx_initImplPostInit(uio);
- } else {
- // Someone else already ran the initialization.
- if (U_FAILURE(uio.fErrCode)) {
- errCode = uio.fErrCode;
- }
- }
-}
-
+// Note: isReset() is used by service registration code.
+// Thread safety of this usage needs review.
+};
+
+#define U_INITONCE_INITIALIZER {ATOMIC_INT32_T_INITIALIZER(0), U_ZERO_ERROR}
+
+
+U_COMMON_API UBool U_EXPORT2 umtx_initImplPreInit(UInitOnce &);
+U_COMMON_API void U_EXPORT2 umtx_initImplPostInit(UInitOnce &);
+
+template<class T> void umtx_initOnce(UInitOnce &uio, T *obj, void (U_CALLCONV T::*fp)()) {
+ if (umtx_loadAcquire(uio.fState) == 2) {
+ return;
+ }
+ if (umtx_initImplPreInit(uio)) {
+ (obj->*fp)();
+ umtx_initImplPostInit(uio);
+ }
+}
+
+
+// umtx_initOnce variant for plain functions, or static class functions.
+// No context parameter.
+inline void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)()) {
+ if (umtx_loadAcquire(uio.fState) == 2) {
+ return;
+ }
+ if (umtx_initImplPreInit(uio)) {
+ (*fp)();
+ umtx_initImplPostInit(uio);
+ }
+}
+
+// umtx_initOnce variant for plain functions, or static class functions.
+// With ErrorCode, No context parameter.
+inline void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)(UErrorCode &), UErrorCode &errCode) {
+ if (U_FAILURE(errCode)) {
+ return;
+ }
+ if (umtx_loadAcquire(uio.fState) != 2 && umtx_initImplPreInit(uio)) {
+ // We run the initialization.
+ (*fp)(errCode);
+ uio.fErrCode = errCode;
+ umtx_initImplPostInit(uio);
+ } else {
+ // Someone else already ran the initialization.
+ if (U_FAILURE(uio.fErrCode)) {
+ errCode = uio.fErrCode;
+ }
+ }
+}
+
+// umtx_initOnce variant for plain functions, or static class functions,
+// with a context parameter.
+template<class T> void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)(T), T context) {
+ if (umtx_loadAcquire(uio.fState) == 2) {
+ return;
+ }
+ if (umtx_initImplPreInit(uio)) {
+ (*fp)(context);
+ umtx_initImplPostInit(uio);
+ }
+}
+
+// umtx_initOnce variant for plain functions, or static class functions,
+// with a context parameter and an error code.
+template<class T> void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)(T, UErrorCode &), T context, UErrorCode &errCode) {
+ if (U_FAILURE(errCode)) {
+ return;
+ }
+ if (umtx_loadAcquire(uio.fState) != 2 && umtx_initImplPreInit(uio)) {
+ // We run the initialization.
+ (*fp)(context, errCode);
+ uio.fErrCode = errCode;
+ umtx_initImplPostInit(uio);
+ } else {
+ // Someone else already ran the initialization.
+ if (U_FAILURE(uio.fErrCode)) {
+ errCode = uio.fErrCode;
+ }
+ }
+}
+
// UMutex should be constexpr-constructible, so that no initialization code
// is run during startup.
// This works on all C++ libraries except MS VS before VS2019.
@@ -194,17 +194,17 @@ template<class T> void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)(T, UE
#else
# define UMUTEX_CONSTEXPR constexpr
#endif
-
+
/**
* UMutex - ICU Mutex class.
- *
+ *
* This is the preferred Mutex class for use within ICU implementation code.
* It is a thin wrapper over C++ std::mutex, with these additions:
* - Static instances are safe, not triggering static construction or destruction,
* and the associated order of construction or destruction issues.
* - Plumbed into u_cleanup() for destructing the underlying std::mutex,
* which frees any OS level resources they may be holding.
- *
+ *
* Limitations:
* - Static or global instances only. Cannot be heap allocated. Cannot appear as a
* member of another class.
@@ -218,17 +218,17 @@ template<class T> void umtx_initOnce(UInitOnce &uio, void (U_CALLCONV *fp)(T, UE
* Mutex lock(myMutex);
* ... // Do stuff that is protected by myMutex;
* } // myMutex is released when lock goes out of scope.
- */
-
+ */
+
class U_COMMON_API UMutex {
public:
UMUTEX_CONSTEXPR UMutex() {}
~UMutex() = default;
-
+
UMutex(const UMutex &other) = delete;
UMutex &operator =(const UMutex &other) = delete;
void *operator new(size_t) = delete;
-
+
// requirements for C++ BasicLockable, allows UMutex to work with std::lock_guard
void lock() {
std::mutex *m = fMutex.load(std::memory_order_acquire);
@@ -236,42 +236,42 @@ public:
m->lock();
}
void unlock() { fMutex.load(std::memory_order_relaxed)->unlock(); }
-
+
static void cleanup();
-
+
private:
alignas(std::mutex) char fStorage[sizeof(std::mutex)] {};
std::atomic<std::mutex *> fMutex { nullptr };
-
+
/** All initialized UMutexes are kept in a linked list, so that they can be found,
* and the underlying std::mutex destructed, by u_cleanup().
*/
UMutex *fListLink { nullptr };
static UMutex *gListHead;
-
+
/** Out-of-line function to lazily initialize a UMutex on first use.
* Initial fast check is inline, in lock(). The returned value may never
* be nullptr.
*/
std::mutex *getMutex();
-};
-
-
-/* Lock a mutex.
- * @param mutex The given mutex to be locked. Pass NULL to specify
- * the global ICU mutex. Recursive locks are an error
- * and may cause a deadlock on some platforms.
- */
-U_INTERNAL void U_EXPORT2 umtx_lock(UMutex* mutex);
-
-/* Unlock a mutex.
- * @param mutex The given mutex to be unlocked. Pass NULL to specify
- * the global ICU mutex.
- */
-U_INTERNAL void U_EXPORT2 umtx_unlock (UMutex* mutex);
-
-
+};
+
+
+/* Lock a mutex.
+ * @param mutex The given mutex to be locked. Pass NULL to specify
+ * the global ICU mutex. Recursive locks are an error
+ * and may cause a deadlock on some platforms.
+ */
+U_INTERNAL void U_EXPORT2 umtx_lock(UMutex* mutex);
+
+/* Unlock a mutex.
+ * @param mutex The given mutex to be unlocked. Pass NULL to specify
+ * the global ICU mutex.
+ */
+U_INTERNAL void U_EXPORT2 umtx_unlock (UMutex* mutex);
+
+
U_NAMESPACE_END
-
-#endif /* UMUTEX_H */
-/*eof*/
+
+#endif /* UMUTEX_H */
+/*eof*/