Youth 发表于 2008-6-21 23:52:27

《ACE程序员指南》7.6.2范例的问题

基本照着书上的代码,ACE 5.6.1+VS2005SP1,碰到的问题是在handle_timeout中putq进去的mb在handle_output中却getq不出来,试着跟踪了一下,putq应该是没问题的,调用之后可以看到msg_queue_里已经有内容,但在getq时,返回的mb没有内容。

相关代码如下:

int Client::handle_timeout(const ACE_Time_Value &, const void *)
{
if (this->iterations_ >= ITERATIONS)
{
    this->peer().close_writer();
    return 0;
}

ACE_Message_Block *mb;
char msg;
ACE_OS::sprintf(msg, "Iteration %d\n", this->iterations_);

ACE_NEW_RETURN(mb, ACE_Message_Block(msg), -1);
this->msg_queue()->enqueue_tail(mb);// this->putq(mb);
++ iterations_;

return 0;
}

int Client::handle_output(ACE_HANDLE fd /* = ACE_INVALID_HANDLE */)
{
ACE_Message_Block *mb;
ACE_Time_Value nowait(ACE_OS::gettimeofday());

while (-1 != this->getq(mb, &nowait))
{
    size_t size = mb->length();
    ssize_t send_cnt = this->peer().send(mb->rd_ptr(), mb->length());

    if (send_cnt == -1)
       ACE_ERROR((LM_ERROR, "(%P|%t) %p\n", "send"));
    else
       mb->rd_ptr(ACE_static_cast(size_t, send_cnt));

    if (mb->length() > 0)
    {
       this->ungetq(mb);
       break;
    }

    mb->release();
}

if (this->msg_queue()->is_empty())
   this->reactor()->cancel_wakeup(this, ACE_Event_Handler::WRITE_MASK);
else
    this->reactor()->schedule_wakeup(this, ACE_Event_Handler::WRITE_MASK);

return 0;
}

winston 发表于 2008-6-22 09:53:59

ACE_Message_Block *mb;
char msg;
ACE_OS::sprintf(msg, "Iteration %d\n", this->iterations_);

ACE_NEW_RETURN(mb, ACE_Message_Block(msg), -1);

这几行有错,ACE_NEW_RETURN(mb, ACE_Message_Block(msg), -1); 这样用法有问题,msg不能是栈上面的东西,你最好直接把内容复制到mb。
参考ACE_Message_Block的类说明文档。上面有注释。

Youth 发表于 2008-6-22 12:42:32

好的,谢谢了,我昨天看了论坛里另外几个帖子后,也怀疑是这方面的问题,但捣鼓了一会还是没搞定,今天再试试~~

Youth 发表于 2008-6-22 15:09:51

改成这样就可以了~

ACE_NEW_RETURN(mb, ACE_Message_Block(32), -1);
ACE_OS::sprintf(mb->wr_ptr(), "Iteration %d\n", this->iterations_);
mb->wr_ptr(12);

this->putq(mb);
页: [1]
查看完整版本: 《ACE程序员指南》7.6.2范例的问题