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 |