1. GPG
1.6 범용 핸들 기반 자원 관리자
P. 115 - 129
NHN NEXT
남현욱
2. 범용 핸들 기반 자원 관리자
자원 관리의 필요성
• 자원의 중복 생성
- 어떤 자원이 이미 생성된 자원이고 하나만 있으면 충분한 경우, 이를 단 하나만 생성하도록
제어해주는 것이 좋다
• 자원의 공유 관리
- 어떤 한 자원이 여러 개체에 의해 사용될 때 이를 관리하지 않으면 댕글링 포인터 등의 문제가
생긴다.
• 성능과 안전성 확보
- 자원의 생성과 해제 시점, 상태를 관리함으로써 성능을 유지하면서 시스템의 안전성을 확보
할 수 있다.
3. 범용 핸들 기반 자원 관리자
방법
핸들(Handle)개념을 이용하자
메모리
포인터
핸들
관리자
포인터를 핸들이라는 추상화 층으
로 한 번 더 감싸서 관리함으로써
제어하기 힘들고 위험한 포인터를
직접적으로 건네주지 않는다.
4. 범용 핸들 기반 자원 관리자
구현 예제
범용 핸들(Handle)클래스
가장 간단한 방법은 두 개의 비트필드 요소를 이용하는 것
-각각 index, magicNumber의 역할을 한다. index는 Handle과 연결된 자원이 무엇인지를 판
별하는 식별자 역할을 하며, magicNumber는 해당 핸들이 유효한지를 검증하는 역할을 한다.
핸들은 읽기 전용
- 핸들은 데이터를 참조하기 위한 값이므로 한 번 생성되면 수정될 일은 거의 없다고 봐도 된다.
구분을 위한 태그(Tag)의 이용
-범용적으로 이용되는 클래스기 때문에 서로 다른 자원에 대한 핸들이 서로 타입 구분이 되지 않
는다. 따라서 이를 구분하기 위한 용도로 태그를 이용한다(코드 참조)
5. 범용 핸들 기반 자원 관리자
구현 예제
범용 핸들(Handle)클래스
template <typename TAG>
class Handle
{
public:
Handle() : m_Handle(0) { }
void Init(unsigned int index);
unsigned int GetIndex() const;
unsigned int GetMagic() const;
unsigned int GetHandle() const;
bool IsNull () const;
private:
union
{
enum
{
MAX_BITS_INDEX = 16,
MAX_BITS_MAGIC = 16,
MAX_INDEX = (1 << MAX_BITS_INDEX) - 1,
MAX_MAGIC = (1 << MAX_BITS_MAGIC) - 1,
}
struct
{
unsigned m_Index : MAX_BITS_INDEX;
unsigned m_Magic : MAX_BITS_MAGIC;
};
unsigned int m_Handle;
}
};
template <typename TAG>
void Handle<TAG> ::Init(unsigned int index)
{
static unsigned int s_AutoMagic = index;
if (++s_AutoMagic > MAX_MAGIC)
{
s_AutoMagic = 1;
}
m_Index = index;
m_Magic = s_AutoMagic;
}
6. 범용 핸들 기반 자원 관리자
구현 예제
범용 핸들(Handle)클래스
template <typename TAG>
class Handle
{
public:
Handle() : m_Handle(0) { }
void Init(unsigned int index);
unsigned int GetIndex() const;
unsigned int GetMagic() const;
unsigned int GetHandle() const;
bool IsNull () const;
private:
union
{
enum
{
MAX_BITS_INDEX = 16,
MAX_BITS_MAGIC = 16,
핸들 구분을 위한 태그. 오로지 구분 만을 위한 목
적이므로 빈 구조체같은 걸 이용하는게 좋다.
ex)
struct TagTexture{};
typedef Handle<TagTexture> HTexture;
HTexture hTexture;
MAX_INDEX = (1 << MAX_BITS_INDEX) - 1,
MAX_MAGIC = (1 << MAX_BITS_MAGIC) - 1,
}
struct
{
unsigned m_Index : MAX_BITS_INDEX;
unsigned m_Magic : MAX_BITS_MAGIC;
};
unsigned int m_Handle;
}
};
template <typename TAG>
void Handle<TAG> ::Init(unsigned int index)
{
static unsigned int s_AutoMagic = index;
if (++s_AutoMagic > MAX_MAGIC)
{
s_AutoMagic = 1;
}
m_Index = index;
m_Magic = s_AutoMagic;
}
7. 범용 핸들 기반 자원 관리자
구현 예제
범용 핸들(Handle)클래스
template <typename TAG>
class Handle
{
public:
Handle() : m_Handle(0) { }
void Init(unsigned int index);
unsigned int GetIndex() const;
unsigned int GetMagic() const;
unsigned int GetHandle() const;
bool IsNull () const;
private:
union
{
enum
{
MAX_BITS_INDEX = 16,
MAX_BITS_MAGIC = 16,
MAX_INDEX = (1 << MAX_BITS_INDEX) - 1,
MAX_MAGIC = (1 << MAX_BITS_MAGIC) - 1,
}
struct
{
unsigned m_Index : MAX_BITS_INDEX;
unsigned m_Magic : MAX_BITS_MAGIC;
};
unsigned int m_Handle;
}
};
template <typename TAG>
void Handle<TAG> ::Init(unsigned int index)
{
static unsigned int s_AutoMagic = index;
if (++s_AutoMagic > MAX_MAGIC)
{
s_AutoMagic = 1;
}
m_Index = index;
m_Magic = s_AutoMagic;
}
내부적으로 핸들은 아래와 같은 구조를 지닌다.
m_Handle
m_Index m_Magic
8. 범용 핸들 기반 자원 관리자
구현 예제
범용 핸들(Handle)클래스
template <typename TAG>
class Handle
{
public:
Handle() : m_Handle(0) { }
void Init(unsigned int index);
unsigned int GetIndex() const;
unsigned int GetMagic() const;
unsigned int GetHandle() const;
bool IsNull () const;
private:
union
{
enum
{
MAX_BITS_INDEX = 16,
MAX_BITS_MAGIC = 16,
MAX_INDEX = (1 << MAX_BITS_INDEX) - 1,
MAX_MAGIC = (1 << MAX_BITS_MAGIC) - 1,
}
struct
{
unsigned m_Index : MAX_BITS_INDEX;
unsigned m_Magic : MAX_BITS_MAGIC;
};
unsigned int m_Handle;
}
};
template <typename TAG>
void Handle<TAG> ::Init(unsigned int index)
{
static unsigned int s_AutoMagic = index;
if (++s_AutoMagic > MAX_MAGIC)
{
s_AutoMagic = 1;
}
m_Index = index;
m_Magic = s_AutoMagic;
}
핸들 클래스는 내부적으로 핸들 값의 저장
과 매직 넘버를 관리하는 역할만 담당한다.
실제 핸들을 부여하고 관리하는 작업은 핸
들 매니저 클래스에서 담당.
9. 범용 핸들 기반 자원 관리자
구현 예제
범용 핸들 매니저(HandleMgr)클래스
핸들 매니저는 자기가 관리하는 자원 정보와 핸들을 관리
-자원의 정보는 해당 자원에 대한 간단한 데이터들만을 포함한다. 이 데이터가 어떤 메모리의 할
당이라든지 복잡한 행동을 수행해서는 안된다.
핸들의 역참조(dereference)를 지원
- 핸들 값으로부터 그 값이 유효하면 그 핸들이 가리키는 자원의 정보를 돌려주는 기능(역참조)
을 지원한다.