Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1740)

Unified Diff: runtime/bin/reference_counting.h

Issue 1852783003: Implements remaining SecurityContext calls for iOS (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Address comments Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: runtime/bin/reference_counting.h
diff --git a/runtime/bin/reference_counting.h b/runtime/bin/reference_counting.h
new file mode 100644
index 0000000000000000000000000000000000000000..a138526041716291b52dc69506474a4e7126df56
--- /dev/null
+++ b/runtime/bin/reference_counting.h
@@ -0,0 +1,159 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef BIN_REFERENCE_COUNTING_H_
+#define BIN_REFERENCE_COUNTING_H_
+
+#include "vm/atomic.h"
+
+namespace dart {
+namespace bin {
+
+// Forward declaration.
+template <class Target> class RefCntReleaseScope;
+
+// Inherit from this class where instances of the derived class should be
+// reference counted. Reference counts on instances are incremented and
+// decremented explicitly with calls to Retain() and Release(). E.g.:
+//
+// class Foo : public ReferenceCounted<Foo> {
+// public:
+// Foo() : ReferenceCounted() {}
+// ...
+// };
+//
+// void DoStuffWithAFoo() {
+// Foo* foo = new Foo();
+// foo->Retain();
+// ...
+// foo->Release();
+// }
+template <class Derived>
+class ReferenceCounted {
+ public:
+ ReferenceCounted() :
+ ref_count_(0) {
+ }
+
+ ~ReferenceCounted() {
+ ASSERT(ref_count_ == 0);
+ }
+
+ void Retain() {
+ uintptr_t old = AtomicOperations::FetchAndIncrement(&ref_count_);
+ ASSERT(old >= 0);
+ }
+
+ void Release() {
+ uintptr_t old = AtomicOperations::FetchAndDecrement(&ref_count_);
+ ASSERT(old > 0);
+ if (old == 1) {
+ delete static_cast<Derived*>(this);
siva 2016/04/12 19:03:01 You are using atomic operations so I assume the in
zra 2016/04/13 16:46:21 Changed so that ref_count_ is initialized to 1 in
+ }
+ }
+
+ private:
+ uintptr_t ref_count() const { return ref_count_; }
siva 2016/04/12 19:03:00 ref_count() is private and never used in this clas
zra 2016/04/13 16:46:21 It's used only for the ASSERT below in RefCntRelea
+
+ uintptr_t ref_count_;
+
+ friend class RefCntReleaseScope<Derived>;
+ DISALLOW_COPY_AND_ASSIGN(ReferenceCounted);
+};
+
+// Creates a scope at the end of which a reference counted object is
+// Released. This is useful for reference counted objects recieved by the IO
+// Service, which have already been Retained E.g.:
+//
+// CObject* Foo::FooRequest(const CObjectArray& request) {
+// Foo* foo = CObjectToFoo(request[0]);
+// RefCntReleaseScope<Foo> rs(foo);
+// ...
+// }
+template <class Target>
+class RefCntReleaseScope {
+ public:
+ explicit RefCntReleaseScope(ReferenceCounted<Target>* t) : target_(t) {
+ ASSERT(target_ != NULL);
+ ASSERT(target_->ref_count() > 0);
+ }
+ ~RefCntReleaseScope() {
+ target_->Release();
+ }
+
+ private:
+ ReferenceCounted<Target>* target_;
+
+ DISALLOW_ALLOCATION();
+ DISALLOW_COPY_AND_ASSIGN(RefCntReleaseScope);
+};
+
+// Instances of RetainedPointer manage Retaining and Releasing reference counted
+// objects. There are two ways to use it. First, it can be used as a field in
+// a class, e.g.:
+//
+// class Foo {
+// private:
+// RetainedPointer<Bar> bar_;
+// public:
+// explicit Foo(Bar* b) : bar_(b) {}
+// }
+//
+// In this case, b will be Retained in Foo's constructor, and Released
+// automatically during Foo's destructor.
+//
+// RetainedPointer can also be used as a scope, as with RefCntReleaseScope,
+// with the difference that entering the scope also Retains the pointer, e.g.:
+//
+// void RetainAndDoStuffWithFoo(Foo* foo) {
+// RetainedPointer<Foo> retained(foo);
+// ..
+// }
+//
+// This Retains foo on entry and Releases foo at every exit from the scope.
+//
+// The underlying pointer can be accessed with the get() and set() methods.
+// Overwriting a non-NULL pointer with set causes that pointer to be Released.
+template <class Target>
+class RetainedPointer {
+ public:
+ RetainedPointer() : target_(NULL) {}
+
+ explicit RetainedPointer(ReferenceCounted<Target>* t) : target_(t) {
+ if (target_ != NULL) {
+ target_->Retain();
+ }
+ }
+
+ ~RetainedPointer() {
+ if (target_ != NULL) {
+ target_->Release();
+ }
+ }
+
+ void set(ReferenceCounted<Target>* t) {
+ if (target_ != NULL) {
+ target_->Release();
+ }
+ target_ = t;
+ if (target_ != NULL) {
+ target_->Retain();
+ }
+ }
+
+ Target* get() const {
+ return static_cast<Target*>(target_);
+ }
siva 2016/04/12 19:03:01 Should this 'get' method be provided because it ma
zra 2016/04/13 16:46:21 When the RetainedPointer is a field in a class, th
+
+ private:
+ ReferenceCounted<Target>* target_;
+
+ DISALLOW_ALLOCATION();
+ DISALLOW_COPY_AND_ASSIGN(RetainedPointer);
+};
+
+} // namespace bin
+} // namespace dart
+
+#endif // BIN_REFERENCE_COUNTING_H_

Powered by Google App Engine
This is Rietveld 408576698