Я читаю этот вопрос
Порты завершения ввода / вывода * 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 и основным потоком?