1// Copyright 2014 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#ifndef MOJO_PUBLIC_CPP_BINDINGS_LIB_SHARED_DATA_H_ 6#define MOJO_PUBLIC_CPP_BINDINGS_LIB_SHARED_DATA_H_ 7 8#include "mojo/public/cpp/system/macros.h" 9 10namespace mojo { 11namespace internal { 12 13// Used to allocate an instance of T that can be shared via reference counting. 14template <typename T> 15class SharedData { 16 public: 17 ~SharedData() { 18 holder_->Release(); 19 } 20 21 SharedData() : holder_(new Holder()) { 22 } 23 24 explicit SharedData(const T& value) : holder_(new Holder(value)) { 25 } 26 27 SharedData(const SharedData<T>& other) : holder_(other.holder_) { 28 holder_->Retain(); 29 } 30 31 SharedData<T>& operator=(const SharedData<T>& other) { 32 if (other.holder_ == holder_) 33 return *this; 34 holder_->Release(); 35 holder_ = other.holder_; 36 holder_->Retain(); 37 return *this; 38 } 39 40 void reset() { 41 holder_->Release(); 42 holder_ = new Holder(); 43 } 44 45 void reset(const T& value) { 46 holder_->Release(); 47 holder_ = new Holder(value); 48 } 49 50 void set_value(const T& value) { 51 holder_->value = value; 52 } 53 T* mutable_value() { 54 return &holder_->value; 55 } 56 const T& value() const { 57 return holder_->value; 58 } 59 60 private: 61 class Holder { 62 public: 63 Holder() : value(), ref_count_(1) { 64 } 65 Holder(const T& value) : value(value), ref_count_(1) { 66 } 67 68 void Retain() { ++ref_count_; } 69 void Release() { if (--ref_count_ == 0) delete this; } 70 71 T value; 72 73 private: 74 int ref_count_; 75 MOJO_DISALLOW_COPY_AND_ASSIGN(Holder); 76 }; 77 78 Holder* holder_; 79}; 80 81} // namespace internal 82} // namespace mojo 83 84#endif // MOJO_PUBLIC_CPP_BINDINGS_LIB_SHARED_DATA_H_ 85