Требования к обработке завершения NDKPI
Потребители NDK и поставщики NDK должны соответствовать этим требованиям для обработки завершения NDKPI.
Правила для функций NdkGetCqResults, NdkGetCqResultsEx и NdkArmCq
Потребитель всегда сериализует свои вызовы к этим функциям поставщика в одном объекте очереди завершения (CQ) (NDK_CQ):
- NdkGetCqResults (NDK_FN_GET_CQ_RESULTS)
- NdkGetCqResultsEx (NDK_FN_GET_CQ_RESULTS_EX)
- NdkArmCq (NDK_FN_ARM_CQ)
Это означает не только то, что потребитель никогда не будет вызывать одну и ту же функцию поставщика несколько раз одновременно, но и то, что он никогда не будет вызывать какие-либо сочетания этих функций одновременно в одном И том же CQ из нескольких потоков.
Завершение NdkOperationTypeReceiveAndInvalidate , которое происходит в результате удаленного вызова NdkSendAndInvalidate (NDK_FN_SEND_AND_INVALIDATE), по-прежнему должно быть извлечено с помощью NdkGetCqResults (не NdkGetCqResultsExn). Это по-прежнему должно сделать недействительным указанный маркер на получателе, но не будет уведомлять принимающего потребителя об этой недействительности (потребитель должен использовать NdkGetCqResultsEx для получения этих сведений). Более поздняя версия NdkInvalidate (NDK_FN_INVALIDATE) для того же токена завершится ошибкой, как обычно.
Правила обратного вызова уведомлений
Поставщик должен вызывать обратный вызов NdkCqNotificationCallback (NDK_FN_CQ_NOTIFICATION_CALLBACK) только один раз и только после того, как потребитель вооружил обратный вызов NdkCqNotificationCall, вызвав NdkArmCq. То есть поставщик должен очистить руку и вызвать обратный вызов NdkCqNotificationCallback при выполнении условий для вызова обратного вызова NdkCqNotificationCallback (иными словами, когда завершение запроса помещается в очередь в CQ).
Если в CQ уже присутствуют завершения, когда потребитель вызывает NdkArmCq, поставщик будет вести себя следующим образом:
- Если хотя бы одно из завершений было добавлено в CQ с момента последнего вызова обратного вызова NdkCqNotificationCallback , поставщик должен немедленно выполнить запрос arm (требования сериализации см. ниже).
- Однако если все завершения в CQ присутствовали также при последнем вызове обратного вызова NdkCqNotificationCall (другими словами, потребитель вызвал NdkArmCq без удаления всех завершений и новые завершения не были помещены в CQ), поставщик может немедленно выполнить запрос arm.
Если поставщику необходимо вызвать обратный вызов NdkCqNotificationCallback , если уже выполняется обратный вызов NdkCqNotificationCallback , поставщик должен отложить вызов обратного вызова NdkCqNotificationCallback до тех пор, пока существующий вызов NdkCqNotificationCallback не вернет управление поставщиком. Другими словами, поставщик отвечает за сериализацию обратных вызовов NdkCqNotificationCallback .
В следующей таблице показан результирующий тип arm, если NdkArmCq вызывается во второй раз до выполнения предыдущего запроса NdkArmCq :
2-я рука ANY | 2-й arm ERRORS | 2-я рука, запрошенная | |
---|---|---|---|
1-я рука ANY |
ANY |
ANY |
ANY |
ОШИБКИ 1-й руки |
ANY |
ОШИБКИ |
ЗАПРОСИЛ |
1-я рука запрашивается |
ANY |
ЗАПРОСИЛ |
ЗАПРОСИЛ |