U_CAPI void U_EXPORT2 u_setAtomicIncDecFunctions(const void *context, UMtxAtomicFn *ip, UMtxAtomicFn *dp, UErrorCode *status) { if (U_FAILURE(*status)) { return; } /* Can not set a mutex function to a NULL value */ if (ip==NULL || dp==NULL) { *status = U_ILLEGAL_ARGUMENT_ERROR; return; } /* If ICU is not in an initial state, disallow this operation. */ if (cmemory_inUse()) { *status = U_INVALID_STATE_ERROR; return; } pIncFn = ip; pDecFn = dp; gIncDecContext = context; #if !U_RELEASE { int32_t testInt = 0; U_ASSERT(umtx_atomic_inc(&testInt) == 1); /* Sanity Check. Do the functions work at all? */ U_ASSERT(testInt == 1); U_ASSERT(umtx_atomic_dec(&testInt) == 0); U_ASSERT(testInt == 0); } #endif }
U_CAPI UPlugLevel U_EXPORT2 uplug_getCurrentLevel() { if(cmemory_inUse()) { return UPLUG_LEVEL_HIGH; } else { return UPLUG_LEVEL_LOW; } }
U_CAPI void U_EXPORT2 u_setMutexFunctions(const void *context, UMtxInitFn *i, UMtxFn *d, UMtxFn *l, UMtxFn *u, UErrorCode *status) { if (U_FAILURE(*status)) { return; } /* Can not set a mutex function to a NULL value */ if (i==NULL || d==NULL || l==NULL || u==NULL) { *status = U_ILLEGAL_ARGUMENT_ERROR; return; } /* If ICU is not in an initial state, disallow this operation. */ if (cmemory_inUse()) { *status = U_INVALID_STATE_ERROR; return; } /* Swap in the mutex function pointers. */ pMutexInitFn = i; pMutexDestroyFn = d; pMutexLockFn = l; pMutexUnlockFn = u; gMutexContext = context; gGlobalMutex = NULL; /* For POSIX, the global mutex will be pre-initialized */ /* Undo that, force re-initialization when u_init() */ /* happens. */ }
U_CAPI void U_EXPORT2 u_setMutexFunctions(const void *context, UMtxInitFn *i, UMtxFn *d, UMtxFn *l, UMtxFn *u, UErrorCode *status) { if (U_FAILURE(*status)) { return; } /* Can not set a mutex function to a NULL value */ if (i==NULL || d==NULL || l==NULL || u==NULL) { *status = U_ILLEGAL_ARGUMENT_ERROR; return; } /* If ICU is not in an initial state, disallow this operation. */ if (cmemory_inUse()) { *status = U_INVALID_STATE_ERROR; return; } // Clean up any previously set user mutex functions. // It's possible to call u_setMutexFunctions() more than once without without explicitly cleaning up, // and the last call should take. Kind of a corner case, but it worked once, there is a test for // it, so we keep it working. The global and impl mutexes will have been created by the // previous u_setMutexFunctions(), and now need to be destroyed. usrMutexCleanup(); /* Swap in the mutex function pointers. */ pMutexInitFn = i; pMutexDestroyFn = d; pMutexLockFn = l; pMutexUnlockFn = u; gMutexContext = context; gMutexListSize = 0; /* Initialize the global and impl mutexes. Safe to do at this point because * u_setMutexFunctions must be done in a single-threaded envioronment. Not thread safe. */ (*pMutexInitFn)(gMutexContext, &globalMutex.fUserMutex, status); globalMutex.fInitialized = TRUE; (*pMutexInitFn)(gMutexContext, &implMutex.fUserMutex, status); implMutex.fInitialized = TRUE; }
U_CAPI void U_EXPORT2 u_setMutexFunctions(const void *context, UMtxInitFn *i, UMtxFn *d, UMtxFn *l, UMtxFn *u, UErrorCode *status) { if (U_FAILURE(*status)) { return; } /* Can not set a mutex function to a NULL value */ if (i==NULL || d==NULL || l==NULL || u==NULL) { *status = U_ILLEGAL_ARGUMENT_ERROR; return; } /* If ICU is not in an initial state, disallow this operation. */ if (cmemory_inUse()) { *status = U_INVALID_STATE_ERROR; return; } /* Kill any existing global mutex. POSIX platforms have a global mutex * even before any other part of ICU is initialized. */ umtx_destroy(&globalUMTX); /* Swap in the mutex function pointers. */ pMutexInitFn = i; pMutexDestroyFn = d; pMutexLockFn = l; pMutexUnlockFn = u; gMutexContext = context; #if defined (POSIX) /* POSIX platforms must have a pre-initialized global mutex * to allow other mutexes to initialize safely. */ umtx_init(&globalUMTX); #endif }