검색결과 리스트
글
안드로이드 프레임워크 프로그래밍(23) [onFirstRef() 함수 호출시기]
안드로이드 Native 단계에서의 Framework를 분석해 보던 도중 의문이 들었던 함수가 하나 있었습니다.
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
1 2 3 4 | void SurfaceFlinger::onFirstRef() { mEventQueue.init(this); } | cs |
표면적으로 보았을 때 onFirstRef() 함수를 바로 호출하는 부분을 해당 부분을 실행하는 소스코드 내에서 바로 찾아내기는 어렵습니다. 그렇다면 위 함수 onFirstRef()가 어느 시점에서 호출이 되는지 살펴보도록 하겠습니다.
먼저 SurfaceFlinger가 처음 생성되는 부분에서부터 추적해 나가도록 해보겠습니다.
/frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
1 2 3 4 5 6 7 8 9 10 | int main(int argc, char** argv) { .... // instantiate surfaceflinger sp<SurfaceFlinger> flinger = new SurfaceFlinger(); .... } | cs |
위 함수 onFirstRef()의 호출 시점을 파악하기 위해 Strong Pointer를 분석해 볼 필요가 있습니다. Strong Pointer에 대해 분석한 이전 포스팅에 대한 내용은 아래 링크를 참조해 주시기 바랍니다.
여기서 바로 StrongPointer에 SurfaceFlinger가 적용되는 코드를 보도록 하겠습니다.
/system/core/include/utils/StrongPointer.h
1 2 3 4 5 6 7 8 9 10 11 12 13 | template<typename T> sp<T>::sp(T* other) : m_ptr(other) { if (other) other->incStrong(this); } template<typename T> sp<T>::sp(const sp<T>& other) : m_ptr(other.m_ptr) { if (m_ptr) m_ptr->incStrong(this); } | cs |
Strong Pointer가 생성될 때 해당 포인터를 받게 되면 해당 포인터의 incStrong() 함수를 실행하게 됩니다. 여기서 incStrong() 함수를 찾아보도록 하겠습니다.
/frameworks/native/services/surfaceflinger/main_surfaceflinger.h
1 2 3 4 5 6 7 8 | class SurfaceFlinger : public BnSurfaceComposer, private IBinder::DeathRecipient, private HWComposer::EventHandler { .... }; | cs |
/frameworks/native/include/gui/ISurfaceComposer.h
1 2 3 4 5 6 | class BnSurfaceComposer: public BnInterface<ISurfaceComposer> { public: .... }; | cs |
/frameworks/native/include/binder/IInterface.h
1 2 3 4 5 6 7 8 9 10 | template<typename INTERFACE> class BnInterface : public INTERFACE, public BBinder { public: virtual sp<IInterface> queryLocalInterface(const String16& _descriptor); virtual const String16& getInterfaceDescriptor() const; protected: virtual IBinder* onAsBinder(); }; | cs |
/frameworks/native/include/binder/Binder.h
1 2 3 4 5 6 | class BBinder : public IBinder { .... }; | cs |
/frameworks/native/include/binder/IBinder.h
1 2 3 4 5 6 | class IBinder : public virtual RefBase { .... }; | cs |
/system/core/include/utils/RefBase.h
1 2 3 4 5 6 7 8 | class RefBase { public: void incStrong(const void* id) const; .... } | cs |
안드로이드 Native 클래스들의 토대라 할 수 있는 RefBase 클래스 내에 incStrong()함수가 존재하는 것을 확인하였습니다. 이제 해당 함수의 소스코드를 살펴보도록 합시다.
/system/core/libutils/RefBase.cpp
1 2 3 4 | RefBase::RefBase() : mRefs(new weakref_impl(this)) { } | cs |
/system/core/libutils/RefBase.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | class RefBase::weakref_impl : public RefBase::weakref_type { public: volatile int32_t mStrong; volatile int32_t mWeak; RefBase* const mBase; volatile int32_t mFlags; .... weakref_impl(RefBase* base) : mStrong(INITIAL_STRONG_VALUE) , mWeak(0) , mBase(base) , mFlags(0) , mStrongRefs(NULL) , mWeakRefs(NULL) , mTrackEnabled(!!DEBUG_REFS_ENABLED_BY_DEFAULT) , mRetain(false) { } .... } | cs |
/system/core/libutils/RefBase.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include <utils/RefBase.h> ... void RefBase::incStrong(const void* id) const { weakref_impl* const refs = mRefs; refs->incWeak(id); refs->addStrongRef(id); const int32_t c = android_atomic_inc(&refs->mStrong); ALOG_ASSERT(c > 0, "incStrong() called on %p after last strong ref", refs); #if PRINT_REFS ALOGD("incStrong of %p from %p: cnt=%d\n", this, id, c); #endif if (c != INITIAL_STRONG_VALUE) { return; } android_atomic_add(-INITIAL_STRONG_VALUE, &refs->mStrong); refs->mBase->onFirstRef(); } | cs |
위의 RefBase 단계에서의 incStrong() 함수가 호출될 때 onFirstRef()함수가 호출되는 것을 확인하실 수 있습니다.
'안드로이드 > 프레임워크' 카테고리의 다른 글
SurfaceFlinger에서 EventThread의 초기화 과정 (1) | 2015.09.08 |
---|---|
안드로이드 프레임워크 프로그래밍(24) [BitTube 클래스] (2) | 2015.09.06 |
Android에서 VSync 동작 원리 및 초기화 과정(4) (5) | 2015.09.02 |
Android에서 VSync 동작 원리 및 초기화 과정(3) (0) | 2015.08.31 |
Android에서 VSync 동작 원리 및 초기화 과정(2) (0) | 2015.08.30 |