From 0ed665951e53a5e9d07c207064c117fae6e9d20f Mon Sep 17 00:00:00 2001 From: "philip.liard@gmail.com" Date: Mon, 17 Jun 2013 11:53:01 +0000 Subject: [PATCH] CPP: Add suport for thread-safety on Linux and Mac in non-Boost base/. This is needed for Chrome on Android which is the only Chrome port that requires thread-safety. R=lararennie@google.com Review URL: https://codereview.appspot.com/10244046 git-svn-id: http://libphonenumber.googlecode.com/svn/trunk@583 ee073f10-1060-11df-b6a4-87a95322a99c --- cpp/README | 6 ++- cpp/src/phonenumbers/base/memory/singleton.h | 21 +++++--- cpp/src/phonenumbers/base/memory/singleton_posix.h | 53 ++++++++++++++++++ cpp/src/phonenumbers/base/synchronization/lock.h | 33 +++++++++--- .../phonenumbers/base/synchronization/lock_posix.h | 63 ++++++++++++++++++++++ cpp/src/phonenumbers/base/thread_checker.h | 3 +- 6 files changed, 165 insertions(+), 14 deletions(-) create mode 100644 cpp/src/phonenumbers/base/memory/singleton_posix.h create mode 100644 cpp/src/phonenumbers/base/synchronization/lock_posix.h diff --git a/cpp/README b/cpp/README index 99e0a5c..45412a8 100644 --- a/cpp/README +++ b/cpp/README @@ -235,7 +235,11 @@ Supported build parameters USE_ALTERNATE_FORMATS = ON | OFF [ON] -- Use alternate formats for the phone number matcher. USE_BOOST = ON | OFF [ON] -- Use Boost. This is only needed in - multi-threaded environments. + multi-threaded environments that + are not Linux and Mac. + Libphonenumber relies on Boost for + non-POSIX (e.g. Windows) + multi-threading. USE_ICU_REGEXP = ON | OFF [ON] -- Use ICU regexp engine. USE_LITE_METADATA = ON | OFF [OFF] -- Generates smaller metadata that doesn't include example numbers. diff --git a/cpp/src/phonenumbers/base/memory/singleton.h b/cpp/src/phonenumbers/base/memory/singleton.h index 38b4bfc..5fd3e4c 100644 --- a/cpp/src/phonenumbers/base/memory/singleton.h +++ b/cpp/src/phonenumbers/base/memory/singleton.h @@ -14,8 +14,8 @@ // Author: Philippe Liard -#ifndef I18N_PHONENUMBERS_BASE_SINGLETON_H_ -#define I18N_PHONENUMBERS_BASE_SINGLETON_H_ +#ifndef I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_H_ +#define I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_H_ #if defined(I18N_PHONENUMBERS_USE_BOOST) @@ -48,16 +48,22 @@ class Singleton : private boost::noncopyable { template boost::scoped_ptr Singleton::instance; template boost::once_flag Singleton::flag = BOOST_ONCE_INIT; +} // namespace phonenumbers +} // namespace i18n + #else // !I18N_PHONENUMBERS_USE_BOOST #include "phonenumbers/base/logging.h" #include "phonenumbers/base/thread_checker.h" +#if !defined(__linux__) && !defined(__APPLE__) + namespace i18n { namespace phonenumbers { // Note that this implementation is not thread-safe. For a thread-safe -// implementation, please compile with -DI18N_PHONENUMBERS_USE_BOOST. +// implementation on non-POSIX platforms, please compile with +// -DI18N_PHONENUMBERS_USE_BOOST. template class Singleton { public: @@ -78,9 +84,12 @@ class Singleton { const ThreadChecker thread_checker_; }; -#endif // !I18N_PHONENUMBERS_USE_BOOST - } // namespace phonenumbers } // namespace i18n -#endif // I18N_PHONENUMBERS_BASE_SINGLETON_H_ +#else +#include "phonenumbers/base/memory/singleton_posix.h" +#endif // !defined(__linux__) && !defined(__APPLE__) + +#endif // !I18N_PHONENUMBERS_USE_BOOST +#endif // I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_H_ diff --git a/cpp/src/phonenumbers/base/memory/singleton_posix.h b/cpp/src/phonenumbers/base/memory/singleton_posix.h new file mode 100644 index 0000000..52cd04d --- /dev/null +++ b/cpp/src/phonenumbers/base/memory/singleton_posix.h @@ -0,0 +1,53 @@ +// Copyright (C) 2013 The Libphonenumber Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_POSIX_H_ +#define I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_POSIX_H_ + +#include + +#include "phonenumbers/base/logging.h" + +namespace i18n { +namespace phonenumbers { + +template +class Singleton { + public: + virtual ~Singleton() {} + + static T* GetInstance() { + const int ret = pthread_once(&once_control_, &Init); + (void) ret; + DCHECK_EQ(0, ret); + return instance_; + } + + private: + static void Init() { + instance_ = new T(); + } + + static T* instance_; // Leaky singleton. + static pthread_once_t once_control_; +}; + +template T* Singleton::instance_; +template pthread_once_t Singleton::once_control_ = + PTHREAD_ONCE_INIT; + +} // namespace phonenumbers +} // namespace i18n + +#endif // I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_POSIX_H_ diff --git a/cpp/src/phonenumbers/base/synchronization/lock.h b/cpp/src/phonenumbers/base/synchronization/lock.h index 7ef136c..63eab24 100644 --- a/cpp/src/phonenumbers/base/synchronization/lock.h +++ b/cpp/src/phonenumbers/base/synchronization/lock.h @@ -34,11 +34,14 @@ typedef boost::mutex::scoped_lock AutoLock; #include "phonenumbers/base/logging.h" #include "phonenumbers/base/thread_checker.h" +// Dummy lock implementation on non-POSIX platforms. If you are running on a +// different platform and care about thread-safety, please compile with +// -DI18N_PHONENUMBERS_USE_BOOST. +#if !defined(__linux__) && !defined(__APPLE__) + namespace i18n { namespace phonenumbers { -// Dummy lock implementation. If you care about thread-safety, please compile -// with -DI18N_PHONENUMBERS_USE_BOOST. class Lock { public: Lock() : thread_checker_() {} @@ -47,18 +50,36 @@ class Lock { DCHECK(thread_checker_.CalledOnValidThread()); } - // No need for Release() since Acquire() is a no-op and Release() is not used - // in the codebase. + void Release() const { + DCHECK(thread_checker_.CalledOnValidThread()); + } private: const ThreadChecker thread_checker_; }; +} // namespace phonenumbers +} // namespace i18n + +#else +#include "phonenumbers/base/synchronization/lock_posix.h" +#endif + +namespace i18n { +namespace phonenumbers { + class AutoLock { public: - AutoLock(Lock& lock) { - lock.Acquire(); + AutoLock(Lock& lock) : lock_(lock) { + lock_.Acquire(); } + + ~AutoLock() { + lock_.Release(); + } + + private: + Lock& lock_; }; } // namespace phonenumbers diff --git a/cpp/src/phonenumbers/base/synchronization/lock_posix.h b/cpp/src/phonenumbers/base/synchronization/lock_posix.h new file mode 100644 index 0000000..8ef1a95 --- /dev/null +++ b/cpp/src/phonenumbers/base/synchronization/lock_posix.h @@ -0,0 +1,63 @@ +// Copyright (C) 2013 The Libphonenumber Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Author: Philippe Liard + +#ifndef I18N_PHONENUMBERS_BASE_SYNCHRONIZATION_LOCK_POSIX_H_ +#define I18N_PHONENUMBERS_BASE_SYNCHRONIZATION_LOCK_POSIX_H_ + +#include + +#include "phonenumbers/base/basictypes.h" +#include "phonenumbers/base/logging.h" + +namespace i18n { +namespace phonenumbers { + +class Lock { + public: + Lock() { + const int ret = pthread_mutex_init(&mutex_, NULL); + (void) ret; + DCHECK_EQ(0, ret); + } + + ~Lock() { + const int ret = pthread_mutex_destroy(&mutex_); + (void) ret; + DCHECK_EQ(0, ret); + } + + void Acquire() const { + int ret = pthread_mutex_lock(&mutex_); + (void) ret; + DCHECK_EQ(0, ret); + } + + void Release() const { + int ret = pthread_mutex_unlock(&mutex_); + (void) ret; + DCHECK_EQ(0, ret); + } + + private: + DISALLOW_COPY_AND_ASSIGN(Lock); + + mutable pthread_mutex_t mutex_; +}; + +} // namespace phonenumbers +} // namespace i18n + +#endif // I18N_PHONENUMBERS_BASE_SYNCHRONIZATION_LOCK_POSIX_H_ diff --git a/cpp/src/phonenumbers/base/thread_checker.h b/cpp/src/phonenumbers/base/thread_checker.h index bac8048..b7a3523 100644 --- a/cpp/src/phonenumbers/base/thread_checker.h +++ b/cpp/src/phonenumbers/base/thread_checker.h @@ -22,7 +22,8 @@ // Note that I18N_PHONENUMBERS_NO_THREAD_SAFETY must be defined only to let the // user of the library know that it can't be used in a thread-safe manner when // it is not depending on Boost. -#if !defined(I18N_PHONENUMBERS_NO_THREAD_SAFETY) +#if !defined(__linux__) && !defined(__APPLE__) && \ + !defined(I18N_PHONENUMBERS_NO_THREAD_SAFETY) #error Building without Boost, please provide \ -DI18N_PHONENUMBERS_NO_THREAD_SAFETY #endif -- 2.7.4