• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 package org.webrtc;
12 
13 import androidx.annotation.Nullable;
14 import java.util.concurrent.atomic.AtomicInteger;
15 
16 /**
17  * Implementation of RefCounted that executes a Runnable once the ref count reaches zero.
18  */
19 class RefCountDelegate implements RefCounted {
20   private final AtomicInteger refCount = new AtomicInteger(1);
21   private final @Nullable Runnable releaseCallback;
22 
23   /**
24    * @param releaseCallback Callback that will be executed once the ref count reaches zero.
25    */
RefCountDelegate(@ullable Runnable releaseCallback)26   public RefCountDelegate(@Nullable Runnable releaseCallback) {
27     this.releaseCallback = releaseCallback;
28   }
29 
30   @Override
retain()31   public void retain() {
32     int updated_count = refCount.incrementAndGet();
33     if (updated_count < 2) {
34       throw new IllegalStateException("retain() called on an object with refcount < 1");
35     }
36   }
37 
38   @Override
release()39   public void release() {
40     int updated_count = refCount.decrementAndGet();
41     if (updated_count < 0) {
42       throw new IllegalStateException("release() called on an object with refcount < 1");
43     }
44     if (updated_count == 0 && releaseCallback != null) {
45       releaseCallback.run();
46     }
47   }
48 
49   /**
50    * Tries to retain the object. Can be used in scenarios where it is unknown if the object has
51    * already been released. Returns true if successful or false if the object was already released.
52    */
safeRetain()53   boolean safeRetain() {
54     int currentRefCount = refCount.get();
55     while (currentRefCount != 0) {
56       if (refCount.weakCompareAndSet(currentRefCount, currentRefCount + 1)) {
57         return true;
58       }
59       currentRefCount = refCount.get();
60     }
61     return false;
62   }
63 }
64