Skip to content

Commit 00e4f74

Browse files
authored
support of singleton and lock for win32 and c++ 11 (google#2400)
Include modification from Dominic Battre
1 parent 14f033e commit 00e4f74

14 files changed

Lines changed: 495 additions & 159 deletions

cpp/CMakeLists.txt

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ option ("USE_LITE_METADATA" "Use lite metadata" "OFF")
8686
option ("USE_RE2" "Use RE2" "OFF")
8787
option ("USE_STD_MAP" "Force the use of std::map" "OFF")
8888
option ("BUILD_STATIC_LIB" "Build static libraries" "ON")
89+
option ("USE_STDMUTEX" "Use C++ 2011 std::mutex for multi-threading" "OFF")
90+
option ("USE_POSIX_THREAD" "Use Posix api for multi-threading" "OFF")
8991

9092
if (${USE_ALTERNATE_FORMATS} STREQUAL "ON")
9193
add_definitions ("-DI18N_PHONENUMBERS_USE_ALTERNATE_FORMATS")
@@ -104,6 +106,19 @@ if (${USE_BOOST} STREQUAL "ON")
104106
include_directories (${Boost_INCLUDE_DIRS})
105107
endif ()
106108

109+
if (${USE_STDMUTEX} STREQUAL "ON")
110+
add_definitions ("-DI18N_PHONENUMBERS_USE_STDMUTEX")
111+
endif ()
112+
113+
if (${USE_POSIX_THREAD} STREQUAL "ON")
114+
add_definitions ("-DI18N_PHONENUMBERS_HAVE_POSIX_THREAD")
115+
find_package (Threads REQUIRED)
116+
endif ()
117+
118+
if (${USE_BOOST} STREQUAL "OFF" AND ${USE_STDMUTEX} STREQUAL "OFF")
119+
find_package (Threads)
120+
endif()
121+
107122
find_or_build_gtest ()
108123

109124
if (${USE_RE2} STREQUAL "ON")
@@ -423,6 +438,15 @@ if (${USE_RE2} STREQUAL "ON")
423438
list (APPEND LIBRARY_DEPS ${RE2_LIB})
424439
endif ()
425440

441+
if (${USE_POSIX_THREAD} STREQUAL "ON" OR ((APPLE OR UNIX) AND ${USE_BOOST} STREQUAL "OFF" AND ${USE_STDMUTEX} STREQUAL "OFF"))
442+
if(CMAKE_USE_PTHREADS_INIT)
443+
list (APPEND CMAKE_C_FLAGS "-pthread")
444+
endif()
445+
if(CMAKE_THREAD_LIBS_INIT)
446+
list (APPEND LIBRARY_DEPS ${CMAKE_THREAD_LIBS_INIT})
447+
endif()
448+
endif ()
449+
426450
if (APPLE)
427451
list (APPEND COMMON_DEPS ${COREFOUNDATION_LIB} ${FOUNDATION_LIB})
428452
endif ()
@@ -579,13 +603,22 @@ install (
579603
install (FILES
580604
"src/phonenumbers/base/memory/scoped_ptr.h"
581605
"src/phonenumbers/base/memory/singleton.h"
606+
"src/phonenumbers/base/memory/singleton_boost.h"
582607
"src/phonenumbers/base/memory/singleton_posix.h"
608+
"src/phonenumbers/base/memory/singleton_stdmutex.h"
609+
"src/phonenumbers/base/memory/singleton_unsafe.h"
610+
"src/phonenumbers/base/memory/singleton_win32.h"
583611
DESTINATION include/phonenumbers/base/memory/
584612
)
585613

586-
install (FILES "src/phonenumbers/base/synchronization/lock.h"
587-
"src/phonenumbers/base/synchronization/lock_posix.h"
588-
DESTINATION include/phonenumbers/base/synchronization/)
614+
install (FILES
615+
"src/phonenumbers/base/synchronization/lock.h"
616+
"src/phonenumbers/base/synchronization/lock_boost.h"
617+
"src/phonenumbers/base/synchronization/lock_posix.h"
618+
"src/phonenumbers/base/synchronization/lock_stdmutex.h"
619+
"src/phonenumbers/base/synchronization/lock_unsafe.h"
620+
"src/phonenumbers/base/synchronization/lock_win32.h"
621+
DESTINATION include/phonenumbers/base/synchronization/)
589622

590623
set (LIBDIR ${CMAKE_INSTALL_LIBDIR})
591624

cpp/README

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,17 @@ Requirements:
117117
$ cd icu/source
118118
$ ./configure && make && sudo make install
119119

120-
- Boost
121-
Version 1.40 or more recent is required if you need libphonenumber to be
122-
thread-safe. If you access libphonenumber from a single thread, you can
123-
avoid the Boost dependency by disabling the USE_BOOST CMake option (see
124-
Troubleshooting section below for information about ccmake).
120+
- A thread synchronization solution or more recent is required if you need
121+
libphonenumber to be thread-safe. Supported solution are:
122+
- Boost Version 1.40 or more recent
123+
- Posix Thread. Linux or Apple (ios/mac) detection is automatic. On other
124+
Posix environnement, uses -DUSE_POSIX_THREAD = ON
125+
- C++ 2011 (and later) std::mutex. Uses -DUSE_STDMUTEX = ON to enable
126+
automatic C++ 2011 detection (if you prefer Posix or Win32 solution).
127+
- Windows Win32 synchronization API.
128+
129+
If you access libphonenumber from a single thread, you don't need one of
130+
these solution.
125131

126132
You can install it very easily on a Debian-based GNU/Linux distribution:
127133
$ sudo apt-get install libboost-dev libboost-thread-dev libboost-system-dev
@@ -350,10 +356,12 @@ Supported build parameters
350356
multi-threaded environments that
351357
are not Linux and Mac.
352358
Libphonenumber relies on Boost for
353-
non-POSIX (e.g. Windows)
359+
non-POSIX, non-Windows and non-C++ 2011
354360
multi-threading.
355361
USE_ICU_REGEXP = ON | OFF [ON] -- Use ICU regexp engine.
356362
USE_LITE_METADATA = ON | OFF [OFF] -- Generates smaller metadata that
357363
doesn't include example numbers.
364+
USE_POSIX_THREAD = ON | OFF [OFF] -- Use Posix thread for multi-threading.
358365
USE_RE2 = ON | OFF [OFF] -- Use RE2.
359366
USE_STD_MAP = ON | OFF [OFF] -- Force the use of std::map.
367+
USE_STDMUTEX = ON | OFF [OFF] -- Detect and use C++2011 for multi-threading.

cpp/src/phonenumbers/asyoutypeformatter.cc

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,11 @@ void AsYouTypeFormatter::NarrowDownPossibleFormats(
211211
++it;
212212
continue;
213213
}
214-
int last_leading_digits_pattern =
215-
std::min(index_of_leading_digits_pattern,
216-
format.leading_digits_pattern_size() - 1);
214+
// We don't use std::min because there is stange symbol conflict
215+
// with including <windows.h> and protobuf symbols
216+
int last_leading_digits_pattern = format.leading_digits_pattern_size() - 1;
217+
if (last_leading_digits_pattern > index_of_leading_digits_pattern)
218+
last_leading_digits_pattern = index_of_leading_digits_pattern;
217219
const scoped_ptr<RegExpInput> input(
218220
regexp_factory_->CreateInput(leading_digits));
219221
if (!regexp_cache_.GetRegExp(format.leading_digits_pattern().Get(

cpp/src/phonenumbers/base/memory/singleton.h

Lines changed: 10 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -18,78 +18,16 @@
1818
#define I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_H_
1919

2020
#if defined(I18N_PHONENUMBERS_USE_BOOST)
21-
22-
#include <boost/scoped_ptr.hpp>
23-
#include <boost/thread/once.hpp>
24-
#include <boost/utility.hpp>
25-
26-
namespace i18n {
27-
namespace phonenumbers {
28-
29-
template <class T>
30-
class Singleton : private boost::noncopyable {
31-
public:
32-
virtual ~Singleton() {}
33-
34-
static T* GetInstance() {
35-
boost::call_once(Init, flag);
36-
return instance.get();
37-
}
38-
39-
private:
40-
static void Init() {
41-
instance.reset(new T());
42-
}
43-
44-
static boost::scoped_ptr<T> instance;
45-
static boost::once_flag flag;
46-
};
47-
48-
template <class T> boost::scoped_ptr<T> Singleton<T>::instance;
49-
template <class T> boost::once_flag Singleton<T>::flag = BOOST_ONCE_INIT;
50-
51-
} // namespace phonenumbers
52-
} // namespace i18n
53-
54-
#else // !I18N_PHONENUMBERS_USE_BOOST
55-
56-
#include "phonenumbers/base/logging.h"
57-
#include "phonenumbers/base/thread_checker.h"
58-
59-
#if !defined(__linux__) && !defined(__APPLE__)
60-
61-
namespace i18n {
62-
namespace phonenumbers {
63-
64-
// Note that this implementation is not thread-safe. For a thread-safe
65-
// implementation on non-POSIX platforms, please compile with
66-
// -DI18N_PHONENUMBERS_USE_BOOST.
67-
template <class T>
68-
class Singleton {
69-
public:
70-
Singleton() : thread_checker_() {}
71-
72-
virtual ~Singleton() {}
73-
74-
static T* GetInstance() {
75-
static T* instance = NULL;
76-
if (!instance) {
77-
instance = new T();
78-
}
79-
DCHECK(instance->thread_checker_.CalledOnValidThread());
80-
return instance;
81-
}
82-
83-
private:
84-
const ThreadChecker thread_checker_;
85-
};
86-
87-
} // namespace phonenumbers
88-
} // namespace i18n
89-
90-
#else
21+
#include "phonenumbers/base/memory/singleton_boost.h"
22+
#elif (__cplusplus >= 201103L) && defined(I18N_PHONENUMBERS_USE_STDMUTEX)
23+
// C++11 Lock implementation based on std::mutex.
24+
#include "phonenumbers/base/memory/singleton_stdmutex.h"
25+
#elif defined(__linux__) || defined(__APPLE__) || defined(I18N_PHONENUMBERS_HAVE_POSIX_THREAD)
9126
#include "phonenumbers/base/memory/singleton_posix.h"
92-
#endif // !defined(__linux__) && !defined(__APPLE__)
93-
27+
#elif defined(WIN32)
28+
#include "phonenumbers/base/memory/singleton_win32.h"
29+
#else
30+
#include "phonenumbers/base/memory/singleton_unsafe.h"
9431
#endif // !I18N_PHONENUMBERS_USE_BOOST
32+
9533
#endif // I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_H_
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// Copyright (C) 2020 The Libphonenumber Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_BOOST_H_
16+
#define I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_BOOST_H_
17+
18+
#include <boost/scoped_ptr.hpp>
19+
#include <boost/thread/once.hpp>
20+
#include <boost/utility.hpp>
21+
22+
namespace i18n {
23+
namespace phonenumbers {
24+
25+
template <class T>
26+
class Singleton : private boost::noncopyable {
27+
public:
28+
Singleton() {}
29+
virtual ~Singleton() {}
30+
31+
static T* GetInstance() {
32+
boost::call_once(Init, flag_);
33+
return instance_.get();
34+
}
35+
36+
private:
37+
static void Init() {
38+
instance_.reset(new T());
39+
}
40+
41+
static boost::scoped_ptr<T> instance_;
42+
static boost::once_flag flag_;
43+
};
44+
45+
template <class T> boost::scoped_ptr<T> Singleton<T>::instance_;
46+
template <class T> boost::once_flag Singleton<T>::flag_ = BOOST_ONCE_INIT;
47+
48+
} // namespace phonenumbers
49+
} // namespace i18n
50+
51+
#endif // I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_BOOST_H_
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright (C) 2020 The Libphonenumber Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_STDMUTEX_H_
16+
#define I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_STDMUTEX_H_
17+
18+
#include <mutex>
19+
20+
#include "phonenumbers/base/basictypes.h"
21+
22+
namespace i18n {
23+
namespace phonenumbers {
24+
25+
template <class T>
26+
class Singleton {
27+
public:
28+
Singleton() {}
29+
virtual ~Singleton() {}
30+
31+
static T* GetInstance() {
32+
if (once_init_) {
33+
singleton_mutex_.lock();
34+
if (once_init_) {
35+
Init();
36+
once_init_ = false;
37+
}
38+
singleton_mutex_.unlock();
39+
}
40+
return instance_;
41+
}
42+
43+
private:
44+
DISALLOW_COPY_AND_ASSIGN(Singleton);
45+
46+
static void Init() {
47+
instance_ = new T();
48+
}
49+
50+
static T* instance_; // Leaky singleton.
51+
static std::mutex singleton_mutex_;
52+
static bool once_init_;
53+
};
54+
55+
template <class T> T* Singleton<T>::instance_;
56+
template <class T> std::mutex Singleton<T>::singleton_mutex_;
57+
template <class T> bool Singleton<T>::once_init_ = true;
58+
59+
} // namespace phonenumbers
60+
} // namespace i18n
61+
62+
#endif // I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_STDMUTEX_H_
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (C) 2013 The Libphonenumber Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_UNSAFE_H_
16+
#define I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_UNSAFE_H_
17+
18+
#include "phonenumbers/base/logging.h"
19+
#include "phonenumbers/base/thread_checker.h"
20+
21+
namespace i18n {
22+
namespace phonenumbers {
23+
24+
// Note that this implementation is not thread-safe. For a thread-safe
25+
// implementation on non-POSIX platforms, please compile with
26+
// -DI18N_PHONENUMBERS_USE_BOOST.
27+
template <class T>
28+
class Singleton {
29+
public:
30+
Singleton() : thread_checker_() {}
31+
virtual ~Singleton() {}
32+
33+
static T* GetInstance() {
34+
static T* instance = NULL;
35+
if (!instance) {
36+
instance = new T();
37+
}
38+
DCHECK(instance->thread_checker_.CalledOnValidThread());
39+
return instance;
40+
}
41+
42+
private:
43+
const ThreadChecker thread_checker_;
44+
};
45+
46+
} // namespace phonenumbers
47+
} // namespace i18n
48+
49+
#endif // I18N_PHONENUMBERS_BASE_MEMORY_SINGLETON_UNSAFE_H_

0 commit comments

Comments
 (0)