19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2005 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "RefBase" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/RefBase.h> 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Atomic.h> 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/CallStack.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h> 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/threads.h> 25a688b574d294faae5f56224908b40856c5045aacMathias Agopian#include <utils/TextOutput.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <typeinfo> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/types.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/stat.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <fcntl.h> 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// compile with refcounting debugging enabled 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define DEBUG_REFS 0 37ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian#define DEBUG_REFS_FATAL_SANITY_CHECKS 0 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define DEBUG_REFS_ENABLED_BY_DEFAULT 1 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define DEBUG_REFS_CALLSTACK_ENABLED 1 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// log all reference counting operations 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define PRINT_REFS 0 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define INITIAL_STRONG_VALUE (1<<28) 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectclass RefBase::weakref_impl : public RefBase::weakref_type 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic: 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project volatile int32_t mStrong; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project volatile int32_t mWeak; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project RefBase* const mBase; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project volatile int32_t mFlags; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if !DEBUG_REFS 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl(RefBase* base) 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mStrong(INITIAL_STRONG_VALUE) 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mWeak(0) 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mBase(base) 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mFlags(0) 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void addStrongRef(const void* /*id*/) { } 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void removeStrongRef(const void* /*id*/) { } 72ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian void renameStrongRefId(const void* /*old_id*/, const void* /*new_id*/) { } 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void addWeakRef(const void* /*id*/) { } 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void removeWeakRef(const void* /*id*/) { } 75ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian void renameWeakRefId(const void* /*old_id*/, const void* /*new_id*/) { } 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void printRefs() const { } 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void trackMe(bool, bool) { } 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl(RefBase* base) 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mStrong(INITIAL_STRONG_VALUE) 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mWeak(0) 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mBase(base) 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mFlags(0) 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mStrongRefs(NULL) 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mWeakRefs(NULL) 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT) 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project , mRetain(false) 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ~weakref_impl() 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 95ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian bool dumpStack = false; 96ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian if (!mRetain && mStrongRefs != NULL) { 97ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian dumpStack = true; 98ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian#if DEBUG_REFS_FATAL_SANITY_CHECKS 99ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian LOG_ALWAYS_FATAL("Strong references remain!"); 100ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian#else 10132a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian LOGE("Strong references remain:"); 102ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian#endif 10332a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian ref_entry* refs = mStrongRefs; 10432a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian while (refs) { 10532a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian char inc = refs->ref >= 0 ? '+' : '-'; 10632a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian LOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref); 10732a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian#if DEBUG_REFS_CALLSTACK_ENABLED 10832a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian refs->stack.dump(); 1096fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian#endif 11032a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian refs = refs->next; 11132a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian } 112ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian } 113ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian 114ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian if (!mRetain && mWeakRefs != NULL) { 115ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian dumpStack = true; 116ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian#if DEBUG_REFS_FATAL_SANITY_CHECKS 11732a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian LOG_ALWAYS_FATAL("Weak references remain:"); 118ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian#else 119ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian LOGE("Weak references remain!"); 120ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian#endif 12132a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian ref_entry* refs = mWeakRefs; 12232a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian while (refs) { 12332a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian char inc = refs->ref >= 0 ? '+' : '-'; 12432a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian LOGD("\t%c ID %p (ref %d):", inc, refs->id, refs->ref); 12532a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian#if DEBUG_REFS_CALLSTACK_ENABLED 12632a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian refs->stack.dump(); 1276fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian#endif 12832a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian refs = refs->next; 12932a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian } 130ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian } 131ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian if (dumpStack) { 13232a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian LOGE("above errors at:"); 133ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian CallStack stack; 134ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian stack.update(); 135ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian stack.dump(); 136ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian } 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 139ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian void addStrongRef(const void* id) { 140ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian //LOGD_IF(mTrackEnabled, 141ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian // "addStrongRef: RefBase=%p, id=%p", mBase, id); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addRef(&mStrongRefs, id, mStrong); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 145ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian void removeStrongRef(const void* id) { 146ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian //LOGD_IF(mTrackEnabled, 147ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian // "removeStrongRef: RefBase=%p, id=%p", mBase, id); 148ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian if (!mRetain) { 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeRef(&mStrongRefs, id); 150ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian } else { 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addRef(&mStrongRefs, id, -mStrong); 152ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian } 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 155ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian void renameStrongRefId(const void* old_id, const void* new_id) { 156ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian //LOGD_IF(mTrackEnabled, 157ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian // "renameStrongRefId: RefBase=%p, oid=%p, nid=%p", 158ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian // mBase, old_id, new_id); 159ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian renameRefsId(mStrongRefs, old_id, new_id); 160ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian } 161ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian 162ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian void addWeakRef(const void* id) { 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addRef(&mWeakRefs, id, mWeak); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 166ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian void removeWeakRef(const void* id) { 167ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian if (!mRetain) { 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeRef(&mWeakRefs, id); 169ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian } else { 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addRef(&mWeakRefs, id, -mWeak); 171ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian } 172ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian } 173ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian 174ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian void renameWeakRefId(const void* old_id, const void* new_id) { 175ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian renameRefsId(mWeakRefs, old_id, new_id); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void trackMe(bool track, bool retain) 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTrackEnabled = track; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRetain = retain; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void printRefs() const 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String8 text; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 1896fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian Mutex::Autolock _l(mMutex); 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char buf[128]; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(buf, "Strong references on RefBase %p (weakref_type %p):\n", mBase, this); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text.append(buf); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printRefsLocked(&text, mStrongRefs); 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(buf, "Weak references on RefBase %p (weakref_type %p):\n", mBase, this); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project text.append(buf); 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project printRefsLocked(&text, mWeakRefs); 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char name[100]; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project snprintf(name, 100, "/data/%p.stack", this); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int rc = open(name, O_RDWR | O_CREAT | O_APPEND); 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (rc >= 0) { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project write(rc, text.string(), text.length()); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(rc); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("STACK TRACE for %p saved in %s", this, name); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project else LOGE("FAILED TO PRINT STACK TRACE for %p in %s: %s", this, 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name, strerror(errno)); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectprivate: 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct ref_entry 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref_entry* next; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const void* id; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if DEBUG_REFS_CALLSTACK_ENABLED 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project CallStack stack; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t ref; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project }; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void addRef(ref_entry** refs, const void* id, int32_t mRef) 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTrackEnabled) { 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoMutex _l(mMutex); 228ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref_entry* ref = new ref_entry; 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Reference count at the time of the snapshot, but before the 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // update. Positive value means we increment, negative--we 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // decrement the reference count. 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref->ref = mRef; 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref->id = id; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if DEBUG_REFS_CALLSTACK_ENABLED 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref->stack.update(2); 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref->next = *refs; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *refs = ref; 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void removeRef(ref_entry** refs, const void* id) 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTrackEnabled) { 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project AutoMutex _l(mMutex); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24832a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian ref_entry* const head = *refs; 24932a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian ref_entry* ref = head; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (ref != NULL) { 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ref->id == id) { 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *refs = ref->next; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete ref; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs = &ref->next; 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref = *refs; 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 259ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian 260ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian#if DEBUG_REFS_FATAL_SANITY_CHECKS 261ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian LOG_ALWAYS_FATAL("RefBase: removing id %p on RefBase %p" 262ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian "(weakref_type %p) that doesn't exist!", 263ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian id, mBase, this); 264ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian#endif 265ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian 266ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian LOGE("RefBase: removing id %p on RefBase %p" 267ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian "(weakref_type %p) that doesn't exist!", 268ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian id, mBase, this); 269ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian 27032a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian ref = head; 27132a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian while (ref) { 27232a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian char inc = ref->ref >= 0 ? '+' : '-'; 27332a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian LOGD("\t%c ID %p (ref %d):", inc, ref->id, ref->ref); 27432a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian ref = ref->next; 27532a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian } 27632a55cf66e12e5e56d2e05b73c6bef453477c2bbMathias Agopian 277ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian CallStack stack; 278ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian stack.update(); 279ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian stack.dump(); 280ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian } 281ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian } 282ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian 283ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian void renameRefsId(ref_entry* r, const void* old_id, const void* new_id) 284ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian { 285ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian if (mTrackEnabled) { 286ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian AutoMutex _l(mMutex); 287ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian ref_entry* ref = r; 288ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian while (ref != NULL) { 289ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian if (ref->id == old_id) { 290ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian ref->id = new_id; 291ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian } 292ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian ref = ref->next; 293ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian } 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void printRefsLocked(String8* out, const ref_entry* refs) const 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char buf[128]; 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (refs) { 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char inc = refs->ref >= 0 ? '+' : '-'; 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(buf, "\t%c ID %p (ref %d):\n", 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project inc, refs->id, refs->ref); 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out->append(buf); 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if DEBUG_REFS_CALLSTACK_ENABLED 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out->append(refs->stack.toString("\t\t")); 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out->append("\t\t(call stacks disabled)"); 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs = refs->next; 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3146fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian mutable Mutex mMutex; 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref_entry* mStrongRefs; 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ref_entry* mWeakRefs; 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool mTrackEnabled; 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Collect stack traces on addref and removeref, instead of deleting the stack references 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // on removeref that match the address ones. 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool mRetain; 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// --------------------------------------------------------------------------- 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::incStrong(const void* id) const 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl* const refs = mRefs; 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs->incWeak(id); 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs->addStrongRef(id); 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int32_t c = android_atomic_inc(&refs->mStrong); 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs); 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if PRINT_REFS 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("incStrong of %p from %p: cnt=%d\n", this, id, c); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c != INITIAL_STRONG_VALUE) { 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); 3446fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian refs->mBase->onFirstRef(); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::decStrong(const void* id) const 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl* const refs = mRefs; 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs->removeStrongRef(id); 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int32_t c = android_atomic_dec(&refs->mStrong); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if PRINT_REFS 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("decStrong of %p from %p: cnt=%d\n", this, id, c); 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ASSERT(c >= 1, "decStrong() called on %p too many times", refs); 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c == 1) { 3576fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian refs->mBase->onLastStrongRef(id); 3586fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian if ((refs->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_STRONG) { 3596fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian delete this; 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs->decWeak(id); 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::forceIncStrong(const void* id) const 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl* const refs = mRefs; 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs->incWeak(id); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs->addStrongRef(id); 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int32_t c = android_atomic_inc(&refs->mStrong); 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ASSERT(c >= 0, "forceIncStrong called on %p after ref count underflow", 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project refs); 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if PRINT_REFS 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("forceIncStrong of %p from %p: cnt=%d\n", this, id, c); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (c) { 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case INITIAL_STRONG_VALUE: 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // fall through... 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 0: 3836fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian refs->mBase->onFirstRef(); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t RefBase::getStrongCount() const 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mRefs->mStrong; 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectRefBase* RefBase::weakref_type::refBase() const 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return static_cast<const weakref_impl*>(this)->mBase; 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::weakref_type::incWeak(const void* id) 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl* const impl = static_cast<weakref_impl*>(this); 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project impl->addWeakRef(id); 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int32_t c = android_atomic_inc(&impl->mWeak); 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ASSERT(c >= 0, "incWeak called on %p after last weak ref", this); 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4056fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::weakref_type::decWeak(const void* id) 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl* const impl = static_cast<weakref_impl*>(this); 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project impl->removeWeakRef(id); 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const int32_t c = android_atomic_dec(&impl->mWeak); 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ASSERT(c >= 1, "decWeak called on %p too many times", this); 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (c != 1) return; 4136fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian 4146fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian if ((impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_STRONG) { 4156fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian // This is the regular lifetime case. The object is destroyed 4166fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian // when the last strong reference goes away. Since weakref_impl 4176fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian // outlive the object, it is not destroyed in the dtor, and 4186fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian // we'll have to do it here. 4192c0042b666a969091c931614f2fc0dce2f1cfac8Mathias Agopian if (impl->mStrong == INITIAL_STRONG_VALUE) { 4206fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian // Special case: we never had a strong reference, so we need to 4216fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian // destroy the object now. 4226fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian delete impl->mBase; 4232c0042b666a969091c931614f2fc0dce2f1cfac8Mathias Agopian } else { 424ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian // LOGV("Freeing refs %p of old RefBase %p\n", this, impl->mBase); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete impl; 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4286fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian // less common case: lifetime is OBJECT_LIFETIME_{WEAK|FOREVER} 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project impl->mBase->onLastWeakRef(id); 4306fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian if ((impl->mFlags&OBJECT_LIFETIME_MASK) == OBJECT_LIFETIME_WEAK) { 4316fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian // this is the OBJECT_LIFETIME_WEAK case. The last weak-reference 4326fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian // is gone, we can destroy the object. 4336fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian delete impl->mBase; 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool RefBase::weakref_type::attemptIncStrong(const void* id) 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project incWeak(id); 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl* const impl = static_cast<weakref_impl*>(this); 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t curCount = impl->mStrong; 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ASSERT(curCount >= 0, "attemptIncStrong called on %p after underflow", 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this); 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (curCount > 0 && curCount != INITIAL_STRONG_VALUE) { 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0) { 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curCount = impl->mStrong; 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curCount <= 0 || curCount == INITIAL_STRONG_VALUE) { 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool allow; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curCount == INITIAL_STRONG_VALUE) { 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Attempting to acquire first strong reference... this is allowed 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the object does NOT have a longer lifetime (meaning the 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // implementation doesn't need to see this), or if the implementation 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // allows it to happen. 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) != OBJECT_LIFETIME_WEAK 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Attempting to revive the object... this is allowed 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // if the object DOES have a longer lifetime (so we can safely 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // call the object with only a weak ref) and the implementation 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // allows it to happen. 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project allow = (impl->mFlags&OBJECT_LIFETIME_WEAK) == OBJECT_LIFETIME_WEAK 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && impl->mBase->onIncStrongAttempted(FIRST_INC_STRONG, id); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allow) { 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project decWeak(id); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curCount = android_atomic_inc(&impl->mStrong); 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If the strong reference count has already been incremented by 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // someone else, the implementor of onIncStrongAttempted() is holding 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // an unneeded reference. So call onLastStrongRef() here to remove it. 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // (No, this is not pretty.) Note that we MUST NOT do this if we 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // are in fact acquiring the first reference. 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curCount > 0 && curCount < INITIAL_STRONG_VALUE) { 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project impl->mBase->onLastStrongRef(id); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project impl->addStrongRef(id); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if PRINT_REFS 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGD("attemptIncStrong of %p from %p: cnt=%d\n", this, id, curCount); 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curCount == INITIAL_STRONG_VALUE) { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android_atomic_add(-INITIAL_STRONG_VALUE, &impl->mStrong); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project impl->mBase->onFirstRef(); 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool RefBase::weakref_type::attemptIncWeak(const void* id) 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project weakref_impl* const impl = static_cast<weakref_impl*>(this); 504ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int32_t curCount = impl->mWeak; 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOG_ASSERT(curCount >= 0, "attemptIncWeak called on %p after underflow", 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project this); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (curCount > 0) { 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mWeak) == 0) { 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project curCount = impl->mWeak; 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (curCount > 0) { 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project impl->addWeakRef(id); 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return curCount > 0; 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint32_t RefBase::weakref_type::getWeakCount() const 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return static_cast<const weakref_impl*>(this)->mWeak; 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::weakref_type::printRefs() const 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static_cast<const weakref_impl*>(this)->printRefs(); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::weakref_type::trackMe(bool enable, bool retain) 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 534c4fbbe06a53de3951c258978ffce1b1f185f8828Josh Stone static_cast<weakref_impl*>(this)->trackMe(enable, retain); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectRefBase::weakref_type* RefBase::createWeak(const void* id) const 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRefs->incWeak(id); 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mRefs; 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectRefBase::weakref_type* RefBase::getWeakRefs() const 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mRefs; 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectRefBase::RefBase() 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mRefs(new weakref_impl(this)) 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectRefBase::~RefBase() 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5556fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian if (mRefs->mStrong == INITIAL_STRONG_VALUE) { 5566fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian // we never acquired a strong (and/or weak) reference on this object. 5576fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian delete mRefs; 5586fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian } else { 5596fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian // life-time of this object is extended to WEAK or FOREVER, in 5606fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian // which case weakref_impl doesn't out-live the object and we 5616fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian // can free it now. 5626fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian if ((mRefs->mFlags & OBJECT_LIFETIME_MASK) != OBJECT_LIFETIME_STRONG) { 5636fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian // It's possible that the weak count is not 0 if the object 5646fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian // re-acquired a weak reference in its destructor 5656fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian if (mRefs->mWeak == 0) { 5666fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian delete mRefs; 5676fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian } 5682c0042b666a969091c931614f2fc0dce2f1cfac8Mathias Agopian } 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5706fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian // for debugging purposes, clear this. 5716fe248139223a9dfaab709bc13849bdc16f27564Mathias Agopian const_cast<weakref_impl*&>(mRefs) = NULL; 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::extendObjectLifetime(int32_t mode) 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android_atomic_or(mode, &mRefs->mFlags); 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::onFirstRef() 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::onLastStrongRef(const void* /*id*/) 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool RefBase::onIncStrongAttempted(uint32_t flags, const void* id) 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (flags&FIRST_INC_STRONG) ? true : false; 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid RefBase::onLastWeakRef(const void* /*id*/) 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 595a688b574d294faae5f56224908b40856c5045aacMathias Agopian 596a688b574d294faae5f56224908b40856c5045aacMathias Agopian// --------------------------------------------------------------------------- 597a688b574d294faae5f56224908b40856c5045aacMathias Agopian 598ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopianvoid RefBase::moveReferences(void* dst, void const* src, size_t n, 599ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian const ReferenceConverterBase& caster) 600ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian{ 601ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian#if DEBUG_REFS 602ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian const size_t itemSize = caster.getReferenceTypeSize(); 603ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian for (size_t i=0 ; i<n ; i++) { 604ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian void* d = reinterpret_cast<void *>(intptr_t(dst) + i*itemSize); 605ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian void const* s = reinterpret_cast<void const*>(intptr_t(src) + i*itemSize); 606ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian RefBase* ref(reinterpret_cast<RefBase*>(caster.getReferenceBase(d))); 607ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian ref->mRefs->renameStrongRefId(s, d); 608ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian ref->mRefs->renameWeakRefId(s, d); 609ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian } 610ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian#endif 611ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian} 612ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian 613ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian// --------------------------------------------------------------------------- 614ec122eb46b6ce8f6e8bb3e08c34e575de666cd3eMathias Agopian 615a688b574d294faae5f56224908b40856c5045aacMathias AgopianTextOutput& printStrongPointer(TextOutput& to, const void* val) 616a688b574d294faae5f56224908b40856c5045aacMathias Agopian{ 617a688b574d294faae5f56224908b40856c5045aacMathias Agopian to << "sp<>(" << val << ")"; 618a688b574d294faae5f56224908b40856c5045aacMathias Agopian return to; 619a688b574d294faae5f56224908b40856c5045aacMathias Agopian} 620a688b574d294faae5f56224908b40856c5045aacMathias Agopian 621a688b574d294faae5f56224908b40856c5045aacMathias AgopianTextOutput& printWeakPointer(TextOutput& to, const void* val) 622a688b574d294faae5f56224908b40856c5045aacMathias Agopian{ 623a688b574d294faae5f56224908b40856c5045aacMathias Agopian to << "wp<>(" << val << ")"; 624a688b574d294faae5f56224908b40856c5045aacMathias Agopian return to; 625a688b574d294faae5f56224908b40856c5045aacMathias Agopian} 626a688b574d294faae5f56224908b40856c5045aacMathias Agopian 627a688b574d294faae5f56224908b40856c5045aacMathias Agopian 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 629