ACE_Message_Block의 chained block 기능 Programming

ACE_Message_Block은 고정 크기 및 가변 크기 버퍼를 효과적으로 관리하기 위한 클래스 입니다.  데이터 복사, read ptr, write ptr 관리, 레퍼런스 카운팅 등 여러가지 편리한 기능들을 제공합니다. 그중의 하나인 chained block 기능을 소개합니다.

코드로 먼저 보여드리죠.

ACE_Message_Block* head = new ACE_Message_Block(size);
ACE_Message_Block* next = new ACE_Message_Block(size);
head->cont(next);
head와 next block은 연결된 상태입니다. 마치 링크드 리스트 처럼 말이죠.

next block 뒤로도 계속 연결할 수 있습니다.


이렇게 연결된 block을 구하는 코드는 아래와 같습니다.
ACE_Message_Block* node = head->cont();

이런 chained block 기능으로 composite 패턴을 구현합니다.
composite 패턴 : 개별객체와 복합객체를 같은 방식으로 다룰수 있는 인터페이스를 제공

서버에서 받은 패킷이 그것을 처리하는 로직으로 도달하기까지 거치는 여러 클래스, 함수들이 ACE_Message_Block을 손쉽게 다룰수 있게 됩니다. head block만 넘기면 되기 때문이죠. 중간에 어떤 데이터를 추가하려고 해도 버퍼를 복사할 필요없이 뒤에 연결하기만 하면 됩니다. cont() 함수로 iterating도 간단하게 할 수 있고  연결된 block들의 총길이와 개개의 block들의 길이 등을 계산하는 함수들도 별도로 제공됩니다. head block만 release하면 연결된 block들도 함께 release 됩니다. 따라서 패킷을 모두 처리한후에 head block만 release하면 되죠.

Chained block의 끝에 새로운 block을 추가하려면 tail block을 알아야 하는데, head block에서 한번에 tail block을 알아내는 인터페이스는 제공하지 않습니다. 아래와 같이 구현하면 됩니다.
ACE_Message_Block *FindTail(ACE_Message_Block *block)
{
    ACE_Message_Block *tail = block;
    while (NULL != tail->cont())
        tail = tail->cont();
    return tail;
}

처리중에 연결된 block중 하나에 다른 스레드에서 접근하면 문제가 생길수 있기 때문에 thread-safe는 별도로 보장을 해주어야 합니다.

핑백

  • flexible gameserver : ACE_WIN32_Asynch_Write_Stream::writev() 의 잠재적 위험성 2010-04-30 17:01:13 #

    ... 블럭들을 한번에 전송해주는 메서드 입니다. ACE_Message_Block에는 블럭을 링크드 리스트처럼 연결할 수 있는 기능이 있습니다. (http://javawork.egloos.com/2439678 참고) writev() 에 연결된 블럭을 인자로 넣어주면 한꺼번에 전송을 해주어서 성능상의 이득을 취할수 있습니다. 두 메서드 모 ... more

덧글

댓글 입력 영역