Несколько обработчиков для одного события в платформе ACE Reactor

Я проектирую сервер, который принимает входящие соединения, клиенты время от времени отправляют запросы, на которые сервер должен ответить, но в основном сервер обнаруживает некоторые события и передает событие всем подключенным клиентам. В основном то, что у меня есть это:

#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. Похоже, только один обработчик разрешен для одного события, бит обработчик может обрабатывать несколько событий. Как сделать так, чтобы несколько обработчиков обрабатывали одно событие?

Если я создаю событие manual-reset-event, тогда все обработчики получают их handle_signal, пока событие установлено. Но это действительно не то, чего я хочу — я не хочу, чтобы клиент был уведомлен об одном и том же событии несколько раз.

Я как бы достиг своей цели, используя семафор вместо события:

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

И заставил строителя и деструктора MyService подсчитать количество подключенных клиентов, чтобы я мог выпустить семафор правильное число раз:

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

Это кажется неправильным и пахнет как хак. Есть ли правильный способ сделать это с ACE?

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector