- } else /* haveInstance==0 */ {
- void *instance=instantiator(context, errorCode);
- Mutex mutex;
- if(fHaveInstance==0) {
- if(U_SUCCESS(errorCode)) {
- fInstance=instance;
- instance=NULL;
- fHaveInstance=1;
- } else {
- fErrorCode=errorCode;
- fHaveInstance=-1;
- }
- } else {
- errorCode=fErrorCode;
- }
+ }
+
+ // First attempt to create the instance.
+ // If a race occurs, then the losing thread will assign its new instance
+ // to the "duplicate" parameter, and the caller deletes it.
+ instance=instantiator(context, errorCode);
+ UMTX_RELEASE_BARRIER; // Release-barrier before fInstance=instance;
+ Mutex mutex;
+ if(fInstance==NULL && U_SUCCESS(errorCode)) {
+ // instance creation newly succeeded
+ U_ASSERT(instance!=NULL);
+ ANNOTATE_HAPPENS_BEFORE(&fInstance);
+ // TODO: With atomicops.h: Release_Store(&fInstance, (AtomicWord)instance);
+ // and remove UMTX_RELEASE_BARRIER above.
+ fInstance=instance;
+ // Set fErrorCode on the off-chance that a previous instance creation failed.
+ fErrorCode=errorCode;
+ // Completed state transition: initial->succeeded, or failed->succeeded.
+ } else {
+ // Record a duplicate if we lost the race, or
+ // if we got an instance but its creation failed anyway.