sl@0: /* sl@0: ********************************************************************** sl@0: * Copyright (C) 1997-2005, International Business Machines sl@0: * Corporation and others. All Rights Reserved. sl@0: ********************************************************************** sl@0: * sl@0: * File UMUTEX.H sl@0: * sl@0: * Modification History: sl@0: * sl@0: * Date Name Description sl@0: * 04/02/97 aliu Creation. sl@0: * 04/07/99 srl rewrite - C interface, multiple mutices sl@0: * 05/13/99 stephen Changed to umutex (from cmutex) sl@0: ****************************************************************************** sl@0: */ sl@0: sl@0: #ifndef UMUTEX_H sl@0: #define UMUTEX_H sl@0: sl@0: #include "unicode/utypes.h" sl@0: #include "unicode/uclean.h" sl@0: sl@0: sl@0: /* APP_NO_THREADS is an old symbol. We'll honour it if present. */ sl@0: #ifdef APP_NO_THREADS sl@0: # define ICU_USE_THREADS 0 sl@0: #endif sl@0: sl@0: /* ICU_USE_THREADS sl@0: * sl@0: * Allows thread support (use of mutexes) to be compiled out of ICU. sl@0: * Default: use threads. sl@0: * Even with thread support compiled out, applications may override the sl@0: * (empty) mutex implementation with the u_setMutexFunctions() functions. sl@0: */ sl@0: #ifndef ICU_USE_THREADS sl@0: # define ICU_USE_THREADS 1 sl@0: #endif sl@0: sl@0: /** sl@0: * By default assume that we are on a machine with a weak memory model, sl@0: * and the double check lock won't work reliably. sl@0: */ sl@0: #if !defined(UMTX_STRONG_MEMORY_MODEL) sl@0: #define UMTX_STRONG_MEMORY_MODEL 0 sl@0: #endif sl@0: sl@0: /** sl@0: * \def UMTX_CHECK sl@0: * Encapsulates a safe check for an expression (usually a condition) sl@0: * for lazy variable inititialization. sl@0: * On CPUs with weak memory models, this must use memory fence instructions sl@0: * or mutexes. sl@0: * @internal sl@0: */ sl@0: #if UMTX_STRONG_MEMORY_MODEL sl@0: sl@0: #define UMTX_CHECK(pMutex, expression, result) \ sl@0: (result)=(expression); sl@0: sl@0: #else sl@0: sl@0: #define UMTX_CHECK(pMutex, expression, result) \ sl@0: umtx_lock(pMutex); \ sl@0: (result)=(expression); \ sl@0: umtx_unlock(pMutex); sl@0: sl@0: #endif sl@0: sl@0: /* sl@0: * Code within ICU that accesses shared static or global data should sl@0: * instantiate a Mutex object while doing so. The unnamed global mutex sl@0: * is used throughout ICU, so keep locking short and sweet. sl@0: * sl@0: * For example: sl@0: * sl@0: * void Function(int arg1, int arg2) sl@0: * { sl@0: * static Object* foo; // Shared read-write object sl@0: * umtx_lock(NULL); // Lock the ICU global mutex sl@0: * foo->Method(); sl@0: * umtx_unlock(NULL); sl@0: * } sl@0: * sl@0: * an alternative C++ mutex API is defined in the file common/mutex.h sl@0: */ sl@0: sl@0: /* Lock a mutex. sl@0: * @param mutex The given mutex to be locked. Pass NULL to specify sl@0: * the global ICU mutex. Recursive locks are an error sl@0: * and may cause a deadlock on some platforms. sl@0: */ sl@0: U_CAPI void U_EXPORT2 umtx_lock ( UMTX* mutex ); sl@0: sl@0: /* Unlock a mutex. Pass in NULL if you want the single global sl@0: mutex. sl@0: * @param mutex The given mutex to be unlocked. Pass NULL to specify sl@0: * the global ICU mutex. sl@0: */ sl@0: U_CAPI void U_EXPORT2 umtx_unlock ( UMTX* mutex ); sl@0: sl@0: /* Initialize a mutex. Use it this way: sl@0: umtx_init( &aMutex ); sl@0: * ICU Mutexes do not need explicit initialization before use. Use of this sl@0: * function is not necessary. sl@0: * Initialization of an already initialized mutex has no effect, and is safe to do. sl@0: * Initialization of mutexes is thread safe. Two threads can concurrently sl@0: * initialize the same mutex without causing problems. sl@0: * @param mutex The given mutex to be initialized sl@0: */ sl@0: U_CAPI void U_EXPORT2 umtx_init ( UMTX* mutex ); sl@0: sl@0: /* Destroy a mutex. This will free the resources of a mutex. sl@0: * Use it this way: sl@0: * umtx_destroy( &aMutex ); sl@0: * Destroying an already destroyed mutex has no effect, and causes no problems. sl@0: * This function is not thread safe. Two threads must not attempt to concurrently sl@0: * destroy the same mutex. sl@0: * @param mutex The given mutex to be destroyed. sl@0: */ sl@0: U_CAPI void U_EXPORT2 umtx_destroy( UMTX *mutex ); sl@0: sl@0: sl@0: sl@0: /* sl@0: * Atomic Increment and Decrement of an int32_t value. sl@0: * sl@0: * Return Values: sl@0: * If the result of the operation is zero, the return zero. sl@0: * If the result of the operation is not zero, the sign of returned value sl@0: * is the same as the sign of the result, but the returned value itself may sl@0: * be different from the result of the operation. sl@0: */ sl@0: U_CAPI int32_t U_EXPORT2 umtx_atomic_inc(int32_t *); sl@0: U_CAPI int32_t U_EXPORT2 umtx_atomic_dec(int32_t *); sl@0: sl@0: sl@0: #endif /*_CMUTEX*/ sl@0: /*eof*/ sl@0: sl@0: sl@0: