Do not create an extra default instance of T when constructing a ThreadLocal<T>.
This commit is contained in:
@@ -1838,8 +1838,9 @@ class ThreadWithParam : public ThreadWithParamBase {
|
||||
template <typename T>
|
||||
class ThreadLocal : public ThreadLocalBase {
|
||||
public:
|
||||
ThreadLocal() : default_() {}
|
||||
explicit ThreadLocal(const T& value) : default_(value) {}
|
||||
ThreadLocal() : default_factory_(new DefaultValueHolderFactory()) {}
|
||||
explicit ThreadLocal(const T& value)
|
||||
: default_factory_(new InstanceValueHolderFactory(value)) {}
|
||||
|
||||
~ThreadLocal() { ThreadLocalRegistry::OnThreadLocalDestroyed(this); }
|
||||
|
||||
@@ -1853,6 +1854,7 @@ class ThreadLocal : public ThreadLocalBase {
|
||||
// knowing the type of T.
|
||||
class ValueHolder : public ThreadLocalValueHolderBase {
|
||||
public:
|
||||
ValueHolder() : value_() {}
|
||||
explicit ValueHolder(const T& value) : value_(value) {}
|
||||
|
||||
T* pointer() { return &value_; }
|
||||
@@ -1869,10 +1871,42 @@ class ThreadLocal : public ThreadLocalBase {
|
||||
}
|
||||
|
||||
virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const {
|
||||
return new ValueHolder(default_);
|
||||
return default_factory_->MakeNewHolder();
|
||||
}
|
||||
|
||||
const T default_; // The default value for each thread.
|
||||
class ValueHolderFactory {
|
||||
public:
|
||||
ValueHolderFactory() {}
|
||||
virtual ~ValueHolderFactory() {}
|
||||
virtual ValueHolder* MakeNewHolder() const = 0;
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolderFactory);
|
||||
};
|
||||
|
||||
class DefaultValueHolderFactory : public ValueHolderFactory {
|
||||
public:
|
||||
DefaultValueHolderFactory() {}
|
||||
virtual ValueHolder* MakeNewHolder() const { return new ValueHolder(); }
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory);
|
||||
};
|
||||
|
||||
class InstanceValueHolderFactory : public ValueHolderFactory {
|
||||
public:
|
||||
explicit InstanceValueHolderFactory(const T& value) : value_(value) {}
|
||||
virtual ValueHolder* MakeNewHolder() const {
|
||||
return new ValueHolder(value_);
|
||||
}
|
||||
|
||||
private:
|
||||
const T value_; // The value for each thread.
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(InstanceValueHolderFactory);
|
||||
};
|
||||
|
||||
scoped_ptr<ValueHolderFactory> default_factory_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
|
||||
};
|
||||
@@ -1993,10 +2027,11 @@ extern "C" inline void DeleteThreadLocalValue(void* value_holder) {
|
||||
template <typename T>
|
||||
class ThreadLocal {
|
||||
public:
|
||||
ThreadLocal() : key_(CreateKey()),
|
||||
default_() {}
|
||||
explicit ThreadLocal(const T& value) : key_(CreateKey()),
|
||||
default_(value) {}
|
||||
ThreadLocal()
|
||||
: key_(CreateKey()), default_factory_(new DefaultValueHolderFactory()) {}
|
||||
explicit ThreadLocal(const T& value)
|
||||
: key_(CreateKey()),
|
||||
default_factory_(new InstanceValueHolderFactory(value)) {}
|
||||
|
||||
~ThreadLocal() {
|
||||
// Destroys the managed object for the current thread, if any.
|
||||
@@ -2016,6 +2051,7 @@ class ThreadLocal {
|
||||
// Holds a value of type T.
|
||||
class ValueHolder : public ThreadLocalValueHolderBase {
|
||||
public:
|
||||
ValueHolder() : value_() {}
|
||||
explicit ValueHolder(const T& value) : value_(value) {}
|
||||
|
||||
T* pointer() { return &value_; }
|
||||
@@ -2041,15 +2077,47 @@ class ThreadLocal {
|
||||
return CheckedDowncastToActualType<ValueHolder>(holder)->pointer();
|
||||
}
|
||||
|
||||
ValueHolder* const new_holder = new ValueHolder(default_);
|
||||
ValueHolder* const new_holder = default_factory_->MakeNewHolder();
|
||||
ThreadLocalValueHolderBase* const holder_base = new_holder;
|
||||
GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base));
|
||||
return new_holder->pointer();
|
||||
}
|
||||
|
||||
class ValueHolderFactory {
|
||||
public:
|
||||
ValueHolderFactory() {}
|
||||
virtual ~ValueHolderFactory() {}
|
||||
virtual ValueHolder* MakeNewHolder() const = 0;
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolderFactory);
|
||||
};
|
||||
|
||||
class DefaultValueHolderFactory : public ValueHolderFactory {
|
||||
public:
|
||||
DefaultValueHolderFactory() {}
|
||||
virtual ValueHolder* MakeNewHolder() const { return new ValueHolder(); }
|
||||
|
||||
private:
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory);
|
||||
};
|
||||
|
||||
class InstanceValueHolderFactory : public ValueHolderFactory {
|
||||
public:
|
||||
explicit InstanceValueHolderFactory(const T& value) : value_(value) {}
|
||||
virtual ValueHolder* MakeNewHolder() const {
|
||||
return new ValueHolder(value_);
|
||||
}
|
||||
|
||||
private:
|
||||
const T value_; // The value for each thread.
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(InstanceValueHolderFactory);
|
||||
};
|
||||
|
||||
// A key pthreads uses for looking up per-thread values.
|
||||
const pthread_key_t key_;
|
||||
const T default_; // The default value for each thread.
|
||||
scoped_ptr<ValueHolderFactory> default_factory_;
|
||||
|
||||
GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user