dean 发表于 2011-1-26 11:32:21

Dev_Poll_Reactor notify问题。

在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 */
}


不解,不知道为什么这么处理?
页: [1]
查看完整版本: Dev_Poll_Reactor notify问题。