Использование обратных вызовов библиотеки сторонних производителей (без файлового дескриптора) в управляемой событиями / асинхронной структуре - PullRequest
2 голосов
/ 29 ноября 2010

Целью является создание однопоточной управляемой событиями среды.Конечный пользователь будет делать что-то вроде:

class MyEventFramework : public EventFramework {
protected:
  virtual void onData (const Data& data);
  virtual void onReport (const Report& report);
  virtual void onUserRequest (const UserRequest& userRequest);
...
};

За кулисами находятся другие компоненты, такие как ряд таймеров и т. Д.

Большинство этих обработчиков вызываются моим собственным кодомпоэтому я могу использовать select() или аналогичное понятие (kqueue(), epoll() и т. д.) для ряда файловых дескрипторов .

Моя проблема заключается в том, что onData()рутина фактически является обратным вызовом из сторонней библиотеки, для которой у меня нет исходного кода.Поэтому я не могу просто использовать их дескриптор файла ;Я только знаю, что что-то произошло через обратный вызов.

Прямо сейчас у меня есть многопоточная реализация моей платформы;логика, ведущая до onData(), происходит в отдельном потоке перед тем, как связаться с пользователем.Это нежелательно, поскольку оно требует подверженных ошибкам блокировок мьютекса, требует дорогостоящего переключения потоков (это приложение с низкой задержкой) и других проблем.(Чтобы уточнить, каждый обработчик в платформе должен быть атомарным по отношению друг к другу из-за потенциальной возможности состязания в клиентском приложении.)

Кто-нибудь еще сталкивался с этим раньше и жил, чтобы рассказать историю?

Ответы [ 2 ]

3 голосов
/ 02 декабря 2010

Если я правильно понимаю: ваш поток рассылки заблокирован по какому-либо системному вызову (скажем, select или poll), и вы хотите, чтобы функция-член onData следовала тому же пути уведомления.

Использование трубы кажется мне хорошим решением без излишней нагрузки на дизайн:

  • select контролирует один конец трубы
  • 3-ий библиотечные обратные вызовы «звонят» другому концу канала при вызове

Это допускает «скачок потока», единственная проблема в том, что канал должен использоваться только как средство уведомления: параметр функции onData должен быть поставлен в очередь где-то между уведомлением канала и потоком обработки пробуждения.

2 голосов
/ 02 декабря 2010

Я неравнодушен к самостоятельным локальным сокетам UDP (т. Е. Привязан к INADDR_LOOPBACK, затем подключен к тому же адресу) В этот момент ваш обратный вызов может записать в сокет либо один байт (для простого пробуждения), либо сообщение с данными обратного вызова.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...