stop_source.h 3.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. // -*- C++ -*-
  2. //===----------------------------------------------------------------------===//
  3. //
  4. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  5. // See https://llvm.org/LICENSE.txt for license information.
  6. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef _LIBCPP___STOP_TOKEN_STOP_SOURCE_H
  10. #define _LIBCPP___STOP_TOKEN_STOP_SOURCE_H
  11. #include <__availability>
  12. #include <__config>
  13. #include <__stop_token/intrusive_shared_ptr.h>
  14. #include <__stop_token/stop_state.h>
  15. #include <__stop_token/stop_token.h>
  16. #include <__utility/move.h>
  17. #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
  18. # pragma GCC system_header
  19. #endif
  20. _LIBCPP_BEGIN_NAMESPACE_STD
  21. #if _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN) && !defined(_LIBCPP_HAS_NO_THREADS)
  22. struct nostopstate_t {
  23. explicit nostopstate_t() = default;
  24. };
  25. inline constexpr nostopstate_t nostopstate{};
  26. class _LIBCPP_AVAILABILITY_SYNC stop_source {
  27. public:
  28. _LIBCPP_HIDE_FROM_ABI stop_source() : __state_(new __stop_state()) { __state_->__increment_stop_source_counter(); }
  29. _LIBCPP_HIDE_FROM_ABI explicit stop_source(nostopstate_t) noexcept : __state_(nullptr) {}
  30. _LIBCPP_HIDE_FROM_ABI stop_source(const stop_source& __other) noexcept : __state_(__other.__state_) {
  31. if (__state_) {
  32. __state_->__increment_stop_source_counter();
  33. }
  34. }
  35. _LIBCPP_HIDE_FROM_ABI stop_source(stop_source&& __other) noexcept = default;
  36. _LIBCPP_HIDE_FROM_ABI stop_source& operator=(const stop_source& __other) noexcept {
  37. // increment `__other` first so that we don't hit 0 in case of self-assignment
  38. if (__other.__state_) {
  39. __other.__state_->__increment_stop_source_counter();
  40. }
  41. if (__state_) {
  42. __state_->__decrement_stop_source_counter();
  43. }
  44. __state_ = __other.__state_;
  45. return *this;
  46. }
  47. _LIBCPP_HIDE_FROM_ABI stop_source& operator=(stop_source&&) noexcept = default;
  48. _LIBCPP_HIDE_FROM_ABI ~stop_source() {
  49. if (__state_) {
  50. __state_->__decrement_stop_source_counter();
  51. }
  52. }
  53. _LIBCPP_HIDE_FROM_ABI void swap(stop_source& __other) noexcept { __state_.swap(__other.__state_); }
  54. [[nodiscard]] _LIBCPP_HIDE_FROM_ABI stop_token get_token() const noexcept { return stop_token(__state_); }
  55. [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool stop_possible() const noexcept { return __state_ != nullptr; }
  56. [[nodiscard]] _LIBCPP_HIDE_FROM_ABI bool stop_requested() const noexcept {
  57. return __state_ != nullptr && __state_->__stop_requested();
  58. }
  59. _LIBCPP_HIDE_FROM_ABI bool request_stop() noexcept { return __state_ && __state_->__request_stop(); }
  60. [[nodiscard]] _LIBCPP_HIDE_FROM_ABI friend bool operator==(const stop_source&, const stop_source&) noexcept = default;
  61. _LIBCPP_HIDE_FROM_ABI friend void swap(stop_source& __lhs, stop_source& __rhs) noexcept { __lhs.swap(__rhs); }
  62. private:
  63. __intrusive_shared_ptr<__stop_state> __state_;
  64. };
  65. #endif // _LIBCPP_STD_VER >= 20
  66. _LIBCPP_END_NAMESPACE_STD
  67. #endif // _LIBCPP_STD_VER >= 20 && !defined(_LIBCPP_HAS_NO_EXPERIMENTAL_STOP_TOKEN) && !defined(_LIBCPP_HAS_NO_THREADS)