본문 바로가기

프로그래밍

[펌] ACE_Message_Block Pool 만들기

ACE_Message_Block

  • 정의

    • 네트워크 어플리케이션들은 다양한 메세지들을 효과적으로 다루기 위해 수단을 제공.
    • 고정 및 가변크기 메세지들을 효율적으로 관리하기 위한 class
  • ACE_Data_Block : Message_Block의 data payload
  • payload : 통신 시스템에서는 헤더와 반대로 메시지 데이터를 보유하는 패킷이나 프레임 부분을 의미

  • composite 패턴 : 개별객체와 복합객체를 같은 방식으로 다룰수 있는 방법을 제공.(Head First Design Pattern p.394)
  • cont() : 조합 메세지 구성을 위한 메소드. ACE_Message_Block을 링크드 리스트 형식으로 만들수 있음. C++NPv1 [그림 4.2]
  • rd_ptr() / wr_ptr() : 데이터를 읽거나 쓸때 사용하는 포인터. read/write 후  포인터를 반드시 전진시켜 줘야 함
  1. memcpy( block.wr_ptr(), recv_ptr, recv_size);
  2. block.wr_ptr(recv_size);
  • base() : 얕은 복사(Shallow copy)
  • copy() : 깊은 복사(Deep copy)
  • release() : 레퍼런스 카운트 1 감소. 0 이면 자원들을 해제.
  • capacity() : Get the total amount of allocated space
  • 받은 패킷/보낼 패킷을 일반화하여 저장
  • ACE_Message_Queue와 함께 사용 : ACE_Message_Block을 element로 가지는 Queue. 잠금 정책을 선택적으로 사용가능.

 

QueueBlockPool

  • ACE_Message_Queue를 이용하여 ACE_Message_Block Pool을 만드는 방식
  • 생성자 : Block개수와 BufferSize를 인자로 받아서 Block 개수 만큼 ACE_Message_Block를 생성하여 Queue에 넣어둔다
  • Alloc : Queue에서 Block을 하나 꺼내어 리턴해준다
  • Free : 인자로 받은 Block을 받아서 Queue에 넣는다
  • 소멸자 : Queue에 들어있는 Block를 모두 꺼내어 소멸시킨다
  • 주의사항

    • ACE_Message_Queue의 생성자 첫번째 인자인 High water mark limit를 넘기면 enqueue가 실패하기 때문에 많은 block을 넣어 두려면 이 속성을 default인 16K 보다 좀 더 크게 설정해야 함.

 

AllocatorBlockPool

  • ACE_Dynamic_Cached_Allocator를 이용하여 ACE_Message_Block Pool을 만드는 방식
  • 3개의 Allocator를 사용

    • messageBlockAllocator : ACE_Message_Block 할당에 사용
    • dataBlockAllocator : ACE_Data_Block 할당에 사용
    • strategyAllocator : ACE_Data_Block 안으로 전달되어 실제 buffer 할당에 사용
  • 생성자 : Block개수와 BufferSize를 인자로 받아 각 Allocator에 전달하여 준다.

    • messageBlockAllocator 에서는 Block개수X sizeof(ACE_Message_Block) 크기의 pool을 생성한다
    • dataBlockAllocator 에서는 Block개수X sizeof(ACE_Data_Block) 크기의 pool을 생성한다
    • strategyAllocator 에서는 Block개수 X BufferSize 크기의 pool을 생성한다
  • Alloc : placement new를 이용하여 Allocator에서 Block을 하나 할당받아서 리턴해준다
  • Free : 아래 둘중에 하나를 실행

    • 3개의 Allocator를 차례로 free한다.
    • block.release() 로 한번에 free한다.
  • 소멸자 : 인자로 가지고 있던 ACE_Dynamic_Cached_Allocator가 소멸 되면서 pool도 모두 소멸된다.

 

Test Scenario

  1. BlockCount와 BufferSize를 인자로 Pool을 생성
  2. Pool에서 block을 하나 할당받음
  3. 할당되었는지 확인
  4. 할당받은 block의 BufferSize가 맞는지 확인
  5. 할당받은 block을 반납
  6. BlockCount 개수만큼 할당이 되는지 확인
  7. 할당받은 block들을 linked list로 엮는다
  8. 만들어진 linked list의 BufferSize 총합이 맞는지 확인 : ( block.total_capacity() == BlockCount*BufferSize )
  9. 더이상 할당이 되지 않는 것을 확인

 

자료