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