aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/_posts/2015-07-03-std-call-once-bug.md
diff options
context:
space:
mode:
Diffstat (limited to '_posts/2015-07-03-std-call-once-bug.md')
-rw-r--r--_posts/2015-07-03-std-call-once-bug.md66
1 files changed, 26 insertions, 40 deletions
diff --git a/_posts/2015-07-03-std-call-once-bug.md b/_posts/2015-07-03-std-call-once-bug.md
index 544c616..0aa0249 100644
--- a/_posts/2015-07-03-std-call-once-bug.md
+++ b/_posts/2015-07-03-std-call-once-bug.md
@@ -36,11 +36,9 @@ using C++11 facilities like this:
#include <mutex>
template <typename Derived>
-class Singleton
-{
+class Singleton {
public:
- static Derived& get_instance()
- {
+ static Derived& get_instance() {
std::call_once(initialized_flag, &initialize_instance);
return Derived::get_instance_unsafe();
}
@@ -49,15 +47,13 @@ protected:
Singleton() = default;
~Singleton() = default;
- static Derived& get_instance_unsafe()
- {
+ static Derived& get_instance_unsafe() {
static Derived instance;
return instance;
}
private:
- static void initialize_instance()
- {
+ static void initialize_instance() {
Derived::get_instance_unsafe();
}
@@ -76,8 +72,7 @@ Now other classes can inherit from `Singleton`, implementing the singleton
pattern effortlessly:
```c++
-class Logger : public Singleton<Logger>
-{
+class Logger : public Singleton<Logger> {
private:
Logger() = default;
~Logger() = default;
@@ -93,11 +88,9 @@ trickery, and the implementation would be much simpler, i.e. something like
this:
```c++
-class Logger
-{
+class Logger {
public:
- static Logger& get_instance()
- {
+ static Logger& get_instance() {
static Logger instance;
return instance;
}
@@ -146,18 +139,15 @@ constructor, and everything looked fine at first glance.
#include <chrono>
#include <thread>
-class Logger : public Singleton<Logger>
-{
+class Logger : public Singleton<Logger> {
public:
- Logger& operator<<(const char* msg)
- {
+ Logger& operator<<(const char* msg) {
// Actual logging is stripped for brevity.
return *this;
}
private:
- Logger()
- {
+ Logger() {
// Opening log files, etc.
std::this_thread::sleep_for(std::chrono::seconds{3});
}
@@ -167,11 +157,9 @@ private:
friend class Singleton<Logger>;
};
-class Duke : public Singleton<Duke>
-{
+class Duke : public Singleton<Duke> {
private:
- Duke()
- {
+ Duke() {
Logger::get_instance() << "started Duke's initialization";
// It's a lot of work to be done.
std::this_thread::sleep_for(std::chrono::seconds{10});
@@ -191,25 +179,23 @@ Like in this example:
```c++
#include <thread>
-namespace
-{
- void get_logger()
- {
- entered(__FUNCTION__);
- Logger::get_instance();
- exiting(__FUNCTION__);
- }
+namespace {
+
+void get_logger() {
+ entered(__FUNCTION__);
+ Logger::get_instance();
+ exiting(__FUNCTION__);
+}
+
+void get_duke() {
+ entered(__FUNCTION__);
+ Duke::get_instance();
+ exiting(__FUNCTION__);
+}
- void get_duke()
- {
- entered(__FUNCTION__);
- Duke::get_instance();
- exiting(__FUNCTION__);
- }
}
-int main()
-{
+int main() {
std::thread t1{&get_duke};
std::thread t2{&get_logger};
t1.join();