Порты завершения ввода / вывода, когда увеличивать / уменьшать RefCount of Per socket в многопоточном исполнении? - PullRequest
0 голосов
/ 06 мая 2018

Я читаю этот вопрос Порты завершения ввода / вывода * LAST *, называемые обратным вызовом, или: где безопасно очищать вещи

И я не могу решить мою проблему. Ответ не полностью охватывает этот метод. Я также много искал здесь и в Google, но не могу найти решение, поэтому я открываю здесь вопрос, надеюсь, что не дублируется.

В конструкции многопоточных портов завершения ввода-вывода, когда увеличить RefCount структуры Per Socket? то есть CompletionKey. В настоящее время я увеличиваю его перед вызовом WSARecv, и если возвращаемое значение вызова не равно 0 или ERROR_IO_PENDING из-за последней ошибки, я уменьшаю его и вызываю функцию очистки, эта функция проверяет, равен ли RefCount 0, если это так, то это освободит структуру Per Socket. В противном случае он просто освободит структуру Per IO (структуру OVERLAPPED), я также увеличу ее перед выдачей любого WSASend, используя тот же способ, который упомянут выше. Это RefCount атомарное использование CRITCAL_SECTION. По возвращении с GetQueuedCompletionStatus я также уменьшаю RefCount.

Однако у меня есть несколько вопросов об этом методе

У меня есть функция, которая отправляет файлы из основного потока, функция читает файл и выдает PostQueuedCompletionStatus для отправки, используя WSASend через потоки IO Worker, функция отправляет файл порциями, и когда каждый chunk завершает потоки IO Worker, сообщая основному потоку с помощью PostMessage, чтобы выполнить еще одну отправку следующего блока.

Теперь, где я должен увеличить это RefCount? в главном потоке перед тем, как позвонить на PostQueuedCompletionStatus? но что, если возврат из GetQueuedCompletionStatus вернул и освободил структуру Per Socket и основной поток все еще использует ее? (Например, основной поток выполняет функцию отправки, но еще не увеличил RefCount) Я попытался увеличить RefCount в функции WSASend в потоках IO Worker, но это та же проблема

Например: что, если поток проснулся от GetQueuedCompletionStatus как закрытие сокета (вызванное невыполнением WSARecv) и уменьшил значение RefCount и стало 0, так что он освободит структуру Per Socket, а WSASend выполняется в другом потоке IO Worker, но еще не увеличил RefCount? тогда очевидно, что поток, который собирается выполнить вызов WSASend, будет аварийно завершать работу с нарушением прав доступа при попытке войти в критическую секцию.

Есть идеи, как синхронизировать доступ к этой структуре между потоками IO Worker и основным потоком?

...