From 9d071d2a2cec9a7662a02669488569a017f0ea35 Mon Sep 17 00:00:00 2001 From: Daniel Wilhelm Date: Mon, 13 Feb 2017 21:25:04 -0700 Subject: 8.9 --- zen/globals.h | 125 ++++++++++++++++++++++++++++------------------------------ 1 file changed, 61 insertions(+), 64 deletions(-) mode change 100644 => 100755 zen/globals.h (limited to 'zen/globals.h') diff --git a/zen/globals.h b/zen/globals.h old mode 100644 new mode 100755 index 123028c7..a1fd2764 --- a/zen/globals.h +++ b/zen/globals.h @@ -1,64 +1,61 @@ -// ***************************************************************************** -// * This file is part of the FreeFileSync project. It is distributed under * -// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 * -// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved * -// ***************************************************************************** - -#ifndef GLOBALS_H_8013740213748021573485 -#define GLOBALS_H_8013740213748021573485 - -#include -#include -#include "scope_guard.h" - -namespace zen -{ -//solve static destruction order fiasco by providing shared ownership and serialized access to global variables -template -class Global -{ -public: - Global() { static_assert(std::is_trivially_destructible::value, "this memory needs to live forever"); } - explicit Global(std::unique_ptr&& newInst) { set(std::move(newInst)); } - ~Global() { set(nullptr); } - - std::shared_ptr get() //=> return std::shared_ptr to let instance life time be handled by caller (MT usage!) - { - while (pod.spinLock.exchange(true)) ; - ZEN_ON_SCOPE_EXIT(pod.spinLock = false); - if (pod.inst) - return *pod.inst; - return nullptr; - } - - void set(std::unique_ptr&& newInst) - { - std::shared_ptr* tmpInst = nullptr; - if (newInst) - tmpInst = new std::shared_ptr(std::move(newInst)); - { - while (pod.spinLock.exchange(true)) ; - ZEN_ON_SCOPE_EXIT(pod.spinLock = false); - std::swap(pod.inst, tmpInst); - } - delete tmpInst; - } - -private: - //avoid static destruction order fiasco: there may be accesses to "Global::get()" during process shutdown - //e.g. _("") used by message in debug_minidump.cpp or by some detached thread assembling an error message! - //=> use trivially-destructible POD only!!! - struct Pod - { - std::shared_ptr* inst = nullptr; - //serialize access; can't use std::mutex: has non-trival destructor - std::atomic spinLock { false }; - } pod; -}; - -#if defined _MSC_VER && _MSC_VER < 1900 - #error function scope static initialization is not yet thread-safe! -#endif -} - -#endif //GLOBALS_H_8013740213748021573485 +// ***************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl-3.0 * +// * Copyright (C) Zenju (zenju AT freefilesync DOT org) - All Rights Reserved * +// ***************************************************************************** + +#ifndef GLOBALS_H_8013740213748021573485 +#define GLOBALS_H_8013740213748021573485 + +#include +#include +#include "scope_guard.h" + +namespace zen +{ +//solve static destruction order fiasco by providing shared ownership and serialized access to global variables +template +class Global +{ +public: + Global() { static_assert(std::is_trivially_destructible::value, "this memory needs to live forever"); } + explicit Global(std::unique_ptr&& newInst) { set(std::move(newInst)); } + ~Global() { set(nullptr); } + + std::shared_ptr get() //=> return std::shared_ptr to let instance life time be handled by caller (MT usage!) + { + while (pod.spinLock.exchange(true)) ; + ZEN_ON_SCOPE_EXIT(pod.spinLock = false); + if (pod.inst) + return *pod.inst; + return nullptr; + } + + void set(std::unique_ptr&& newInst) + { + std::shared_ptr* tmpInst = nullptr; + if (newInst) + tmpInst = new std::shared_ptr(std::move(newInst)); + { + while (pod.spinLock.exchange(true)) ; + ZEN_ON_SCOPE_EXIT(pod.spinLock = false); + std::swap(pod.inst, tmpInst); + } + delete tmpInst; + } + +private: + //avoid static destruction order fiasco: there may be accesses to "Global::get()" during process shutdown + //e.g. _("") used by message in debug_minidump.cpp or by some detached thread assembling an error message! + //=> use trivially-destructible POD only!!! + struct Pod + { + std::shared_ptr* inst = nullptr; + //serialize access; can't use std::mutex: has non-trival destructor + std::atomic spinLock { false }; + } pod; +}; + +} + +#endif //GLOBALS_H_8013740213748021573485 -- cgit