1cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project/* 2cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project 3cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * 4cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 5cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * you may not use this file except in compliance with the License. 6cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * You may obtain a copy of the License at 7cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * 8cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 9cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * 10cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 11cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 12cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * See the License for the specific language governing permissions and 14cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project * limitations under the License. 15cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project */ 16cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 17cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#define LOG_TAG "RefBase" 18da8ec4b634ffc165fc12f8ae2671d61e684bd248Mathias Agopian// #define LOG_NDEBUG 0 19cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 205bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn#include <fcntl.h> 215bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn#include <stdio.h> 225bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn#include <stdlib.h> 235bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn#include <sys/stat.h> 245bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn#include <sys/types.h> 255bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn#include <typeinfo> 265bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn#include <unistd.h> 275bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn 28cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/RefBase.h> 29cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 30cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/Atomic.h> 31cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/CallStack.h> 32cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/Log.h> 33cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#include <utils/threads.h> 34cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 355bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn#ifndef __unused 365bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn#define __unused __attribute__((__unused__)) 375bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn#endif 38cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 39cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// compile with refcounting debugging enabled 40cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#define DEBUG_REFS 0 416d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian 426d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian// whether ref-tracking is enabled by default, if not, trackMe(true, false) 436d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian// needs to be called explicitly 446d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian#define DEBUG_REFS_ENABLED_BY_DEFAULT 0 456d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian 466d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian// whether callstack are collected (significantly slows things down) 47cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#define DEBUG_REFS_CALLSTACK_ENABLED 1 48cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 496d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian// folder where stack traces are saved when DEBUG_REFS is enabled 506d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian// this folder needs to exist and be writable 516d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian#define DEBUG_REFS_CALLSTACK_PATH "/data/debug" 526d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian 53cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// log all reference counting operations 54cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#define PRINT_REFS 0 55cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 56cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// --------------------------------------------------------------------------- 57cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 58cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectnamespace android { 59cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 60cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#define INITIAL_STRONG_VALUE (1<<28) 61cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 62cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// --------------------------------------------------------------------------- 63cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 64cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectclass RefBase::weakref_impl : public RefBase::weakref_type 65cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 66cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectpublic: 67cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project volatile int32_t mStrong; 68cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project volatile int32_t mWeak; 69cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project RefBase* const mBase; 70cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project volatile int32_t mFlags; 719c8fa9ed4111c69c82ace01c8a7ac3beeacdce78Mathias Agopian 72cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if !DEBUG_REFS 73cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 74cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project weakref_impl(RefBase* base) 75cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mStrong(INITIAL_STRONG_VALUE) 76cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project , mWeak(0) 77cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project , mBase(base) 78cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project , mFlags(0) 79cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project { 80cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 81cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 82cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project void addStrongRef(const void* /*id*/) { } 83cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project void removeStrongRef(const void* /*id*/) { } 84ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { } 85cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project void addWeakRef(const void* /*id*/) { } 86cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project void removeWeakRef(const void* /*id*/) { } 87ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { } 88cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project void printRefs() const { } 89cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project void trackMe(bool, bool) { } 90cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 91cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#else 92cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 93cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project weakref_impl(RefBase* base) 94cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mStrong(INITIAL_STRONG_VALUE) 95cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project , mWeak(0) 96cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project , mBase(base) 97cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project , mFlags(0) 98cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project , mStrongRefs(NULL) 99cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project , mWeakRefs(NULL) 100cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT) 101cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project , mRetain(false) 102cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project { 103cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 104cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 105cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ~weakref_impl() 106cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project { 107ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian bool dumpStack = false; 108ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian if (!mRetain && mStrongRefs != NULL) { 109ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian dumpStack = true; 1101b781ab0e0e8d59a7a8d1140bf6dee96a48a160cSteve Block ALOGE("Strong references remain:"); 111ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian ref_entry* refs = mStrongRefs; 112ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian while (refs) { 113ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian char inc = refs->ref >= 0 ? '+' : '-'; 114eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref); 115ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian#if DEBUG_REFS_CALLSTACK_ENABLED 11655e0f1c8bdb5d7299ba0c79e084b7ac749eb4c3bIan McKellar refs->stack.log(LOG_TAG); 117ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian#endif 118ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian refs = refs->next; 119ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 120ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 121ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian 122ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian if (!mRetain && mWeakRefs != NULL) { 123ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian dumpStack = true; 1241b781ab0e0e8d59a7a8d1140bf6dee96a48a160cSteve Block ALOGE("Weak references remain!"); 125ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian ref_entry* refs = mWeakRefs; 126ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian while (refs) { 127ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian char inc = refs->ref >= 0 ? '+' : '-'; 128eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref); 129ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian#if DEBUG_REFS_CALLSTACK_ENABLED 13055e0f1c8bdb5d7299ba0c79e084b7ac749eb4c3bIan McKellar refs->stack.log(LOG_TAG); 131ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian#endif 132ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian refs = refs->next; 133ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 134ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 135ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian if (dumpStack) { 1361b781ab0e0e8d59a7a8d1140bf6dee96a48a160cSteve Block ALOGE("above errors at:"); 137d34a8cad1efa1c8da1c7b5ad81226b822064cf73Mathias Agopian CallStack stack(LOG_TAG); 138ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 139cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 140cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 141ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian void addStrongRef(const void* id) { 142eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block //ALOGD_IF(mTrackEnabled, 143ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // "addStrongRef: RefBase=%p, id=%p", mBase, id); 144cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project addRef(&mStrongRefs, id, mStrong); 145cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 146cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 147ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian void removeStrongRef(const void* id) { 148eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block //ALOGD_IF(mTrackEnabled, 149ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // "removeStrongRef: RefBase=%p, id=%p", mBase, id); 150ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian if (!mRetain) { 151cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project removeRef(&mStrongRefs, id); 152ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } else { 153cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project addRef(&mStrongRefs, id, -mStrong); 154ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 155cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 156cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 157ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian void renameStrongRefId(const void* old_id, const void* new_id) { 158eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block //ALOGD_IF(mTrackEnabled, 159ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // "renameStrongRefId: RefBase=%p, oid=%p, nid=%p", 160ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // mBase, old_id, new_id); 161ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian renameRefsId(mStrongRefs, old_id, new_id); 162ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 163ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian 164ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian void addWeakRef(const void* id) { 165cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project addRef(&mWeakRefs, id, mWeak); 166cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 167cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 168ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian void removeWeakRef(const void* id) { 169ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian if (!mRetain) { 170cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project removeRef(&mWeakRefs, id); 171ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } else { 172cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project addRef(&mWeakRefs, id, -mWeak); 173ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 174ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 175ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian 176ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian void renameWeakRefId(const void* old_id, const void* new_id) { 177ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian renameRefsId(mWeakRefs, old_id, new_id); 178cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 179cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 180cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project void trackMe(bool track, bool retain) 181cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project { 182cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mTrackEnabled = track; 183cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mRetain = retain; 184cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 185cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 186cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project void printRefs() const 187cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project { 188cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project String8 text; 189cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 190cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project { 191ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian Mutex::Autolock _l(mMutex); 192cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char buf[128]; 193cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this); 194cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project text.append(buf); 195cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project printRefsLocked(&text, mStrongRefs); 196cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project sprintf(buf, "Weak references on RefBase %p (weakref_type %p):\n", mBase, this); 197cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project text.append(buf); 198cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project printRefsLocked(&text, mWeakRefs); 199cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 200cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 201cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project { 202cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char name[100]; 2036d4419d9b130719dd2355861907dc8f87368a51cMathias Agopian snprintf(name, 100, DEBUG_REFS_CALLSTACK_PATH "/%p.stack", this); 204769828d2d44fca3829e628bb424aa426aa468ee9Mathias Agopian int rc = open(name, O_RDWR | O_CREAT | O_APPEND, 644); 205cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (rc >= 0) { 206cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project write(rc, text.string(), text.length()); 207cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project close(rc); 208eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("STACK TRACE for %p saved in %s", this, name); 209cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 2101b781ab0e0e8d59a7a8d1140bf6dee96a48a160cSteve Block else ALOGE("FAILED TO PRINT STACK TRACE for %p in %s: %s", this, 211cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project name, strerror(errno)); 212cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 213cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 214cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 215cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectprivate: 216cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project struct ref_entry 217cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project { 218cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ref_entry* next; 219cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const void* id; 220cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if DEBUG_REFS_CALLSTACK_ENABLED 221cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project CallStack stack; 222cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif 223cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project int32_t ref; 224cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project }; 225cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 226cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project void addRef(ref_entry** refs, const void* id, int32_t mRef) 227cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project { 228cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mTrackEnabled) { 229cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project AutoMutex _l(mMutex); 230ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian 231cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ref_entry* ref = new ref_entry; 232cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // Reference count at the time of the snapshot, but before the 233cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // update. Positive value means we increment, negative--we 234cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // decrement the reference count. 235cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ref->ref = mRef; 236cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ref->id = id; 237cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if DEBUG_REFS_CALLSTACK_ENABLED 238cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ref->stack.update(2); 239cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif 240cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ref->next = *refs; 241cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *refs = ref; 242cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 243cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 244cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 245cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project void removeRef(ref_entry** refs, const void* id) 246cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project { 247cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (mTrackEnabled) { 248cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project AutoMutex _l(mMutex); 249cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 250ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian ref_entry* const head = *refs; 251ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian ref_entry* ref = head; 252cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project while (ref != NULL) { 253cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (ref->id == id) { 254cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project *refs = ref->next; 255cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project delete ref; 256cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return; 257cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 258cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project refs = &ref->next; 259cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ref = *refs; 260cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 261ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian 2621b781ab0e0e8d59a7a8d1140bf6dee96a48a160cSteve Block ALOGE("RefBase: removing id %p on RefBase %p" 263ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian "(weakref_type %p) that doesn't exist!", 264ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian id, mBase, this); 265ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian 266ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian ref = head; 267ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian while (ref) { 268ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian char inc = ref->ref >= 0 ? '+' : '-'; 269eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("\t%c ID %p (ref %d):", inc, ref->id, ref->ref); 270ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian ref = ref->next; 271ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 272ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian 273d34a8cad1efa1c8da1c7b5ad81226b822064cf73Mathias Agopian CallStack stack(LOG_TAG); 274ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 275ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 276ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian 277ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian void renameRefsId(ref_entry* r, const void* old_id, const void* new_id) 278ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian { 279ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian if (mTrackEnabled) { 280ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian AutoMutex _l(mMutex); 281ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian ref_entry* ref = r; 282ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian while (ref != NULL) { 283ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian if (ref->id == old_id) { 284ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian ref->id = new_id; 285ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 286ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian ref = ref->next; 287ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 288cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 289cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 290cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 291cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project void printRefsLocked(String8* out, const ref_entry* refs) const 292cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project { 293cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char buf[128]; 294cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project while (refs) { 295cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project char inc = refs->ref >= 0 ? '+' : '-'; 296cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project sprintf(buf, "\t%c ID %p (ref %d):\n", 297cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project inc, refs->id, refs->ref); 298cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project out->append(buf); 299cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if DEBUG_REFS_CALLSTACK_ENABLED 300cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project out->append(refs->stack.toString("\t\t")); 301cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#else 302cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project out->append("\t\t(call stacks disabled)"); 303cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif 304cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project refs = refs->next; 305cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 306cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 307cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 308ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian mutable Mutex mMutex; 309cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ref_entry* mStrongRefs; 310cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project ref_entry* mWeakRefs; 311cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 312cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project bool mTrackEnabled; 313cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // Collect stack traces on addref and removeref, instead of deleting the stack references 314cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // on removeref that match the address ones. 315cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project bool mRetain; 316cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 317cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif 318cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}; 319cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 320cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project// --------------------------------------------------------------------------- 321cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 322cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::incStrong(const void* id) const 323cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 324cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project weakref_impl* const refs = mRefs; 325cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project refs->incWeak(id); 326cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 327cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project refs->addStrongRef(id); 328cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const int32_t c = android_atomic_inc(&refs->mStrong); 329ae07445e9793724324b93bb593fe20be2a386707Steve Block ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs); 330cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if PRINT_REFS 331eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c); 332cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif 333cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (c != INITIAL_STRONG_VALUE) { 334cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return; 335cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 336cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 337cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); 338ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian refs->mBase->onFirstRef(); 339cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 340cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 341cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::decStrong(const void* id) const 342cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 343cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project weakref_impl* const refs = mRefs; 344cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project refs->removeStrongRef(id); 345cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const int32_t c = android_atomic_dec(&refs->mStrong); 346cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if PRINT_REFS 347eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("decStrong of %p from %p: cnt=%d\n", this, id, c); 348cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif 349ae07445e9793724324b93bb593fe20be2a386707Steve Block ALOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs); 350cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (c == 1) { 351ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian refs->mBase->onLastStrongRef(id); 352ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) { 3539c8fa9ed4111c69c82ace01c8a7ac3beeacdce78Mathias Agopian delete this; 354cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 355cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 356cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project refs->decWeak(id); 357cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 358cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 359cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::forceIncStrong(const void* id) const 360cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 361cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project weakref_impl* const refs = mRefs; 362cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project refs->incWeak(id); 363cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 364cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project refs->addStrongRef(id); 365cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const int32_t c = android_atomic_inc(&refs->mStrong); 366ae07445e9793724324b93bb593fe20be2a386707Steve Block ALOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow", 367cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project refs); 368cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if PRINT_REFS 369eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("forceIncStrong of %p from %p: cnt=%d\n", this, id, c); 370cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif 371cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 372cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project switch (c) { 373cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project case INITIAL_STRONG_VALUE: 374cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); 375cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // fall through... 376cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project case 0: 377ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian refs->mBase->onFirstRef(); 378cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 379cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 380cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 381cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectint32_t RefBase::getStrongCount() const 382cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 383cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return mRefs->mStrong; 384cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 385cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 386cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectRefBase* RefBase::weakref_type::refBase() const 387cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 388cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return static_cast<const weakref_impl*>(this)->mBase; 389cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 390cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 391cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::weakref_type::incWeak(const void* id) 392cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 393cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project weakref_impl* const impl = static_cast<weakref_impl*>(this); 394cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project impl->addWeakRef(id); 3955bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn const int32_t c __unused = android_atomic_inc(&impl->mWeak); 396ae07445e9793724324b93bb593fe20be2a386707Steve Block ALOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this); 397cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 398cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 399ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian 400cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::weakref_type::decWeak(const void* id) 401cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 402cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project weakref_impl* const impl = static_cast<weakref_impl*>(this); 403cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project impl->removeWeakRef(id); 404cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project const int32_t c = android_atomic_dec(&impl->mWeak); 405ae07445e9793724324b93bb593fe20be2a386707Steve Block ALOG_ASSERT(c >= 1, "decWeak called on %p too many times", this); 406cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (c != 1) return; 407ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian 408ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) { 409ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // This is the regular lifetime case. The object is destroyed 410ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // when the last strong reference goes away. Since weakref_impl 411ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // outlive the object, it is not destroyed in the dtor, and 412ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // we'll have to do it here. 413ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian if (impl->mStrong == INITIAL_STRONG_VALUE) { 414ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // Special case: we never had a strong reference, so we need to 415ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // destroy the object now. 4169c8fa9ed4111c69c82ace01c8a7ac3beeacdce78Mathias Agopian delete impl->mBase; 417ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } else { 418b37fbe9f810545bf62468fea5958325caa3635beSteve Block // ALOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase); 419cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project delete impl; 420cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 421cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } else { 422ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER} 423cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project impl->mBase->onLastWeakRef(id); 424ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) { 425ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference 426ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // is gone, we can destroy the object. 4279c8fa9ed4111c69c82ace01c8a7ac3beeacdce78Mathias Agopian delete impl->mBase; 428cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 429cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 430cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 431cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 432cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectbool RefBase::weakref_type::attemptIncStrong(const void* id) 433cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 434cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project incWeak(id); 435cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 436cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project weakref_impl* const impl = static_cast<weakref_impl*>(this); 437cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project int32_t curCount = impl->mStrong; 438a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn 439a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn ALOG_ASSERT(curCount >= 0, 440a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn "attemptIncStrong called on %p after underflow", this); 441a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn 442cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) { 443a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // we're in the easy/common case of promoting a weak-reference 444a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // from an existing strong reference. 445cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) { 446cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project break; 447cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 448a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // the strong count has changed on us, we need to re-assert our 449a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // situation. 450cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project curCount = impl->mStrong; 451cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 452cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 453cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) { 454a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // we're now in the harder case of either: 455a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // - there never was a strong reference on us 456a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // - or, all strong references have been released 457a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) { 458a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // this object has a "normal" life-time, i.e.: it gets destroyed 459a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // when the last strong reference goes away 460a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn if (curCount <= 0) { 461a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // the last strong-reference got released, the object cannot 462a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // be revived. 463a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn decWeak(id); 464a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn return false; 465a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn } 466a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn 467a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // here, curCount == INITIAL_STRONG_VALUE, which means 468a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // there never was a strong-reference, so we can try to 469a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // promote this object; we need to do that atomically. 470a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn while (curCount > 0) { 471a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn if (android_atomic_cmpxchg(curCount, curCount + 1, 472a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn &impl->mStrong) == 0) { 473a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn break; 474a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn } 475a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // the strong count has changed on us, we need to re-assert our 476a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // situation (e.g.: another thread has inc/decStrong'ed us) 477a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn curCount = impl->mStrong; 478a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn } 479a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn 480a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn if (curCount <= 0) { 481a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // promote() failed, some other thread destroyed us in the 482a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // meantime (i.e.: strong count reached zero). 483a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn decWeak(id); 484a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn return false; 485a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn } 486cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } else { 487a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // this object has an "extended" life-time, i.e.: it can be 488a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // revived from a weak-reference only. 489a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // Ask the object's implementation if it agrees to be revived 490a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn if (!impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id)) { 491a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // it didn't so give-up. 492a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn decWeak(id); 493a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn return false; 494a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn } 495a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // grab a strong-reference, which is always safe due to the 496a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // extended life-time. 497a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn curCount = android_atomic_inc(&impl->mStrong); 498cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 499cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 500cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // If the strong reference count has already been incremented by 501cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // someone else, the implementor of onIncStrongAttempted() is holding 502cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // an unneeded reference. So call onLastStrongRef() here to remove it. 503cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // (No, this is not pretty.) Note that we MUST NOT do this if we 504cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project // are in fact acquiring the first reference. 505cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) { 506cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project impl->mBase->onLastStrongRef(id); 507cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 508cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 509cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 510cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project impl->addStrongRef(id); 511cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 512cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#if PRINT_REFS 513eb0953307ce75cec031aedbf21abff08e5a737e5Steve Block ALOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount); 514cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project#endif 515cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 516a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // now we need to fix-up the count if it was INITIAL_STRONG_VALUE 517a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // this must be done safely, i.e.: handle the case where several threads 518a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // were here in attemptIncStrong(). 519a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn curCount = impl->mStrong; 520a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn while (curCount >= INITIAL_STRONG_VALUE) { 521a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn ALOG_ASSERT(curCount > INITIAL_STRONG_VALUE, 522a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn "attemptIncStrong in %p underflowed to INITIAL_STRONG_VALUE", 523a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn this); 524a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn if (android_atomic_cmpxchg(curCount, curCount-INITIAL_STRONG_VALUE, 525a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn &impl->mStrong) == 0) { 526a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn break; 527a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn } 528a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // the strong-count changed on us, we need to re-assert the situation, 529a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn // for e.g.: it's possible the fix-up happened in another thread. 530a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn curCount = impl->mStrong; 531cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 532a729ab1e3be17ed20073f7c035df0433888164d6Dianne Hackborn 533cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return true; 534cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 535cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 536cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectbool RefBase::weakref_type::attemptIncWeak(const void* id) 537cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 538cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project weakref_impl* const impl = static_cast<weakref_impl*>(this); 539ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian 540cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project int32_t curCount = impl->mWeak; 541ae07445e9793724324b93bb593fe20be2a386707Steve Block ALOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow", 542cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project this); 543cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project while (curCount > 0) { 544cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) { 545cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project break; 546cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 547cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project curCount = impl->mWeak; 548cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 549cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 550cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project if (curCount > 0) { 551cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project impl->addWeakRef(id); 552cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 553cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 554cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return curCount > 0; 555cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 556cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 557cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectint32_t RefBase::weakref_type::getWeakCount() const 558cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 559cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return static_cast<const weakref_impl*>(this)->mWeak; 560cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 561cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 562cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::weakref_type::printRefs() const 563cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 564cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project static_cast<const weakref_impl*>(this)->printRefs(); 565cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 566cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 567cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::weakref_type::trackMe(bool enable, bool retain) 568cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 569ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian static_cast<weakref_impl*>(this)->trackMe(enable, retain); 570cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 571cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 572cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectRefBase::weakref_type* RefBase::createWeak(const void* id) const 573cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 574cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project mRefs->incWeak(id); 575cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return mRefs; 576cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 577cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 578cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectRefBase::weakref_type* RefBase::getWeakRefs() const 579cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 580cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return mRefs; 581cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 582cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 583cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectRefBase::RefBase() 584cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project : mRefs(new weakref_impl(this)) 585cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 586cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 587cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 588cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source ProjectRefBase::~RefBase() 589cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 590ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian if (mRefs->mStrong == INITIAL_STRONG_VALUE) { 591ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // we never acquired a strong (and/or weak) reference on this object. 5929c8fa9ed4111c69c82ace01c8a7ac3beeacdce78Mathias Agopian delete mRefs; 593ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } else { 594ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // life-time of this object is extended to WEAK or FOREVER, in 595ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // which case weakref_impl doesn't out-live the object and we 596ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // can free it now. 597ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) { 598ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // It's possible that the weak count is not 0 if the object 599ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // re-acquired a weak reference in its destructor 600ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian if (mRefs->mWeak == 0) { 601ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian delete mRefs; 602ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 603ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 604cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project } 605ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian // for debugging purposes, clear this. 606ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian const_cast<weakref_impl*&>(mRefs) = NULL; 607cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 608cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 609cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::extendObjectLifetime(int32_t mode) 610cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 611cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project android_atomic_or(mode, &mRefs->mFlags); 612cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 613cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 614cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::onFirstRef() 615cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 616cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 617cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 618cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::onLastStrongRef(const void* /*id*/) 619cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 620cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 621cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 6225bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzynbool RefBase::onIncStrongAttempted(uint32_t flags, const void* /*id*/) 623cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 624cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project return (flags&FIRST_INC_STRONG) ? true : false; 625cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 626cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project 627cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Projectvoid RefBase::onLastWeakRef(const void* /*id*/) 628cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project{ 629cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project} 630ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian 631ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian// --------------------------------------------------------------------------- 632ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian 633ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian#if DEBUG_REFS 6345bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzynvoid RefBase::renameRefs(size_t n, const ReferenceRenamer& renamer) { 635ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian for (size_t i=0 ; i<n ; i++) { 6366cd548c7154c1633a0ed318c31dd22c50a5f5d02Mathias Agopian renamer(i); 637ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian } 638ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian} 6395bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn#else 6405bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzynvoid RefBase::renameRefs(size_t /*n*/, const ReferenceRenamer& /*renamer*/) { } 6415bed8036644f552210a7cfcbed2d6d20cf2981b0Mark Salyzyn#endif 642ad09965050f8226fda6f5238db060ce65abaa71cMathias Agopian 6436cd548c7154c1633a0ed318c31dd22c50a5f5d02Mathias Agopianvoid RefBase::renameRefId(weakref_type* ref, 6446cd548c7154c1633a0ed318c31dd22c50a5f5d02Mathias Agopian const void* old_id, const void* new_id) { 6456cd548c7154c1633a0ed318c31dd22c50a5f5d02Mathias Agopian weakref_impl* const impl = static_cast<weakref_impl*>(ref); 6466cd548c7154c1633a0ed318c31dd22c50a5f5d02Mathias Agopian impl->renameStrongRefId(old_id, new_id); 6476cd548c7154c1633a0ed318c31dd22c50a5f5d02Mathias Agopian impl->renameWeakRefId(old_id, new_id); 6486cd548c7154c1633a0ed318c31dd22c50a5f5d02Mathias Agopian} 6496cd548c7154c1633a0ed318c31dd22c50a5f5d02Mathias Agopian 6506cd548c7154c1633a0ed318c31dd22c50a5f5d02Mathias Agopianvoid RefBase::renameRefId(RefBase* ref, 6516cd548c7154c1633a0ed318c31dd22c50a5f5d02Mathias Agopian const void* old_id, const void* new_id) { 6526cd548c7154c1633a0ed318c31dd22c50a5f5d02Mathias Agopian ref->mRefs->renameStrongRefId(old_id, new_id); 6536cd548c7154c1633a0ed318c31dd22c50a5f5d02Mathias Agopian ref->mRefs->renameWeakRefId(old_id, new_id); 6546cd548c7154c1633a0ed318c31dd22c50a5f5d02Mathias Agopian} 6556cd548c7154c1633a0ed318c31dd22c50a5f5d02Mathias Agopian 656cbb1011c95e0c25c29e40e203a6a31bccd029da3The Android Open Source Project}; // namespace android 657