简介
ACE_Oneshot_Acceptor与ACE_Acceptor,ACE_Strategy_Acceptor有些差异,首先其构造函数以及open函数中不会向Reactor注册ACCEPT_MASK事件,再次创建SVC_HANDLER不是由acceptor自己创建,而是由调用方创建。
结构
ACE_Oneshot_Acceptor只包含并发策略
接受连接accept
virtual int accept (SVC_HANDLER * = 0,
typename PEER_ACCEPTOR::PEER_ADDR *remote_addr = 0,
const ACE_Synch_Options &synch_options = ACE_Synch_Options::defaults,
bool restart = true,
bool reset_new_handle = false);
依赖synch_options
同步选项
- 使用reactor等待连接到来
- 立即判断是否有连接到来
- 超时时间内是否有连接到来
ACE_SOCK_Acceptor
如果设置了超时时间,则用select判断是否有新连接到来,如果套接字为阻塞,则将套接字设置为非阻塞,accept接收连接,然后恢复为阻塞
如果连接成功,则activate_svc_handler
激活事件处理器
如果连接失败,返回错误码为EWOULDBLOCK(包含设置0超时),同步选项设置的使用reactor,则注册到reactor事件循环中,并且添加到reactor的超时处理中,等待新连接到来
新连接到来
- 取消定时器
- 取消注册reactor,不再接受新连接,与Oneshot对应,只处理一次连接
- accept接收新连接
- 注册新连接的处理器到reactor中
template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_input (ACE_HANDLE)
{
ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_input");
int result = 0;
// Cancel any timer that might be pending.
this->cancel ();
// Try to find out if the implementation of the reactor that we are
// using requires us to reset the event association for the newly
// created handle. This is because the newly created handle will
// inherit the properties of the listen handle, including its event
// associations.
ACE_Reactor *reactor = this->reactor ();
bool reset_new_handle = false;
// There is a use-case whereby this object will be gone upon return
// from shared_accept - if the Svc_Handler deletes this Oneshot_Acceptor
// during the shared_accept/activation steps. So, do whatever we need
// to do with this object before calling shared_accept.
if (reactor)
{
reset_new_handle = reactor->uses_event_associations ();
reactor->remove_handler
(this,
ACE_Event_Handler::ACCEPT_MASK | ACE_Event_Handler::DONT_CALL);
}
if (this->shared_accept (this->svc_handler_, // stream
0, // remote address
0, // timeout
this->restart_, // restart
reset_new_handle // reset new handle
) == -1)
result = -1;
return result;
}
template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::shared_accept
(SVC_HANDLER *svc_handler,
typename PEER_ACCEPTOR::PEER_ADDR *remote_addr,
ACE_Time_Value *timeout,
bool restart,
bool reset_new_handle)
{
ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::shared_accept");
if (svc_handler == 0)
return -1;
// Accept connection into the Svc_Handler.
else if (this->peer_acceptor_.accept (svc_handler->peer (), // stream
remote_addr, // remote address
timeout, // timeout
restart, // restart
reset_new_handle // reset new handle
) == -1)
{
// Check whether we just timed out or whether we failed...
if (!(errno == EWOULDBLOCK || errno == ETIME))
// Close down handler to avoid memory leaks.
svc_handler->close (CLOSE_DURING_NEW_CONNECTION);
return -1;
}
// Activate the <svc_handler> using the designated concurrency
// strategy (note that this method becomes responsible for handling
// errors and freeing up the memory if things go awry...)
else
return this->activate_svc_handler (svc_handler);
}
超时处理
- 如果超时时间内没有新连接到来,调用新连接事件处理器
- 从reactor中注销acceptor
template <typename SVC_HANDLER, typename PEER_ACCEPTOR> int
ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_timeout
(const ACE_Time_Value &tv,
const void *arg)
{
ACE_TRACE ("ACE_Oneshot_Acceptor<SVC_HANDLER, PEER_ACCEPTOR>::handle_timeout");
errno = ETIME;
if (this->svc_handler_->handle_timeout (tv, arg) == -1)
this->svc_handler_->handle_close (this->svc_handler_->get_handle (),
ACE_Event_Handler::TIMER_MASK);
// Since we aren't necessarily registered with the Reactor, don't
// bother to check the return value here...
if (this->reactor ())
this->reactor ()->remove_handler (this,
ACE_Event_Handler::ACCEPT_MASK);
return 0;
}