From d853a61a3568d8964d2a5abb594ebbfa1ccc79d2 Mon Sep 17 00:00:00 2001 From: Gilles Vollant Date: Sun, 6 Oct 2019 01:58:00 +0200 Subject: [PATCH] support of singleton and lock for win32 and c++ 11 Include modification from Dominic Battre --- cpp/CMakeLists.txt | 39 ++++++++- cpp/README | 20 +++-- cpp/src/phonenumbers/asyoutypeformatter.cc | 8 +- cpp/src/phonenumbers/base/memory/singleton.h | 82 +++--------------- .../base/memory/singleton_boost.h | 51 ++++++++++++ .../base/memory/singleton_stdmutex.h | 62 ++++++++++++++ .../base/memory/singleton_unsafe.h | 49 +++++++++++ .../base/memory/singleton_win32.h | 69 +++++++++++++++ .../phonenumbers/base/synchronization/lock.h | 83 +++---------------- .../base/synchronization/lock_boost.h | 31 +++++++ .../base/synchronization/lock_stdmutex.h | 47 +++++++++++ .../base/synchronization/lock_unsafe.h | 51 ++++++++++++ .../base/synchronization/lock_win32.h | 54 ++++++++++++ cpp/src/phonenumbers/base/thread_checker.h | 8 +- 14 files changed, 495 insertions(+), 159 deletions(-) create mode 100644 cpp/src/phonenumbers/base/memory/singleton_boost.h create mode 100644 cpp/src/phonenumbers/base/memory/singleton_stdmutex.h create mode 100644 cpp/src/phonenumbers/base/memory/singleton_unsafe.h create mode 100644 cpp/src/phonenumbers/base/memory/singleton_win32.h create mode 100644 cpp/src/phonenumbers/base/synchronization/lock_boost.h create mode 100644 cpp/src/phonenumbers/base/synchronization/lock_stdmutex.h create mode 100644 cpp/src/phonenumbers/base/synchronization/lock_unsafe.h create mode 100644 cpp/src/phonenumbers/base/synchronization/lock_win32.h diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index fe8f6aa83..1e306ad59 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -86,6 +86,8 @@ option ("USE_LITE_METADATA" "Use lite metadata" "OFF") option ("USE_RE2" "Use RE2" "OFF") option ("USE_STD_MAP" "Force the use of std::map" "OFF") option ("BUILD_STATIC_LIB" "Build static libraries" "ON") +option ("USE_STDMUTEX" "Use C++ 2011 std::mutex for multi-threading" "OFF") +option ("USE_POSIX_THREAD" "Use Posix api for multi-threading" "OFF") if (${USE_ALTERNATE_FORMATS} STREQUAL "ON") add_definitions ("-DI18N_PHONENUMBERS_USE_ALTERNATE_FORMATS") @@ -104,6 +106,19 @@ if (${USE_BOOST} STREQUAL "ON") include_directories (${Boost_INCLUDE_DIRS}) endif () +if (${USE_STDMUTEX} STREQUAL "ON") + add_definitions ("-DI18N_PHONENUMBERS_USE_STDMUTEX") +endif () + +if (${USE_POSIX_THREAD} STREQUAL "ON") + add_definitions ("-DI18N_PHONENUMBERS_HAVE_POSIX_THREAD") + find_package (Threads REQUIRED) +endif () + +if (${USE_BOOST} STREQUAL "OFF" AND ${USE_STDMUTEX} STREQUAL "OFF") + find_package (Threads) +endif() + find_or_build_gtest () if (${USE_RE2} STREQUAL "ON") @@ -423,6 +438,15 @@ if (${USE_RE2} STREQUAL "ON") list (APPEND LIBRARY_DEPS ${RE2_LIB}) endif () +if (${USE_POSIX_THREAD} STREQUAL "ON" OR ((APPLE OR UNIX) AND ${USE_BOOST} STREQUAL "OFF" AND ${USE_STDMUTEX} STREQUAL "OFF")) + if(CMAKE_USE_PTHREADS_INIT) + list (APPEND CMAKE_C_FLAGS "-pthread") + endif() + if(CMAKE_THREAD_LIBS_INIT) + list (APPEND LIBRARY_DEPS ${CMAKE_THREAD_LIBS_INIT}) + endif() +endif () + if (APPLE) list (APPEND COMMON_DEPS ${COREFOUNDATION_LIB} ${FOUNDATION_LIB}) endif () @@ -579,13 +603,22 @@ install ( install (FILES "src/phonenumbers/base/memory/scoped_ptr.h" "src/phonenumbers/base/memory/singleton.h" + "src/phonenumbers/base/memory/singleton_boost.h" "src/phonenumbers/base/memory/singleton_posix.h" + "src/phonenumbers/base/memory/singleton_stdmutex.h" + "src/phonenumbers/base/memory/singleton_unsafe.h" + "src/phonenumbers/base/memory/singleton_win32.h" DESTINATION include/phonenumbers/base/memory/ ) -install (FILES "src/phonenumbers/base/synchronization/lock.h" - "src/phonenumbers/base/synchronization/lock_posix.h" - DESTINATION include/phonenumbers/base/synchronization/) +install (FILES + "src/phonenumbers/base/synchronization/lock.h" + "src/phonenumbers/base/synchronization/lock_boost.h" + "src/phonenumbers/base/synchronization/lock_posix.h" + "src/phonenumbers/base/synchronization/lock_stdmutex.h" + "src/phonenumbers/base/synchronization/lock_unsafe.h" + "src/phonenumbers/base/synchronization/lock_win32.h" + DESTINATION include/phonenumbers/base/synchronization/) set (LIBDIR ${CMAKE_INSTALL_LIBDIR}) diff --git a/cpp/README b/cpp/README index 52f932d17..ac94bbcd5 100644 --- a/cpp/README +++ b/cpp/README @@ -117,11 +117,17 @@ Requirements: $ cd icu/source $ ./configure && make && sudo make install - - Boost - Version 1.40 or more recent is required if you need libphonenumber to be - thread-safe. If you access libphonenumber from a single thread, you can - avoid the Boost dependency by disabling the USE_BOOST CMake option (see - Troubleshooting section below for information about ccmake). + - A thread synchronization solution or more recent is required if you need + libphonenumber to be thread-safe. Supported solution are: + - Boost Version 1.40 or more recent + - Posix Thread. Linux or Apple (ios/mac) detection is automatic. On other + Posix environnement, uses -DUSE_POSIX_THREAD = ON + - C++ 2011 (and later) std::mutex. Uses -DUSE_STDMUTEX = ON to enable + automatic C++ 2011 detection (if you prefer Posix or Win32 solution). + - Windows Win32 synchronization API. + + If you access libphonenumber from a single thread, you don't need one of + these solution. You can install it very easily on a Debian-based GNU/Linux distribution: $ sudo apt-get install libboost-dev libboost-thread-dev libboost-system-dev @@ -350,10 +356,12 @@ Supported build parameters multi-threaded environments that are not Linux and Mac. Libphonenumber relies on Boost for - non-POSIX (e.g. Windows) + non-POSIX, non-Windows and non-C++ 2011 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. + USE_POSIX_THREAD = ON | OFF [OFF] -- Use Posix thread for multi-threading. USE_RE2 = ON | OFF [OFF] -- Use RE2. USE_STD_MAP = ON | OFF [OFF] -- Force the use of std::map. + USE_STDMUTEX = ON | OFF [OFF] -- Detect and use C++2011 for multi-threading. diff --git a/cpp/src/phonenumbers/asyoutypeformatter.cc b/cpp/src/phonenumbers/asyoutypeformatter.cc index f12e18e68..d55ead6b9 100644 --- a/cpp/src/phonenumbers/asyoutypeformatter.cc +++ b/cpp/src/phonenumbers/asyoutypeformatter.cc @@ -211,9 +211,11 @@ void AsYouTypeFormatter::NarrowDownPossibleFormats( ++it; continue; } - int last_leading_digits_pattern = - std::min(index_of_leading_digits_pattern, - format.leading_digits_pattern_size() - 1); + // We don't use std::min because there is stange symbol conflict + // with including and protobuf symbols + int last_leading_digits_pattern = format.leading_digits_pattern_size() - 1; + if (last_leading_digits_pattern > index_of_leading_digits_pattern) + last_leading_digits_pattern = index_of_leading_digits_pattern; const scoped_ptr input( regexp_factory_->CreateInput(leading_digits)); if (!regexp_cache_.GetRegExp(format.leading_digits_pattern().Get( diff --git a/cpp/src/phonenumbers/base/memory/singleton.h b/cpp/src/phonenumbers/base/memory/singleton.h index 5fd3e4c6e..46b062071 100644 --- a/cpp/src/phonenumbers/base/memory/singleton.h +++ b/cpp/src/phonenumbers/base/memory/singleton.h @@ -18,78 +18,16 @@ #define I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_H_ #if defined(I18N_PHONENUMBERS_USE_BOOST) - -#include -#include -#include - -namespace i18n { -namespace phonenumbers { - -template -class Singleton : private boost::noncopyable { - public: - virtual ~Singleton() {} - - static T* GetInstance() { - boost::call_once(Init, flag); - return instance.get(); - } - - private: - static void Init() { - instance.reset(new T()); - } - - static boost::scoped_ptr instance; - static boost::once_flag flag; -}; - -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 on non-POSIX platforms, please compile with -// -DI18N_PHONENUMBERS_USE_BOOST. -template -class Singleton { - public: - Singleton() : thread_checker_() {} - - virtual ~Singleton() {} - - static T* GetInstance() { - static T* instance = NULL; - if (!instance) { - instance = new T(); - } - DCHECK(instance->thread_checker_.CalledOnValidThread()); - return instance; - } - - private: - const ThreadChecker thread_checker_; -}; - -} // namespace phonenumbers -} // namespace i18n - -#else +#include "phonenumbers/base/memory/singleton_boost.h" +#elif (__cplusplus >= 201103L) && defined(I18N_PHONENUMBERS_USE_STDMUTEX) +// C++11 Lock implementation based on std::mutex. +#include "phonenumbers/base/memory/singleton_stdmutex.h" +#elif defined(__linux__) || defined(__APPLE__) || defined(I18N_PHONENUMBERS_HAVE_POSIX_THREAD) #include "phonenumbers/base/memory/singleton_posix.h" -#endif // !defined(__linux__) && !defined(__APPLE__) - +#elif defined(WIN32) +#include "phonenumbers/base/memory/singleton_win32.h" +#else +#include "phonenumbers/base/memory/singleton_unsafe.h" #endif // !I18N_PHONENUMBERS_USE_BOOST + #endif // I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_H_ diff --git a/cpp/src/phonenumbers/base/memory/singleton_boost.h b/cpp/src/phonenumbers/base/memory/singleton_boost.h new file mode 100644 index 000000000..a945e437d --- /dev/null +++ b/cpp/src/phonenumbers/base/memory/singleton_boost.h @@ -0,0 +1,51 @@ +// Copyright (C) 2020 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_BOOST_H_ +#define I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_BOOST_H_ + +#include +#include +#include + +namespace i18n { +namespace phonenumbers { + +template +class Singleton : private boost::noncopyable { + public: + Singleton() {} + virtual ~Singleton() {} + + static T* GetInstance() { + boost::call_once(Init, flag_); + return instance_.get(); + } + + private: + static void Init() { + instance_.reset(new T()); + } + + static boost::scoped_ptr instance_; + static boost::once_flag flag_; +}; + +template boost::scoped_ptr Singleton::instance_; +template boost::once_flag Singleton::flag_ = BOOST_ONCE_INIT; + +} // namespace phonenumbers +} // namespace i18n + +#endif // I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_BOOST_H_ diff --git a/cpp/src/phonenumbers/base/memory/singleton_stdmutex.h b/cpp/src/phonenumbers/base/memory/singleton_stdmutex.h new file mode 100644 index 000000000..ce7fd45a6 --- /dev/null +++ b/cpp/src/phonenumbers/base/memory/singleton_stdmutex.h @@ -0,0 +1,62 @@ +// Copyright (C) 2020 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_STDMUTEX_H_ +#define I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_STDMUTEX_H_ + +#include + +#include "phonenumbers/base/basictypes.h" + +namespace i18n { +namespace phonenumbers { + +template +class Singleton { + public: + Singleton() {} + virtual ~Singleton() {} + + static T* GetInstance() { + if (once_init_) { + singleton_mutex_.lock(); + if (once_init_) { + Init(); + once_init_ = false; + } + singleton_mutex_.unlock(); + } + return instance_; + } + + private: + DISALLOW_COPY_AND_ASSIGN(Singleton); + + static void Init() { + instance_ = new T(); + } + + static T* instance_; // Leaky singleton. + static std::mutex singleton_mutex_; + static bool once_init_; +}; + +template T* Singleton::instance_; +template std::mutex Singleton::singleton_mutex_; +template bool Singleton::once_init_ = true; + +} // namespace phonenumbers +} // namespace i18n + +#endif // I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_STDMUTEX_H_ diff --git a/cpp/src/phonenumbers/base/memory/singleton_unsafe.h b/cpp/src/phonenumbers/base/memory/singleton_unsafe.h new file mode 100644 index 000000000..972149fe5 --- /dev/null +++ b/cpp/src/phonenumbers/base/memory/singleton_unsafe.h @@ -0,0 +1,49 @@ +// 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_UNSAFE_H_ +#define I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_UNSAFE_H_ + +#include "phonenumbers/base/logging.h" +#include "phonenumbers/base/thread_checker.h" + +namespace i18n { +namespace phonenumbers { + +// Note that this implementation is not thread-safe. For a thread-safe +// implementation on non-POSIX platforms, please compile with +// -DI18N_PHONENUMBERS_USE_BOOST. +template +class Singleton { + public: + Singleton() : thread_checker_() {} + virtual ~Singleton() {} + + static T* GetInstance() { + static T* instance = NULL; + if (!instance) { + instance = new T(); + } + DCHECK(instance->thread_checker_.CalledOnValidThread()); + return instance; + } + + private: + const ThreadChecker thread_checker_; +}; + +} // namespace phonenumbers +} // namespace i18n + +#endif // I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_UNSAFE_H_ diff --git a/cpp/src/phonenumbers/base/memory/singleton_win32.h b/cpp/src/phonenumbers/base/memory/singleton_win32.h new file mode 100644 index 000000000..7da69e8a1 --- /dev/null +++ b/cpp/src/phonenumbers/base/memory/singleton_win32.h @@ -0,0 +1,69 @@ +// Copyright (C) 2020 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_WIN32_H_ +#define I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_WIN32_H_ + +#include +#include + +#include "phonenumbers/base/basictypes.h" + +namespace i18n { +namespace phonenumbers { + +template +class Singleton { + public: + Singleton() {} + virtual ~Singleton() {} + + static T* GetInstance() { + if (once_init_) { + EnterCriticalSection(&critical_section_); + if (once_init_) { + Init(); + once_init_ = false; + } + LeaveCriticalSection(&critical_section_); + } + return instance_; + } + + private: + DISALLOW_COPY_AND_ASSIGN(Singleton); + + static void Init() { + instance_ = new T(); + } + + static T* instance_; // Leaky singleton. + static CRITICAL_SECTION critical_section_; + static bool once_init_; +}; + +static bool perform_init_crit(CRITICAL_SECTION& cs) +{ + InitializeCriticalSection(&cs); + return true; +} + +template T* Singleton::instance_; +template CRITICAL_SECTION Singleton::critical_section_; +template bool Singleton::once_init_=perform_init_crit(Singleton::critical_section_); + +} // namespace phonenumbers +} // namespace i18n + +#endif // I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_WIN32_H_ diff --git a/cpp/src/phonenumbers/base/synchronization/lock.h b/cpp/src/phonenumbers/base/synchronization/lock.h index 1893f1b3c..a13f0db15 100644 --- a/cpp/src/phonenumbers/base/synchronization/lock.h +++ b/cpp/src/phonenumbers/base/synchronization/lock.h @@ -18,81 +18,20 @@ #define I18N_PHONENUMBERS_BASE_SYNCHRONIZATION_LOCK_H_ #if defined(I18N_PHONENUMBERS_USE_BOOST) -#include - -namespace i18n { -namespace phonenumbers { - -typedef boost::mutex Lock; -typedef boost::mutex::scoped_lock AutoLock; - -} // namespace phonenumbers -} // namespace i18n - -#else // I18N_PHONENUMBERS_USE_BOOST - -#include "phonenumbers/base/logging.h" -#include "phonenumbers/base/thread_checker.h" - +#include "phonenumbers/base/synchronization/lock_boost.h" +#elif (__cplusplus >= 201103L) && defined(I18N_PHONENUMBERS_USE_STDMUTEX) // C++11 Lock implementation based on std::mutex. -#if __cplusplus>=201103L -#include - -namespace i18n { -namespace phonenumbers { - -class Lock { -public: - Lock() = default; - - void Acquire() const { - mutex_.lock(); - } - - void Release() const { - mutex_.unlock(); - } - -private: - mutable std::mutex mutex_; -}; - -} // namespace phonenumbers -} // namespace i18n - -// 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. -#elif !defined(__linux__) && !defined(__APPLE__) - -namespace i18n { -namespace phonenumbers { - -class Lock { - public: - Lock() {} - - void Acquire() const { - DCHECK(thread_checker_.CalledOnValidThread()); - IGNORE_UNUSED(thread_checker_); - } - - void Release() const { - DCHECK(thread_checker_.CalledOnValidThread()); - IGNORE_UNUSED(thread_checker_); - } - - private: - const ThreadChecker thread_checker_; -}; - -} // namespace phonenumbers -} // namespace i18n - -#else +#include "phonenumbers/base/synchronization/lock_stdmutex.h" +#elif defined(__linux__) || defined(__APPLE__) || defined(I18N_PHONENUMBERS_HAVE_POSIX_THREAD) #include "phonenumbers/base/synchronization/lock_posix.h" +#elif defined(WIN32) +#include "phonenumbers/base/synchronization/lock_win32.h" +#else +#include "phonenumbers/base/synchronization/lock_unsafe.h" #endif +// lock_boost.h comes with its own AutoLock. +#if !defined(I18N_PHONENUMBERS_USE_BOOST) namespace i18n { namespace phonenumbers { @@ -112,6 +51,6 @@ class AutoLock { } // namespace phonenumbers } // namespace i18n +#endif // !I18N_PHONENUMBERS_USE_BOOST -#endif // I18N_PHONENUMBERS_USE_BOOST #endif // I18N_PHONENUMBERS_BASE_SYNCHRONIZATION_LOCK_H_ diff --git a/cpp/src/phonenumbers/base/synchronization/lock_boost.h b/cpp/src/phonenumbers/base/synchronization/lock_boost.h new file mode 100644 index 000000000..c3798e9df --- /dev/null +++ b/cpp/src/phonenumbers/base/synchronization/lock_boost.h @@ -0,0 +1,31 @@ +// Copyright (C) 2020 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_BOOST_H_ +#define I18N_PHONENUMBERS_BASE_SYNCHRONIZATION_LOCK_BOOST_H_ + +#include + +namespace i18n { +namespace phonenumbers { + +typedef boost::mutex Lock; +typedef boost::mutex::scoped_lock AutoLock; + +} // namespace phonenumbers +} // namespace i18n + +#endif // I18N_PHONENUMBERS_BASE_SYNCHRONIZATION_LOCK_BOOST_H_ diff --git a/cpp/src/phonenumbers/base/synchronization/lock_stdmutex.h b/cpp/src/phonenumbers/base/synchronization/lock_stdmutex.h new file mode 100644 index 000000000..1514d7e52 --- /dev/null +++ b/cpp/src/phonenumbers/base/synchronization/lock_stdmutex.h @@ -0,0 +1,47 @@ +// Copyright (C) 2020 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_STDMUTEX_H_ +#define I18N_PHONENUMBERS_BASE_SYNCHRONIZATION_LOCK_STDMUTEX_H_ + +#include + +#include "phonenumbers/base/basictypes.h" + +namespace i18n { +namespace phonenumbers { + +class Lock { + public: + Lock() = default; + + void Acquire() const { + mutex_.lock(); + } + + void Release() const { + mutex_.unlock(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(Lock); + mutable std::mutex mutex_; +}; + +} // namespace phonenumbers +} // namespace i18n + +#endif // I18N_PHONENUMBERS_BASE_SYNCHRONIZATION_LOCK_STDMUTEX_H_ diff --git a/cpp/src/phonenumbers/base/synchronization/lock_unsafe.h b/cpp/src/phonenumbers/base/synchronization/lock_unsafe.h new file mode 100644 index 000000000..ad94fefb1 --- /dev/null +++ b/cpp/src/phonenumbers/base/synchronization/lock_unsafe.h @@ -0,0 +1,51 @@ +// Copyright (C) 2020 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_UNSAFE_H_ +#define I18N_PHONENUMBERS_BASE_SYNCHRONIZATION_LOCK_UNSAFE_H_ + +#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. +namespace i18n { +namespace phonenumbers { + +class Lock { + public: + Lock() {} + + void Acquire() const { + DCHECK(thread_checker_.CalledOnValidThread()); + IGNORE_UNUSED(thread_checker_); + } + + void Release() const { + DCHECK(thread_checker_.CalledOnValidThread()); + IGNORE_UNUSED(thread_checker_); + } + + private: + DISALLOW_COPY_AND_ASSIGN(Lock); + const ThreadChecker thread_checker_; +}; + +} // namespace phonenumbers +} // namespace i18n + +#endif // I18N_PHONENUMBERS_BASE_SYNCHRONIZATION_LOCK_UNSAFE_H_ diff --git a/cpp/src/phonenumbers/base/synchronization/lock_win32.h b/cpp/src/phonenumbers/base/synchronization/lock_win32.h new file mode 100644 index 000000000..dea1464da --- /dev/null +++ b/cpp/src/phonenumbers/base/synchronization/lock_win32.h @@ -0,0 +1,54 @@ +// Copyright (C) 2020 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_WINDOWS_H_ +#define I18N_PHONENUMBERS_BASE_SYNCHRONIZATION_LOCK_WINDOWS_H_ + +#include +#include + +#include "phonenumbers/base/basictypes.h" + +namespace i18n { +namespace phonenumbers { + +class Lock { + public: + Lock() { + InitializeCriticalSection(&cs_); + } + + ~Lock() { + DeleteCriticalSection(&cs_); + } + + void Acquire() { + EnterCriticalSection(&cs_); + } + + void Release() { + LeaveCriticalSection(&cs_); + } + + private: + DISALLOW_COPY_AND_ASSIGN(Lock); + CRITICAL_SECTION cs_; +}; + +} // 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 b7a352343..6679d9bb0 100644 --- a/cpp/src/phonenumbers/base/thread_checker.h +++ b/cpp/src/phonenumbers/base/thread_checker.h @@ -22,8 +22,10 @@ // 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(__linux__) && !defined(__APPLE__) && \ - !defined(I18N_PHONENUMBERS_NO_THREAD_SAFETY) +#if !defined(__linux__) && !defined(__APPLE__) && !defined(I18N_PHONENUMBERS_HAVE_POSIX_THREAD) && \ + !defined(I18N_PHONENUMBERS_NO_THREAD_SAFETY) && \ + !((__cplusplus >= 201103L) && defined(I18N_PHONENUMBERS_USE_STDMUTEX)) && \ + !defined(WIN32) #error Building without Boost, please provide \ -DI18N_PHONENUMBERS_NO_THREAD_SAFETY #endif @@ -31,7 +33,7 @@ #endif #if !defined(NDEBUG) && !defined(I18N_PHONENUMBERS_USE_BOOST) && \ - (defined(__linux__) || defined(__apple__)) + (defined(__linux__) || defined(__APPLE__) || defined(I18N_PHONENUMBERS_HAVE_POSIX_THREAD)) #include