Advertisement
Guest User

Untitled

a guest
Dec 7th, 2019
92
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.96 KB | None | 0 0
  1. #include <iomanip>
  2. #include <iostream>
  3. #include <memory>
  4. #include <mutex>
  5. #include <optional>
  6. #include <vector>
  7.  
  8. // Took here cause lazy:
  9. // https://github.com/adobe/chromium/blob/master/third_party/tcmalloc/vendor/src/base/thread_annotations.h
  10.  
  11. #if defined(__GNUC__) && \
  12. (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)) && \
  13. defined(__SUPPORT_TS_ANNOTATION__) && (!defined(SWIG))
  14. #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x))
  15. #else
  16. #define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op
  17. #endif
  18.  
  19. #define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
  20. #define GUARDED_VAR THREAD_ANNOTATION_ATTRIBUTE__(guarded)
  21.  
  22. // Note: current implementation tightly couples contained object wrapper and
  23. // container because I was lazy. You can clean this up if you'd like.
  24.  
  25. struct ContainedObject {
  26. int value = 0;
  27. };
  28.  
  29. class Container {
  30. public:
  31. class ContainedObjectWrapper {
  32. public:
  33. ContainedObjectWrapper(std::unique_ptr<ContainedObject> contained_object,
  34. Container *parent_container)
  35. : contained_object_(std::move(contained_object)),
  36. parent_container_(parent_container) {}
  37. // Add error checking etc. if you need...
  38. ContainedObject &GetWrappedValue() { return *contained_object_; }
  39. ~ContainedObjectWrapper() {
  40. parent_container_->AddValue(std::move(contained_object_));
  41. // Unnecessary, but explicit.
  42. contained_object_ = nullptr;
  43. }
  44.  
  45. private:
  46. std::unique_ptr<ContainedObject> contained_object_;
  47. Container *parent_container_;
  48. };
  49.  
  50. // If you make a separate "GetValue" and "HasValue" you have potential "time
  51. // of check vs. time of use" kinds of bugs.
  52. std::unique_ptr<ContainedObjectWrapper> GetValueWrapper() {
  53. std::lock_guard<std::mutex> lock(mu_);
  54. if (values_.empty()) {
  55. return {};
  56. } else {
  57. auto retval = std::make_unique<ContainedObjectWrapper>(
  58. std::move(values_.back()), this);
  59. values_.pop_back();
  60. return retval;
  61. }
  62. }
  63. void AddValue(std::unique_ptr<ContainedObject> contained_object) {
  64. std::lock_guard<std::mutex> lock(mu_);
  65. values_.push_back(std::move(contained_object));
  66. }
  67.  
  68. private:
  69. std::vector<std::unique_ptr<ContainedObject>> values_ GUARDED_BY(mu_);
  70. std::mutex mu_;
  71. };
  72.  
  73. int main() {
  74. Container container;
  75. auto object = std::make_unique<ContainedObject>();
  76. object->value = 31337;
  77. container.AddValue(std::move(object));
  78. std::cout << std::boolalpha;
  79. {
  80. auto value_wrapper = container.GetValueWrapper();
  81. std::cout << (value_wrapper == nullptr) << '\n';
  82. auto &value = value_wrapper->GetWrappedValue();
  83. std::cout << value.value << '\n';
  84. }
  85. {
  86. auto value_wrapper = container.GetValueWrapper();
  87. std::cout << (value_wrapper == nullptr) << '\n';
  88. auto &value = value_wrapper->GetWrappedValue();
  89. std::cout << value.value << '\n';
  90. }
  91. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement