ACE Reactor框架中单个事件的多个处理程序

时间:2013-05-24 17:42:01

标签: c++ ace

我正在设计一个接受传入连接的服务器,客户端偶尔会发送服务器需要响应的请求,但主要是服务器检测到某些事件并将事件广播给所有连接的客户端。基本上我所拥有的是:

#include <ace/Acceptor.h>
#include <ace/INET_Addr.h>
#include <ace/Reactor.h>
#include <ace/SOCK_Acceptor.h>
#include <ace/SOCK_Stream.h>
#include <ace/Svc_Handler.h>

#include <iostream>
#include <thread>

// XXX: for simplicity
HANDLE const hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);

class MyService
  : public ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
{
public:
  MyService() : signalCount_(0) { }

  int open(void*) override
  {
    ACE_Reactor::instance()->register_handler(
        this,
        ACE_Event_Handler::READ_MASK);

    ACE_Reactor::instance()->register_handler(
        this,
        hEvent);

    return 0;
  }

  int handle_input(ACE_HANDLE) override
  {
    // Handle stuff coming in from clients.
    return 0;
  }

  int handle_signal(int, siginfo_t*, ucontext_t*) override
  {
    // handle the detected event, send to client.
    std::cout
      << signalCount_++ << " "
      << this << " "
      << __FUNCTION__
      << std::endl;
    return 0;
  }

  unsigned signalCount_;
};

typedef ACE_Acceptor<MyService, ACE_SOCK_ACCEPTOR> MyAcceptor;

int main()
{
  WSADATA wsData;
  WSAStartup(MAKEWORD(2, 0), &wsData);

  std::thread thr([=]()
  {
    // simulate the events.
    Sleep(1000);
    SetEvent(hEvent);
  });

  auto r = ACE_Reactor::instance();
  MyAcceptor acceptor(ACE_INET_Addr(1234), r);

  r->run_reactor_event_loop();
}

这里的问题是,无论何时设置hEvent,只有MyService的第一个实例调用其handle_signal。看起来一个事件只允许一个处理程序,处理程序可以处理多个事件。如何让多个处理程序处理单个事件?

如果我使事件手动重置事件,那么只要事件被设置,所有处理程序都会调用它们的handle_signal。但这真的不是我想要的 - 我不希望客户多次收到同一事件的通知。

我通过使用信号量而不是事件来实现我的目标:

HANDLE const hEvent = ::CreateSemaphore(NULL, 0, 16, NULL);

并使MyService的construtor和析构函数计算连接客户端的数量,以便我可以正确释放信号量:

  std::thread thr([=]()
  {
     while (true)
     {
        Sleep(1000);
        ReleaseSemaphore(hEvent, clientCount, nullptr);
     }
  });

这似乎是错误的,闻起来很像黑客。是否有适当的方法与ACE一起做这个?

0 个答案:

没有答案