找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 4630|回复: 0

Dev_Poll_Reactor notify问题。

[复制链接]
发表于 2011-1-26 11:32:21 | 显示全部楼层 |阅读模式
在linux平台下使用Dev_Poll_Reactor 的nofify,一开始使用pipe机制,但是处理不过来,导致死锁。后来改用队列机制,但是第一次抛入的事件并不处理,要等到第二次才处理。以下是ace源码。
int
ACE_Notification_Queue::push_new_notification(
  ACE_Notification_Buffer const & buffer)
{
  ACE_TRACE ("ACE_Notification_Queue::push_new_notification");

  bool notification_required = false;

  ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, mon, this->notify_queue_lock_, -1);

  // No pending notifications.
  if (this->notify_queue_.is_empty ())
    notification_required = true; //第一次进入时,notify_queue为空,标识为true

  if (free_queue_.is_empty())
    {
      if (allocate_more_buffers() == -1)
        {
          return -1;
        }
    }

  ACE_Notification_Queue_Node * node =
    free_queue_.pop_front();

  ACE_ASSERT (node != 0);
  node->set(buffer);

  notify_queue_.push_back(node);//notify_queue不为空了
  if (!notification_required) // 但是 此时标识还是为true的    {
      return 0;      
    }

  return 1; // 这里返回。}

int
ACE_Dev_Poll_Reactor_Notify::notify (ACE_Event_Handler *eh,
                                     ACE_Reactor_Mask mask,
                                     ACE_Time_Value *timeout)
{
  ACE_TRACE ("ACE_Dev_Poll_Reactor_Notify::notify");

  // Just consider this method a "no-op" if there's no
  // ACE_Dev_Poll_Reactor configured.
  if (this->dp_reactor_ == 0)
    return 0;

  ACE_Notification_Buffer buffer (eh, mask);

#if defined (ACE_HAS_REACTOR_NOTIFICATION_QUEUE)
  ACE_UNUSED_ARG (timeout);
  ACE_Dev_Poll_Handler_Guard eh_guard (eh);

  // When using the queue, the push call indicates whether or not a pipe
  // write is needed. If it's not, don't waste pipe space.
  int push_result = this->notification_queue_.push_new_notification (buffer);
  if (-1 == push_result || 1 == push_result)
    return -1 == push_result ? -1 : 0; // Also decrement eh's reference count
//这里第一次,因为返回1,直接return 0 了,并不往下运行。  // The notification has been queued, so it will be delivered at some
  // point (and may have been already); release the refcnt guard.
  eh_guard.release ();

  // Now pop the pipe to force the callback for dispatching when ready. If
  // the send fails due to a full pipe, don't fail - assume the already-sent
  // pipe bytes will cause the entire notification queue to be processed.
  // Note that we don't need a timeout since the pipe is already in
  // nonblocking mode and all we want is one attempt.
  ssize_t n = ACE::send (this->notification_pipe_.write_handle (),
                         (char *) &buffer,
                         1);             // Only need one byte to pop the pipe
  if (n == -1 && (errno != EAGAIN))
    return -1;

  return 0;
#else

  ACE_Dev_Poll_Handler_Guard eh_guard (eh);

  ssize_t n = ACE::send (this->notification_pipe_.write_handle (),
                         (char *) &buffer,
                         sizeof buffer,
                         timeout);
  if (n == -1)
    return -1;

  eh_guard.release ();

  return 0;
#endif /* ACE_HAS_REACTOR_NOTIFICATION_QUEUE */
}


不解,不知道为什么这么处理?
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-11-22 02:08 , Processed in 0.012572 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表