ACE 反应式处理器


// --------------------------------------------------------------
// 
// Copyright (C) 2008 - All Rights Reserved
// 
// Author:  LiuYin
// File:  SvcPostman
// Version:  1.0
// Date:   2008-4-2
// 
// Purpose: 
// 
// --------------------------------------------------------------

#ifndef SvcPostman_H
#define SvcPostman_H

//

#include <ACE/Svc_Handler.h>
#include <ACE/SOCK_Stream.h>
#include <ACE/Synch_Traits.h>
#include <ACE/Global_Macros.h>
#include <ACE/os_include/os_netdb.h>
#include <ACE/Reactor_Notification_Strategy.h>

//

class CSvcPostman : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH>
{
 typedef ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_MT_SYNCH> Super;

public:
 CSvcPostman(size_t next_length = 256);

 int send(const ACE_Message_Block &_message_block);

 int open(void *p = 0);
 int handle_input(ACE_HANDLE fd = ACE_INVALID_HANDLE);
 int handle_output(ACE_HANDLE fd = ACE_INVALID_HANDLE);
 int handle_close(ACE_HANDLE handle, ACE_Reactor_Mask mask);

protected:
 virtual size_t handle_recv(const ACE_Message_Block &message_block) = 0;

 ~CSvcPostman();

private:
 int send_block(ACE_Message_Block *message_block);

private:
 size_t next_length_;

 ACE_Reactor_Notification_Strategy notifier_;
};

//

#endif

/


#include "SvcPostman.h"

//

CSvcPostman::CSvcPostman(size_t next_length)
 : next_length_(next_length),
  notifier_(0, this, ACE_Event_Handler::WRITE_MASK)
{
 ACE_TRACE(ACE_TEXT("CSvcPostman(size_t)"));
}

CSvcPostman::~CSvcPostman()
{
 ACE_TRACE(ACE_TEXT("~CSvcPostman()"));
}

int CSvcPostman::send(const ACE_Message_Block &_message_block)
{
 ACE_TRACE(ACE_TEXT("send(const ACE_Message_Block &)"));

 ACE_Message_Block *message_block = _message_block.duplicate();

 int ret = -1;
 if (!message_block || get_handle() == ACE_INVALID_HANDLE) {
  goto Exit;
 }
 if (this->putq(message_block, &(ACE_Time_Value(ACE_OS::gettimeofday()))) == -1) {
  goto Exit;
 }

 ret = 0;
Exit:
 if (ret == -1) {
  if (message_block) {
   message_block->release();
   message_block = 0;
  }
 }
 return ret;
}

int CSvcPostman::open(void *p)
{
 ACE_TRACE(ACE_TEXT("open(void *)"));

 notifier_.reactor(this->reactor());
 this->msg_queue()->notification_strategy(&notifier_);

 return Super::open(p);
}

int CSvcPostman::handle_input(ACE_HANDLE fd)
{
 ACE_TRACE(ACE_TEXT("handle_input(ACE_HANDLE)"));

 ACE_Message_Block message_block;
 message_block.init(next_length_);
 ACE_OS::memset(message_block.base(), 0, message_block.size());

 int recv_length = this->peer().recv(message_block.wr_ptr(), message_block.size());
 if (recv_length > 0) {
  message_block.wr_ptr(recv_length);

  next_length_ = handle_recv(message_block);
 }
 else {
  ACE_DEBUG((LM_DEBUG, "Peer Closed!/n"));
 }

 return (recv_length > 0) ? 0 : -1;
}

int CSvcPostman::handle_output(ACE_HANDLE fd)
{
 ACE_TRACE(ACE_TEXT("handle_output(ACE_HANDLE)"));

 ACE_Message_Block *message_block = 0;

 int ret = -1;
 while (this->getq(message_block, &(ACE_Time_Value(ACE_OS::gettimeofday()))) != -1) {
  if (message_block) {
   send_block(message_block);
  }
 }

 ret = (this->msg_queue()->is_empty() ? -1 : 0);
Exit:
 return ret;
}

int CSvcPostman::handle_close(ACE_HANDLE handle, ACE_Reactor_Mask mask)
{
 ACE_TRACE(ACE_TEXT("handle_close(ACE_HANDLE, ACE_Reactor_Mask)"));

 if (ACE_BIT_ENABLED(mask, ACE_Event_Handler::READ_MASK)) {
  delete this;
 }

 return 0;
}

int CSvcPostman::send_block(ACE_Message_Block *message_block)
{
 int ret = -1;
 while (message_block) {
  if (message_block->length() > 0) {
   ssize_t send_size = this->peer().send(message_block->rd_ptr(), message_block->length());
   if (send_size < message_block->length()) {
    if (send_size > 0) {
     message_block->rd_ptr(ACE_static_cast(size_t, send_size));
    }

    this->ungetq(message_block);
    break;
   }
  }

  ACE_Message_Block *_message_block = message_block->cont();
  message_block->release();
  message_block = _message_block;
 }

 ret = 0;
Exit:
 return ret;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值