19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "RefBase" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/RefBase.h> 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Atomic.h> 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/CallStack.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/KeyedVector.h> 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/threads.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <typeinfo> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/types.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/stat.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h> 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// compile with refcounting debugging enabled 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define DEBUG_REFS 0 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define DEBUG_REFS_ENABLED_BY_DEFAULT 1 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define DEBUG_REFS_CALLSTACK_ENABLED 1 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// log all reference counting operations 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define PRINT_REFS 0 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define INITIAL_STRONG_VALUE (1<<28) 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass RefBase::weakref_impl : public RefBase::weakref_type 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project volatile int32_t mStrong; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project volatile int32_t mWeak; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RefBase* const mBase; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project volatile int32_t mFlags; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if !DEBUG_REFS 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl(RefBase* base) 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mStrong(INITIAL_STRONG_VALUE) 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mWeak(0) 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mBase(base) 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mFlags(0) 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void addStrongRef(const void* /*id*/) { } 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void removeStrongRef(const void* /*id*/) { } 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void addWeakRef(const void* /*id*/) { } 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void removeWeakRef(const void* /*id*/) { } 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void printRefs() const { } 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void trackMe(bool, bool) { } 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl(RefBase* base) 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mStrong(INITIAL_STRONG_VALUE) 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mWeak(0) 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mBase(base) 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mFlags(0) 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mStrongRefs(NULL) 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mWeakRefs(NULL) 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT) 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mRetain(false) 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //LOGI("NEW weakref_impl %p for RefBase %p", this, base); 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~weakref_impl() 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ALWAYS_FATAL_IF(!mRetain && mStrongRefs != NULL, "Strong references remain!"); 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ALWAYS_FATAL_IF(!mRetain && mWeakRefs != NULL, "Weak references remain!"); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void addStrongRef(const void* id) 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addRef(&mStrongRefs, id, mStrong); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void removeStrongRef(const void* id) 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mRetain) 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeRef(&mStrongRefs, id); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addRef(&mStrongRefs, id, -mStrong); 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void addWeakRef(const void* id) 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addRef(&mWeakRefs, id, mWeak); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void removeWeakRef(const void* id) 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mRetain) 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeRef(&mWeakRefs, id); 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addRef(&mWeakRefs, id, -mWeak); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void trackMe(bool track, bool retain) 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTrackEnabled = track; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRetain = retain; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void printRefs() const 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 text; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoMutex _l(const_cast<weakref_impl*>(this)->mMutex); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char buf[128]; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text.append(buf); 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printRefsLocked(&text, mStrongRefs); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(buf, "Weak references on RefBase %p (weakref_type %p):\n", mBase, this); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text.append(buf); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printRefsLocked(&text, mWeakRefs); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char name[100]; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project snprintf(name, 100, "/data/%p.stack", this); 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rc = open(name, O_RDWR | O_CREAT | O_APPEND); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rc >= 0) { 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project write(rc, text.string(), text.length()); 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(rc); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("STACK TRACE for %p saved in %s", this, name); 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else LOGE("FAILED TO PRINT STACK TRACE for %p in %s: %s", this, 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name, strerror(errno)); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate: 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct ref_entry 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref_entry* next; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const void* id; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if DEBUG_REFS_CALLSTACK_ENABLED 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CallStack stack; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t ref; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void addRef(ref_entry** refs, const void* id, int32_t mRef) 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTrackEnabled) { 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoMutex _l(mMutex); 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref_entry* ref = new ref_entry; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Reference count at the time of the snapshot, but before the 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // update. Positive value means we increment, negative--we 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // decrement the reference count. 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref->ref = mRef; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref->id = id; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if DEBUG_REFS_CALLSTACK_ENABLED 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref->stack.update(2); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref->next = *refs; 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *refs = ref; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void removeRef(ref_entry** refs, const void* id) 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTrackEnabled) { 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoMutex _l(mMutex); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref_entry* ref = *refs; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (ref != NULL) { 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ref->id == id) { 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *refs = ref->next; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete ref; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs = &ref->next; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref = *refs; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p (weakref_type %p) that doesn't exist!", 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project id, mBase, this); 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void printRefsLocked(String8* out, const ref_entry* refs) const 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char buf[128]; 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (refs) { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char inc = refs->ref >= 0 ? '+' : '-'; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(buf, "\t%c ID %p (ref %d):\n", 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inc, refs->id, refs->ref); 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out->append(buf); 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if DEBUG_REFS_CALLSTACK_ENABLED 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out->append(refs->stack.toString("\t\t")); 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out->append("\t\t(call stacks disabled)"); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs = refs->next; 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex mMutex; 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref_entry* mStrongRefs; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref_entry* mWeakRefs; 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool mTrackEnabled; 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Collect stack traces on addref and removeref, instead of deleting the stack references 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // on removeref that match the address ones. 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool mRetain; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void addRef(KeyedVector<const void*, int32_t>* refs, const void* id) 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoMutex _l(mMutex); 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t i = refs->indexOfKey(id); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i >= 0) { 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ++(refs->editValueAt(i)); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i = refs->add(id, 1); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void removeRef(KeyedVector<const void*, int32_t>* refs, const void* id) 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoMutex _l(mMutex); 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ssize_t i = refs->indexOfKey(id); 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ALWAYS_FATAL_IF(i < 0, "RefBase: removing id %p that doesn't exist!", id); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i >= 0) { 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t val = --(refs->editValueAt(i)); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (val == 0) { 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs->removeItemsAt(i); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void printRefs(const KeyedVector<const void*, int32_t>& refs) 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const size_t N=refs.size(); 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (size_t i=0; i<N; i++) { 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printf("\tID %p: %d remain\n", refs.keyAt(i), refs.valueAt(i)); 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mutable Mutex mMutex; 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyedVector<const void*, int32_t> mStrongRefs; 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project KeyedVector<const void*, int32_t> mWeakRefs; 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::incStrong(const void* id) const 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl* const refs = mRefs; 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs->addWeakRef(id); 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs->incWeak(id); 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs->addStrongRef(id); 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int32_t c = android_atomic_inc(&refs->mStrong); 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs); 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if PRINT_REFS 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("incStrong of %p from %p: cnt=%d\n", this, id, c); 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c != INITIAL_STRONG_VALUE) { 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const_cast<RefBase*>(this)->onFirstRef(); 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::decStrong(const void* id) const 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl* const refs = mRefs; 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs->removeStrongRef(id); 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int32_t c = android_atomic_dec(&refs->mStrong); 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if PRINT_REFS 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("decStrong of %p from %p: cnt=%d\n", this, id, c); 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs); 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c == 1) { 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const_cast<RefBase*>(this)->onLastStrongRef(id); 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((refs->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) { 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete this; 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs->removeWeakRef(id); 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs->decWeak(id); 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::forceIncStrong(const void* id) const 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl* const refs = mRefs; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs->addWeakRef(id); 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs->incWeak(id); 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs->addStrongRef(id); 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int32_t c = android_atomic_inc(&refs->mStrong); 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow", 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs); 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if PRINT_REFS 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("forceIncStrong of %p from %p: cnt=%d\n", this, id, c); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (c) { 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case INITIAL_STRONG_VALUE: 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fall through... 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 0: 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const_cast<RefBase*>(this)->onFirstRef(); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t RefBase::getStrongCount() const 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mRefs->mStrong; 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectRefBase* RefBase::weakref_type::refBase() const 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return static_cast<const weakref_impl*>(this)->mBase; 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::weakref_type::incWeak(const void* id) 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl* const impl = static_cast<weakref_impl*>(this); 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project impl->addWeakRef(id); 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int32_t c = android_atomic_inc(&impl->mWeak); 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this); 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::weakref_type::decWeak(const void* id) 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl* const impl = static_cast<weakref_impl*>(this); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project impl->removeWeakRef(id); 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int32_t c = android_atomic_dec(&impl->mWeak); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ASSERT(c >= 1, "decWeak called on %p too many times", this); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c != 1) return; 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK) { 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (impl->mStrong == INITIAL_STRONG_VALUE) 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete impl->mBase; 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else { 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// LOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete impl; 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project impl->mBase->onLastWeakRef(id); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((impl->mFlags&OBJECT_LIFETIME_FOREVER) != OBJECT_LIFETIME_FOREVER) { 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete impl->mBase; 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool RefBase::weakref_type::attemptIncStrong(const void* id) 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project incWeak(id); 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl* const impl = static_cast<weakref_impl*>(this); 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t curCount = impl->mStrong; 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow", 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) { 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) { 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curCount = impl->mStrong; 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool allow; 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curCount == INITIAL_STRONG_VALUE) { 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Attempting to acquire first strong reference... this is allowed 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the object does NOT have a longer lifetime (meaning the 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // implementation doesn't need to see this), or if the implementation 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // allows it to happen. 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Attempting to revive the object... this is allowed 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the object DOES have a longer lifetime (so we can safely 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // call the object with only a weak ref) and the implementation 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // allows it to happen. 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allow) { 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project decWeak(id); 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curCount = android_atomic_inc(&impl->mStrong); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the strong reference count has already been incremented by 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // someone else, the implementor of onIncStrongAttempted() is holding 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // an unneeded reference. So call onLastStrongRef() here to remove it. 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (No, this is not pretty.) Note that we MUST NOT do this if we 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // are in fact acquiring the first reference. 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) { 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project impl->mBase->onLastStrongRef(id); 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project impl->addWeakRef(id); 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project impl->addStrongRef(id); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if PRINT_REFS 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curCount == INITIAL_STRONG_VALUE) { 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong); 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project impl->mBase->onFirstRef(); 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool RefBase::weakref_type::attemptIncWeak(const void* id) 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl* const impl = static_cast<weakref_impl*>(this); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t curCount = impl->mWeak; 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow", 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this); 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (curCount > 0) { 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) { 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curCount = impl->mWeak; 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curCount > 0) { 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project impl->addWeakRef(id); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return curCount > 0; 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t RefBase::weakref_type::getWeakCount() const 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return static_cast<const weakref_impl*>(this)->mWeak; 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::weakref_type::printRefs() const 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static_cast<const weakref_impl*>(this)->printRefs(); 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::weakref_type::trackMe(bool enable, bool retain) 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static_cast<const weakref_impl*>(this)->trackMe(enable, retain); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectRefBase::weakref_type* RefBase::createWeak(const void* id) const 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRefs->incWeak(id); 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mRefs; 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectRefBase::weakref_type* RefBase::getWeakRefs() const 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mRefs; 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectRefBase::RefBase() 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mRefs(new weakref_impl(this)) 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// LOGV("Creating refs %p with RefBase %p\n", mRefs, this); 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectRefBase::~RefBase() 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// LOGV("Destroying RefBase %p (refs %p)\n", this, mRefs); 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRefs->mWeak == 0) { 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// LOGV("Freeing refs %p of old RefBase %p\n", mRefs, this); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete mRefs; 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::extendObjectLifetime(int32_t mode) 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android_atomic_or(mode, &mRefs->mFlags); 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::onFirstRef() 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::onLastStrongRef(const void* /*id*/) 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool RefBase::onIncStrongAttempted(uint32_t flags, const void* id) 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (flags&FIRST_INC_STRONG) ? true : false; 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::onLastWeakRef(const void* /*id*/) 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 535