// © 2016 and later: Unicode, Inc. and others. // License & terms of use: http://www.unicode.org/copyright.html /* ****************************************************************************** * * Copyright (C) 1997-2016, International Business Machines * Corporation and others. All Rights Reserved. * ****************************************************************************** * * File umutex.cpp * * Modification History: * * Date Name Description * 04/02/97 aliu Creation. * 04/07/99 srl updated * 05/13/99 stephen Changed to umutex (from cmutex). * 11/22/99 aliu Make non-global mutex autoinitialize [j151] ****************************************************************************** */ #include "umutex.h" #include "unicode/utypes.h" #include "uassert.h" #include "ucln_cmn.h" #include "cmemory.h" U_NAMESPACE_BEGIN #if defined(U_USER_MUTEX_CPP) // Support for including an alternate implementation of mutexes has been withdrawn. // See issue ICU-20185. #error U_USER_MUTEX_CPP not supported #endif /************************************************************************************************* * * ICU Mutex wrappers. * *************************************************************************************************/ namespace { std::mutex *initMutex; std::condition_variable *initCondition; // The ICU global mutex. // Used when ICU implementation code passes nullptr for the mutex pointer. UMutex globalMutex; std::once_flag initFlag; std::once_flag *pInitFlag = …; } // Anonymous namespace U_CDECL_BEGIN static UBool U_CALLCONV umtx_cleanup() { … } static void U_CALLCONV umtx_init() { … } U_CDECL_END std::mutex *UMutex::getMutex() { … } UMutex *UMutex::gListHead = …; void UMutex::cleanup() { … } U_CAPI void U_EXPORT2 umtx_lock(UMutex *mutex) { … } U_CAPI void U_EXPORT2 umtx_unlock(UMutex* mutex) { … } /************************************************************************************************* * * UInitOnce Implementation * *************************************************************************************************/ // This function is called when a test of a UInitOnce::fState reveals that // initialization has not completed, that we either need to call the init // function on this thread, or wait for some other thread to complete. // // The actual call to the init function is made inline by template code // that knows the C++ types involved. This function returns true if // the caller needs to call the Init function. // U_COMMON_API UBool U_EXPORT2 umtx_initImplPreInit(UInitOnce &uio) { … } // This function is called by the thread that ran an initialization function, // just after completing the function. // Some threads may be waiting on the condition, requiring the broadcast wakeup. // Some threads may be racing to test the fState variable outside of the mutex, // requiring the use of store/release when changing its value. U_COMMON_API void U_EXPORT2 umtx_initImplPostInit(UInitOnce &uio) { … } U_NAMESPACE_END /************************************************************************************************* * * Deprecated functions for setting user mutexes. * *************************************************************************************************/ U_DEPRECATED void U_EXPORT2 u_setMutexFunctions(const void * /*context */, UMtxInitFn *, UMtxFn *, UMtxFn *, UMtxFn *, UErrorCode *status) { … } U_DEPRECATED void U_EXPORT2 u_setAtomicIncDecFunctions(const void * /*context */, UMtxAtomicFn *, UMtxAtomicFn *, UErrorCode *status) { … }