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 |