RefCountBase.java revision 80aed3c513dc6a6670e25ef6e11bc71ab6a2d9fd
1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.camera.async; 18 19import com.google.common.base.Preconditions; 20 21/** 22 * Wraps an object with reference counting. When the reference count goes to 0 23 * for the first time, the object is closed. 24 */ 25public class RefCountBase<T extends SafeCloseable> implements SafeCloseable { 26 private final Object mLock; 27 private final T mObject; 28 private int mRefCount; 29 private boolean mObjectClosed; 30 31 public RefCountBase(T object) { 32 this(object, 1); 33 } 34 35 public RefCountBase(T object, int initialReferenceCount) { 36 Preconditions.checkState( 37 initialReferenceCount > 0, "initialReferenceCount is not greater than 0."); 38 mLock = new Object(); 39 mObject = object; 40 mRefCount = initialReferenceCount; 41 mObjectClosed = false; 42 } 43 44 public void addRef() { 45 synchronized (mLock) { 46 Preconditions.checkState(!mObjectClosed, 47 "addRef on an object which has been closed."); 48 mRefCount++; 49 } 50 } 51 52 public T get() { 53 return mObject; 54 } 55 56 @Override 57 public void close() { 58 synchronized (mLock) { 59 // A SafeCloseable must tolerate multiple calls to close(). 60 if (mObjectClosed) { 61 return; 62 } 63 mRefCount--; 64 if (mRefCount > 0) { 65 return; 66 } 67 mObjectClosed = true; 68 } 69 // Do this outside of the mLock critical section for speed and to avoid 70 // deadlock. 71 mObject.close(); 72 } 73} 74