atomic.h 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. // This file is part of Desktop App Toolkit,
  2. // a set of libraries for developing nice desktop applications.
  3. //
  4. // For license and copyright information please follow this link:
  5. // https://github.com/desktop-app/legal/blob/master/LEGAL
  6. //
  7. #pragma once
  8. #include <mutex>
  9. #include <memory>
  10. #include <condition_variable>
  11. namespace base {
  12. // Helper for macOS < 11.0 and GCC < 11 that don't have wait/notify.
  13. #if defined __cpp_lib_atomic_wait && !defined Q_OS_MAC
  14. using std::atomic;
  15. using std::atomic_notify_all;
  16. #else // __cpp_lib_atomic_wait
  17. template <typename Type>
  18. class atomic final {
  19. public:
  20. atomic(Type value) : _value(value) {
  21. }
  22. atomic &operator=(Type value) {
  23. _value = value;
  24. return *this;
  25. }
  26. [[nodiscard]] Type load() const {
  27. return _value.load();
  28. }
  29. void wait(Type whileEquals) {
  30. if (_value == whileEquals) {
  31. std::unique_lock<std::mutex> lock(_mutex);
  32. while (_value == whileEquals) {
  33. _condition.wait(lock);
  34. }
  35. }
  36. }
  37. friend inline bool operator==(const atomic &a, Type b) {
  38. return (a._value == b);
  39. }
  40. friend void atomic_notify_all(atomic *value) {
  41. std::unique_lock<std::mutex> lock(value->_mutex);
  42. value->_condition.notify_all();
  43. }
  44. private:
  45. std::atomic<Type> _value;
  46. std::mutex _mutex;
  47. std::condition_variable _condition;
  48. };
  49. #endif // __cpp_lib_atomic_wait
  50. } // namespace base