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