Эполл - EPOLLONESHOT многопоточный - PullRequest
0 голосов
/ 22 февраля 2020

В настоящее время я создаю сервер веб-сокетов, используя epoll с неблокирующими сокетами. Сервер поддерживает SSL с использованием OpenSSL. Моя настройка следующая:

  1. У меня есть 1 основной поток, который выполняет epoll_wait () на всех клиентских сокетах. Когда происходит что-то новое (EPOLLIN | EPOLLOUT), он отправляет работу в один из n рабочих потоков. Все клиентские сокеты настроены с помощью EPOLLET | EPOLLONESHOT с использованием EPOLL_CTL_ADD / EPOLL_CTL_MOD.
  2. У меня есть n рабочих потоков, которые либо: подключаются, отключаются, читаются или пишутся для клиентского сокета. Когда одно из 4 заданий было обработано, клиентский сокет настраивается с EPOLLIN / EPOLLOUT, EPOLLET и EPOLLONESHOT, снова используя EPOLL_CTL_MOD.
  3. С использованием EPOLLONESHOT я гарантирую, что дескриптор файла клиента используется только один поток за раз.
  4. Когда один клиент пишет другому, отправленное сообщение в настоящее время помещается в кольцевой буфер MPS C получателя. Этот кольцевой буфер должен быть обработан дескриптором принимающего файла с использованием рабочего потока, выполняющего задание записи. Чтобы дескриптор принимающего файла знал, что он должен выполнить запись, мне нужно установить EPOLLOUT для его дескриптора файла epoll.

В этот момент дескриптор принимающего файла может выполнять другую работу, такую ​​как чтение или может просто ждать в главном потоке. Мой вопрос заключается в том, как (поточно) безопасно использовать EPOLL_CTL_MOD в дескрипторе файла epoll принимающего клиента, чтобы я сохранил гарантию в пункте 3? другое задание, может быть выполнено с помощью другого кольцевого буфера MPS C с событиями epoll, который будет добавлен в конце рабочей обработки, но как мне справиться со случаем, когда в настоящий момент никакие задания для дескриптора файла не обрабатываются, без введения какого-либо состояние гонки?

Вопрос несколько связан с обходной частью Как использовать epoll для чтения и записи с того же FD , но даже с использованием dup и наличием отдельных ожиданий для чтения и пишет, я не думаю, что это вариант, так как OpenSSL может требовать SSL_ERROR_WANT_WRITE для чтения и SSL_ERROR_WANT_READ для записи.

...