Chromium Code Reviews| Index: src/lazy-instance.h | 
| diff --git a/src/lazy-instance.h b/src/lazy-instance.h | 
| index 09dfe2154dc2992305a0b04787d8c3cca3391193..95258f3f70c46438786a63d95e0a3b2717d2cb66 100644 | 
| --- a/src/lazy-instance.h | 
| +++ b/src/lazy-instance.h | 
| @@ -151,9 +151,32 @@ struct DefaultCreateTrait { | 
| }; | 
| +template <typename T> | 
| +struct ThreadSafeInitOnceTrait { | 
| + template <typename Function, typename Storage> | 
| + static void Init(OnceType* once, Function function, Storage storage) { | 
| + CallOnce(once, function, storage); | 
| + } | 
| +}; | 
| + | 
| + | 
| +// Initialization trait for users who don't care about thread-safety. | 
| +template <typename T> | 
| +struct SingleThreadInitOnceTrait { | 
| + template <typename Function, typename Storage> | 
| + static void Init(OnceType* once, Function function, Storage storage) { | 
| + if (*once == ONCE_STATE_UNINITIALIZED) { | 
| + function(storage); | 
| + *once = ONCE_STATE_DONE; | 
| + } | 
| + } | 
| +}; | 
| + | 
| + | 
| // TODO(pliard): Handle instances destruction (using global destructors). | 
| template <typename T, typename AllocationTrait, typename CreateTrait, | 
| - typename DestroyTrait /* not used yet. */ > | 
| + template <class> class InitOnceTrait, | 
| + typename DestroyTrait /* not used yet. */> | 
| struct LazyInstanceImpl { | 
| public: | 
| typedef typename AllocationTrait::StorageType StorageType; | 
| @@ -164,7 +187,12 @@ struct LazyInstanceImpl { | 
| } | 
| void Init() const { | 
| - CallOnce(&once_, &InitInstance, &storage_); | 
| + InitOnceTrait<T>::Init( | 
| + &once_, | 
| + // Casts to void* are needed here to avoid breaking strict aliasing | 
| + // rules. | 
| + reinterpret_cast<void (*)(void*)>(&InitInstance), | 
| + reinterpret_cast<void*>(&storage_)); | 
| } | 
| public: | 
| @@ -187,28 +215,32 @@ struct LazyInstanceImpl { | 
| template <typename T, | 
| typename CreateTrait = DefaultConstructTrait<T>, | 
| + template <class> class InitOnceTrait = ThreadSafeInitOnceTrait, | 
| 
 
danno
2012/03/29 07:45:17
how about changing the default to SingleThreadInit
 
Philippe
2012/03/29 09:00:48
Right. I was just concerned about the potential ri
 
 | 
| typename DestroyTrait = LeakyInstanceTrait<T> > | 
| struct LazyStaticInstance { | 
| - typedef LazyInstanceImpl<T, StaticallyAllocatedInstanceTrait<T>, CreateTrait, | 
| - DestroyTrait> type; | 
| + typedef LazyInstanceImpl<T, StaticallyAllocatedInstanceTrait<T>, | 
| + CreateTrait, InitOnceTrait, DestroyTrait> type; | 
| }; | 
| template <typename T, | 
| typename CreateTrait = DefaultConstructTrait<T>, | 
| + template <class> class InitOnceTrait = ThreadSafeInitOnceTrait, | 
| 
 
danno
2012/03/29 07:45:17
Here too
 
Philippe
2012/03/29 09:00:48
Done.
 
 | 
| typename DestroyTrait = LeakyInstanceTrait<T> > | 
| struct LazyInstance { | 
| // A LazyInstance is a LazyStaticInstance. | 
| - typedef typename LazyStaticInstance<T, CreateTrait, DestroyTrait>::type type; | 
| + typedef typename LazyStaticInstance<T, CreateTrait, InitOnceTrait, | 
| + DestroyTrait>::type type; | 
| }; | 
| template <typename T, | 
| typename CreateTrait = DefaultConstructTrait<T>, | 
| + template <class> class InitOnceTrait = ThreadSafeInitOnceTrait, | 
| 
 
danno
2012/03/29 07:45:17
Here too
 
Philippe
2012/03/29 09:00:48
Done.
 
 | 
| typename DestroyTrait = LeakyInstanceTrait<T> > | 
| struct LazyDynamicInstance { | 
| - typedef LazyInstanceImpl<T, DynamicallyAllocatedInstanceTrait<T>, CreateTrait, | 
| - DestroyTrait> type; | 
| + typedef LazyInstanceImpl<T, DynamicallyAllocatedInstanceTrait<T>, | 
| + CreateTrait, InitOnceTrait, DestroyTrait> type; | 
| }; | 
| } } // namespace v8::internal |