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

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
« no previous file with comments | « runtime/bin/io_impl_sources.gypi ('k') | runtime/bin/secure_socket.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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..8e79f4fc5724b35bbcb2a546296ae5a77fa0b881
--- /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(); // Reference count starts at 1, so no explicit
+// // call to Retain is needed after allocation.
+// ...
+// foo->Release();
+// }
+template <class Derived>
+class ReferenceCounted {
+ public:
+ ReferenceCounted() :
+ ref_count_(1) {
+ }
+
+ ~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);
+ }
+ }
+
+ private:
+ uintptr_t ref_count_;
+
+ // These are used only in the ASSERT below in RefCntReleaseScope.
+ uintptr_t ref_count() const { return 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_);
+ }
+
+ private:
+ ReferenceCounted<Target>* target_;
+
+ DISALLOW_ALLOCATION();
+ DISALLOW_COPY_AND_ASSIGN(RetainedPointer);
+};
+
+} // namespace bin
+} // namespace dart
+
+#endif // BIN_REFERENCE_COUNTING_H_
« no previous file with comments | « runtime/bin/io_impl_sources.gypi ('k') | runtime/bin/secure_socket.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698