| Index: third_party/libphonenumber/cpp/src/base/threading/thread_local.h
|
| ===================================================================
|
| --- third_party/libphonenumber/cpp/src/base/threading/thread_local.h (revision 0)
|
| +++ third_party/libphonenumber/cpp/src/base/threading/thread_local.h (revision 0)
|
| @@ -0,0 +1,127 @@
|
| +// Copyright (c) 2010 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +// WARNING: Thread local storage is a bit tricky to get right. Please make
|
| +// sure that this is really the proper solution for what you're trying to
|
| +// achieve. Don't prematurely optimize, most likely you can just use a Lock.
|
| +//
|
| +// These classes implement a wrapper around the platform's TLS storage
|
| +// mechanism. On construction, they will allocate a TLS slot, and free the
|
| +// TLS slot on destruction. No memory management (creation or destruction) is
|
| +// handled. This means for uses of ThreadLocalPointer, you must correctly
|
| +// manage the memory yourself, these classes will not destroy the pointer for
|
| +// you. There are no at-thread-exit actions taken by these classes.
|
| +//
|
| +// ThreadLocalPointer<Type> wraps a Type*. It performs no creation or
|
| +// destruction, so memory management must be handled elsewhere. The first call
|
| +// to Get() on a thread will return NULL. You can update the pointer with a
|
| +// call to Set().
|
| +//
|
| +// ThreadLocalBoolean wraps a bool. It will default to false if it has never
|
| +// been set otherwise with Set().
|
| +//
|
| +// Thread Safety: An instance of ThreadLocalStorage is completely thread safe
|
| +// once it has been created. If you want to dynamically create an instance,
|
| +// you must of course properly deal with safety and race conditions. This
|
| +// means a function-level static initializer is generally inappropiate.
|
| +//
|
| +// Example usage:
|
| +// // My class is logically attached to a single thread. We cache a pointer
|
| +// // on the thread it was created on, so we can implement current().
|
| +// MyClass::MyClass() {
|
| +// DCHECK(Singleton<ThreadLocalPointer<MyClass> >::get()->Get() == NULL);
|
| +// Singleton<ThreadLocalPointer<MyClass> >::get()->Set(this);
|
| +// }
|
| +//
|
| +// MyClass::~MyClass() {
|
| +// DCHECK(Singleton<ThreadLocalPointer<MyClass> >::get()->Get() != NULL);
|
| +// Singleton<ThreadLocalPointer<MyClass> >::get()->Set(NULL);
|
| +// }
|
| +//
|
| +// // Return the current MyClass associated with the calling thread, can be
|
| +// // NULL if there isn't a MyClass associated.
|
| +// MyClass* MyClass::current() {
|
| +// return Singleton<ThreadLocalPointer<MyClass> >::get()->Get();
|
| +// }
|
| +
|
| +#ifndef BASE_THREADING_THREAD_LOCAL_H_
|
| +#define BASE_THREADING_THREAD_LOCAL_H_
|
| +#pragma once
|
| +
|
| +#include "base/basictypes.h"
|
| +
|
| +#if defined(OS_POSIX)
|
| +#include <pthread.h>
|
| +#endif
|
| +
|
| +namespace base {
|
| +
|
| +namespace internal {
|
| +
|
| +// Helper functions that abstract the cross-platform APIs. Do not use directly.
|
| +struct ThreadLocalPlatform {
|
| +#if defined(OS_WIN)
|
| + typedef unsigned long SlotType;
|
| +#elif defined(OS_POSIX)
|
| + typedef pthread_key_t SlotType;
|
| +#endif
|
| +
|
| + static void AllocateSlot(SlotType& slot);
|
| + static void FreeSlot(SlotType& slot);
|
| + static void* GetValueFromSlot(SlotType& slot);
|
| + static void SetValueInSlot(SlotType& slot, void* value);
|
| +};
|
| +
|
| +} // namespace internal
|
| +
|
| +template <typename Type>
|
| +class ThreadLocalPointer {
|
| + public:
|
| + ThreadLocalPointer() : slot_() {
|
| + internal::ThreadLocalPlatform::AllocateSlot(slot_);
|
| + }
|
| +
|
| + ~ThreadLocalPointer() {
|
| + internal::ThreadLocalPlatform::FreeSlot(slot_);
|
| + }
|
| +
|
| + Type* Get() {
|
| + return static_cast<Type*>(
|
| + internal::ThreadLocalPlatform::GetValueFromSlot(slot_));
|
| + }
|
| +
|
| + void Set(Type* ptr) {
|
| + internal::ThreadLocalPlatform::SetValueInSlot(slot_, ptr);
|
| + }
|
| +
|
| + private:
|
| + typedef internal::ThreadLocalPlatform::SlotType SlotType;
|
| +
|
| + SlotType slot_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ThreadLocalPointer<Type>);
|
| +};
|
| +
|
| +class ThreadLocalBoolean {
|
| + public:
|
| + ThreadLocalBoolean() { }
|
| + ~ThreadLocalBoolean() { }
|
| +
|
| + bool Get() {
|
| + return tlp_.Get() != NULL;
|
| + }
|
| +
|
| + void Set(bool val) {
|
| + tlp_.Set(reinterpret_cast<void*>(val ? 1 : 0));
|
| + }
|
| +
|
| + private:
|
| + ThreadLocalPointer<void> tlp_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(ThreadLocalBoolean);
|
| +};
|
| +
|
| +} // namespace base
|
| +
|
| +#endif // BASE_THREADING_THREAD_LOCAL_H_
|
|
|
| Property changes on: third_party\libphonenumber\cpp\src\base\threading\thread_local.h
|
| ___________________________________________________________________
|
| Added: svn:eol-style
|
| + LF
|
|
|
|
|