안드로이드 프레임워크 프로그래밍(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에 대해 분석한 이전 포스팅에 대한 내용은 아래 링크를 참조해 주시기 바랍니다.


http://elecs.tistory.com/79


 여기서 바로 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()함수가 호출되는 것을 확인하실 수 있습니다.