5. Structure
Class : Asynchronous Layer
Class : Synchronous Layer
Responsibility: 비동기 IO
Responsibility: 동기 IO 처리 처리
Collaborator : Queueing Collaborator : Queueing
Layer Layer
External Event
Source
Class : Queueing Layer
Class : External Event
Source
Responsibility: 비동기 Layer
와 동기 레이어간 데이터 전달
Responsibility: 비동기 Layer
역할.
에서 발생하는 IO에 대한 이벤
Collaborator : 비동기 Layer
트 처리.
동기 Layer
Collaborator : 비동기 Layer
6. Structure (2)
Synchronous Sync Service 1 Sync Service 2 Sync Service 3
Service Layer
Queueing Queue
Layer
Asynchronous External
Async Service
Service Layer Event Source
8. Implementation
동기 IO Layer와 비동기 IO Layer 를 나눈다.
동기 IO Layer 구현
비동기 IO Layer 구현
External Event Source 구현
Queueing Layer 구현
Queue는 Thread Safe하게 구현!!
Sync Layer와 Async Layer에 어떻게 알려주고 통신이 되게
할건가??
9. Implementation(2)
int
ACE_Message_Queue_NT::enqueue (ACE_Message_Block *new_item,
ACE_Time_Value *)
{
ACE_TRACE ("ACE_Message_Queue_NT::enqueue");
ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1);
if (this->state_ != ACE_Message_Queue_Base::DEACTIVATED)
{
size_t const msize = new_item->total_size ();
size_t const mlength = new_item->total_length ();
// Note - we send ACTIVATED in the 3rd arg to tell the completion
// routine it's _NOT_ being woken up because of deactivate().
ULONG_PTR state_to_post;
state_to_post = ACE_Message_Queue_Base::ACTIVATED;
if (::PostQueuedCompletionStatus (this->completion_port_,
static_cast<DWORD> (msize),
state_to_post,
reinterpret_cast<LPOVERLAPPED> (new_item)))
{
// Update the states once I succeed.
this->cur_bytes_ += msize;
this->cur_length_ += mlength;
return ACE_Utils::truncate_cast<int> (++this->cur_count_);
}
}
else
errno = ESHUTDOWN;
// Fail to enqueue the message.
return -1;
}
10. Implementation(2)
int
ACE_Message_Queue_NT::dequeue (ACE_Message_Block *&first_item,
ACE_Time_Value *timeout)
{
ACE_TRACE ("ACE_Message_Queue_NT::dequeue_head");
{
ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1);
<<생략>>
// Get a message from the completion port.
int retv = ::GetQueuedCompletionStatus (this->completion_port_,
&msize,
&queue_state,
reinterpret_cast<LPOVERLAPPED *> (&first_item),
(timeout == 0 ? INFINITE : timeout->msec ()));
{
ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, ace_mon, this->lock_, -1);
--this->cur_thrs_; // Decrease waiting thread count.
if (retv)
{
if (queue_state == ACE_Message_Queue_Base::ACTIVATED)
{ // Really get a valid MB from the queue.
--this->cur_count_;
this->cur_bytes_ -= msize;
this->cur_length_ -= first_item->total_length ();
return ACE_Utils::truncate_cast<int> (this->cur_count_);
}
else // Woken up by deactivate () or pulse ().
errno = ESHUTDOWN;
}
}
return -1;
}
11. Conclusion
구조가 더 간단해 지고 성능에 영향을 주지 않는다.
Sync IO 와 Async IO 레이어의 분리로 상호 의존관계가 없어진다.
메모리 Copy나 Thread 동기화 등에 대한 처리를 주의 깊게 해야한
다.
디버깅이나 테스트하기 복잡하다.