51-refstring.patch 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. diff --git a/src/include/refstring.h b/src/include/refstring.h
  2. index 0675b39..c32630c 100644
  3. --- a/src/include/refstring.h
  4. +++ b/src/include/refstring.h
  5. @@ -13,7 +13,13 @@
  6. #include <stdexcept>
  7. #include <cstddef>
  8. #include <cstring>
  9. +
  10. +#if !defined(_LIBCPP_HAS_NO_THREADS) && !defined(_LIBCPP_CXX03_LANG) && !defined(_LIBCPP_USE_ATOMIC)
  11. +#define _LIBCPP_USE_ATOMIC
  12. +#include <atomic>
  13. +#else
  14. #include "atomic_support.h"
  15. +#endif
  16. // MacOS and iOS used to ship with libstdc++, and still support old applications
  17. // linking against libstdc++. The libc++ and libstdc++ exceptions are supposed
  18. @@ -40,7 +46,11 @@ typedef int count_t;
  19. struct _Rep_base {
  20. std::size_t len;
  21. std::size_t cap;
  22. +#ifdef _LIBCPP_USE_ATOMIC
  23. + std::atomic<count_t> count;
  24. +#else
  25. count_t count;
  26. +#endif
  27. };
  28. inline _Rep_base* rep_from_data(const char *data_) noexcept {
  29. @@ -96,7 +106,11 @@ __libcpp_refstring::__libcpp_refstring(const __libcpp_refstring &s) noexcept
  30. : __imp_(s.__imp_)
  31. {
  32. if (__uses_refcount())
  33. +#ifdef _LIBCPP_USE_ATOMIC
  34. + rep_from_data(__imp_)->count.fetch_add(1);
  35. +#else
  36. __libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
  37. +#endif
  38. }
  39. inline
  40. @@ -105,10 +119,19 @@ __libcpp_refstring& __libcpp_refstring::operator=(__libcpp_refstring const& s) n
  41. struct _Rep_base *old_rep = rep_from_data(__imp_);
  42. __imp_ = s.__imp_;
  43. if (__uses_refcount())
  44. +#ifdef _LIBCPP_USE_ATOMIC
  45. + rep_from_data(__imp_)->count.fetch_add(1);
  46. +#else
  47. __libcpp_atomic_add(&rep_from_data(__imp_)->count, 1);
  48. +#endif
  49. +
  50. if (adjust_old_count)
  51. {
  52. +#ifdef _LIBCPP_USE_ATOMIC
  53. + if (old_rep->count.fetch_sub(1) == 0)
  54. +#else
  55. if (__libcpp_atomic_add(&old_rep->count, count_t(-1)) < 0)
  56. +#endif
  57. {
  58. ::operator delete(old_rep);
  59. }
  60. @@ -120,7 +143,11 @@ inline
  61. __libcpp_refstring::~__libcpp_refstring() {
  62. if (__uses_refcount()) {
  63. _Rep_base* rep = rep_from_data(__imp_);
  64. +#ifdef _LIBCPP_USE_ATOMIC
  65. + if (rep->count.fetch_sub(1) == 0) {
  66. +#else
  67. if (__libcpp_atomic_add(&rep->count, count_t(-1)) < 0) {
  68. +#endif
  69. ::operator delete(rep);
  70. }
  71. }