diff options
| author | Stanislaw Halik <sthalik@misaki.pl> | 2018-12-29 13:27:21 +0100 | 
|---|---|---|
| committer | Stanislaw Halik <sthalik@misaki.pl> | 2019-01-16 07:48:18 +0100 | 
| commit | e9bbb68829e972df2e458aa5beec0568d4737f02 (patch) | |
| tree | b305103d53214dcddb76c1f26738d334972b17d3 /compat | |
| parent | a1a9a091093c9fb711a1665de9f4d46ae5c5ab67 (diff) | |
compat/spinlock: implement and use it
Diffstat (limited to 'compat')
| -rw-r--r-- | compat/check-visible.cpp | 37 | ||||
| -rw-r--r-- | compat/check-visible.hpp | 6 | ||||
| -rw-r--r-- | compat/spinlock.hpp | 30 | 
3 files changed, 52 insertions, 21 deletions
| diff --git a/compat/check-visible.cpp b/compat/check-visible.cpp index 4cdb1b46..d7f24177 100644 --- a/compat/check-visible.cpp +++ b/compat/check-visible.cpp @@ -1,31 +1,33 @@  #include "check-visible.hpp" -#if defined _WIN32 - +#include "macros.hpp"  #include "timer.hpp" -#include "math.hpp" +#include "spinlock.hpp" -#include <QMutex> +#include <QWidget>  #include <QDebug> -#include <windows.h> -  constexpr int visible_timeout = 1000;  constexpr int invisible_timeout = 250;  static Timer timer; -static QMutex mtx; +static std::atomic_flag lock = ATOMIC_FLAG_INIT;  static bool visible = true; +#if defined _WIN32 + +#include <windows.h> +  void set_is_visible(const QWidget& w, bool force)  { -    QMutexLocker l(&mtx); +    spinlock_guard l(lock); + +    HWND hwnd = (HWND)w.winId();      if (!force && timer.elapsed_ms() < (visible ? visible_timeout : invisible_timeout))          return;      timer.start(); -    HWND hwnd = (HWND)w.winId();      if (RECT r; GetWindowRect(hwnd, &r))      { @@ -56,22 +58,21 @@ void set_is_visible(const QWidget& w, bool force)      }  } -bool check_is_visible() -{ -    QMutexLocker l(&mtx); - -    return visible; -} -  #else  void set_is_visible(const QWidget&, bool)  {  } -bool check_is_visible() +void check_is_visible(bool)  { -    return true;  }  #endif + +bool check_is_visible() +{ +    spinlock_guard l(lock); +    return visible; +} + diff --git a/compat/check-visible.hpp b/compat/check-visible.hpp index e24a654b..5b194c7c 100644 --- a/compat/check-visible.hpp +++ b/compat/check-visible.hpp @@ -1,12 +1,12 @@  #pragma once  #include "export.hpp" -#include "macros.hpp" +#include "macros1.h" -#include <QWidget> +class QWidget;  cc_noinline OTR_COMPAT_EXPORT  void set_is_visible(QWidget const& w, bool force = false); -cc_noinline OTR_COMPAT_EXPORT +OTR_COMPAT_EXPORT  bool check_is_visible(); diff --git a/compat/spinlock.hpp b/compat/spinlock.hpp new file mode 100644 index 00000000..7e4cd8cf --- /dev/null +++ b/compat/spinlock.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "macros1.h" +#include <atomic> + +struct spinlock_guard final +{ +    spinlock_guard(const spinlock_guard&) = delete; +    spinlock_guard& operator=(const spinlock_guard&) = delete; +    constexpr spinlock_guard(spinlock_guard&&) noexcept = default; + +    cc_forceinline +    spinlock_guard(std::atomic_flag* lock) noexcept : spinlock_guard(*lock) {} + +    cc_forceinline +    spinlock_guard(std::atomic_flag& lock) noexcept : lock(lock) +    { +        while (lock.test_and_set(std::memory_order_acquire)) +            (void)0; +    } + +    cc_forceinline +    ~spinlock_guard() noexcept +    { +        lock.clear(std::memory_order_release); +    } + +private: +    std::atomic_flag& lock; +}; | 
