diff options
Diffstat (limited to 'std_call_once_bug')
-rw-r--r-- | std_call_once_bug/CMakeLists.txt | 5 | ||||
-rw-r--r-- | std_call_once_bug/README.md | 26 | ||||
-rw-r--r-- | std_call_once_bug/sample.cpp | 131 |
3 files changed, 0 insertions, 162 deletions
diff --git a/std_call_once_bug/CMakeLists.txt b/std_call_once_bug/CMakeLists.txt deleted file mode 100644 index 31d45de..0000000 --- a/std_call_once_bug/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -project(std_call_once_bug CXX) - -include(../common.cmake) - -add_executable(sample sample.cpp) diff --git a/std_call_once_bug/README.md b/std_call_once_bug/README.md deleted file mode 100644 index 176dda0..0000000 --- a/std_call_once_bug/README.md +++ /dev/null @@ -1,26 +0,0 @@ -std::call_once bug in Visual C++ 2012/2013 -========================================== - -Code samples from the post "std::call_once bug in Visual C++ 2012/2013". - -Building --------- - -Create the build files using CMake and build using your native build tools -(Visual Studio/make/etc.). - -In the example below, the project directory is "C:\workspace\personal\blog" -and Visual Studio 2013 is used, targeting x86. - - > cmake -G "Visual Studio 12 2013" C:\workspace\personal\blog\std_call_once_bug - ... - - > cmake --build . --config release - ... - -See also --------- - -* [License] - -[License]: ../README.md#license diff --git a/std_call_once_bug/sample.cpp b/std_call_once_bug/sample.cpp deleted file mode 100644 index 01b5092..0000000 --- a/std_call_once_bug/sample.cpp +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright (c) 2016 Egor Tensin <Egor.Tensin@gmail.com> -// This file is part of the "Egor's blog" project. -// For details, see https://github.com/egor-tensin/blog. -// Distributed under the MIT License. - -#include <ctime> - -#include <chrono> -#include <iostream> -#include <mutex> -#include <sstream> -#include <string> -#include <thread> - -namespace -{ - template <typename Derived> - class Singleton - { - public: - static Derived& get_instance() - { - std::call_once(initialized_flag, &initialize_instance); - return Derived::get_instance_unsafe(); - } - - protected: - Singleton() = default; - ~Singleton() = default; - - static Derived& get_instance_unsafe() - { - static Derived instance; - return instance; - } - - private: - static void initialize_instance() - { - Derived::get_instance_unsafe(); - } - - static std::once_flag initialized_flag; - - Singleton(const Singleton&) = delete; - Singleton& operator=(const Singleton&) = delete; - }; - - template <typename Derived> - std::once_flag Singleton<Derived>::initialized_flag; - - class Logger : public Singleton<Logger> - { - public: - Logger& operator<<(const char*) - { - return *this; - } - - private: - Logger() - { - std::this_thread::sleep_for(std::chrono::seconds{3}); - } - - ~Logger() = default; - - friend class Singleton<Logger>; - }; - - class Duke : public Singleton<Duke> - { - private: - Duke() - { - Logger::get_instance() << "started Duke's initialization"; - std::this_thread::sleep_for(std::chrono::seconds{10}); - Logger::get_instance() << "finishing Duke's initialization"; - } - - ~Duke() = default; - - friend class Singleton<Duke>; - }; - - std::mutex timestamp_mtx; - - std::string get_timestamp() - { - std::lock_guard<std::mutex> lck{timestamp_mtx}; - const auto tt = std::time(NULL); - return std::ctime(&tt); - } - - void entered(const char* f) - { - std::ostringstream oss; - oss << "Entered " << f << " at " << get_timestamp(); - std::cout << oss.str(); - } - - void exiting(const char* f) - { - std::ostringstream oss; - oss << "Exiting " << f << " at " << get_timestamp(); - std::cout << oss.str(); - } - - void get_logger() - { - entered(__FUNCTION__); - Logger::get_instance(); - exiting(__FUNCTION__); - } - - void get_duke() - { - entered(__FUNCTION__); - Duke::get_instance(); - exiting(__FUNCTION__); - } -} - -int main() -{ - std::thread t1{&get_duke}; - std::thread t2{&get_logger}; - t1.join(); - t2.join(); - return 0; -} |