NDKPI 개체 수명 요구 사항

NDK 개체를 만들고, 사용하고, 닫는 방법

NDK 소비자는 해당 개체에 대해 NDK 공급자의 create 함수를 호출하여 NDK 개체에 대한 만들기 요청을 시작합니다.

소비자가 create 함수를 호출하면 NdkCreateCompletion (NDK_FN_CREATE_COMPLETION)을 매개 변수로 전달합니다.

소비자는 개체의 디스패치 테이블에서 공급자 함수를 호출하여 NdkRequestCompletion (NDK_FN_REQUEST_COMPLETION) 완료 콜백을 매개 변수로 전달하여 다양한 요청을 시작합니다.

개체가 더 이상 필요하지 않은 경우 소비자는 공급자의 NdkCloseObject (NDK_FN_CLOSE_OBJECT) 함수를 호출하여 개체에 대한 닫기 요청을 시작하고 NdkCloseCompletion (NDK_FN_CLOSE_COMPLETION) 콜백을 매개 변수로 전달합니다.

공급자는 소비자의 콜백 함수를 호출하여 요청을 비동기적으로 완료합니다. 이 호출은 공급자가 작업을 완료하고(예: 개체 닫기) 제어를 소비자에게 반환하고 있음을 소비자에게 나타냅니다. 공급자가 성공적으로 또는 오류로 닫기 요청을 동기적으로 완료하는 경우 소비자의 콜백 함수를 호출하지 않습니다.

완료 콜백에 대한 규칙

공급자가 소비자의 요청에 따라 개체를 만든 경우 공급자는 소비자의 NdkCreateCompletion 콜백을 호출하여 개체를 사용할 준비가 되었음을 나타냅니다.

소비자는 첫 번째 콜백이 반환되는 것을 기다리지 않고 동일한 개체에 대해 다른 공급자 함수를 호출할 수 있습니다.

소비자는 해당 개체에 대한 모든 공급자 함수가 반환될 때까지 개체에 대해 NdkCloseObject 함수를 호출하지 않습니다.

그러나 공급자 함수가 완료 요청을 시작하는 경우 공급자 함수가 반환되지 않은 경우에도 소비자는 해당 완료 콜백 내에서 NdkCloseObject 를 자유롭게 호출할 수 있습니다.

공급자 함수는 다음 중 하나를 수행하여 콜백에서 반환하기 전에 완료 요청을 시작할 수 있습니다.

  • 완료 콜백을 직접 호출
  • 완료 요청을 다른 스레드로 큐에 대기

완료 요청을 시작하면 공급자는 소비자에 대한 제어를 효과적으로 반환합니다. 공급자는 공급자가 완료 요청을 시작한 후 언제든지 개체를 닫을 수 있다고 가정해야 합니다.

참고 완료 요청을 시작한 후 교착 상태를 방지하려면 공급자는 다음 중 하나를 수행해야 합니다.

  • 완료 콜백이 반환될 때까지 개체에서 다른 작업을 수행하지 않습니다.
  • 공급자가 개체를 반드시 터치해야 하는 경우 개체를 그대로 유지하는 데 필요한 조치를 취합니다.

예: Consumer-Provider 상호 작용

다음 시나리오를 고려하세요.

  1. 소비자는 커넥터(NDK_CONNECTOR)를 만든 다음 NdkConnect (NDK_FN_CONNECT)를 호출합니다.
  2. 공급자는 연결 요청을 처리하고, 실패에 도달하고, NdkConnect 호출의 컨텍스트에서 소비자의 완료 콜백을 호출합니다(내부 구현 선택으로 인해 인라인 오류를 반환하는 것과 반대).
  3. 소비자는 NdkConnect 호출이 아직 소비자에게 반환되지 않았더라도 이 완료 콜백의 컨텍스트에서 NdkCloseObject를 호출합니다.

교착 상태를 방지하려면 공급자가 2단계( NdkConnect 호출 내에서 완료 콜백을 시작한 시점) 후에 커넥터 개체를 건드리지 않아야 합니다.

선행 및 후속 개체 닫기

소비자가 후속 개체에 대해 NdkCloseObject 를 호출하기 전에 소비자가 선행 개체를 닫기 위해 NdkCloseObject 함수를 호출할 수 있도록 공급자를 준비해야 합니다. 소비자가 이 작업을 수행하는 경우 공급자가 수행해야 하는 작업은 다음과 같습니다.

  • 공급자는 모든 후속 개체가 닫히기 전까지 선행 개체를 닫지 않아야 합니다. 즉, 공급자는 모든 후속 개체가 닫히면 닫기 요청에서 STATUS_PENDING 반환하고 닫기 요청에 대해 등록된 NdkCloseCompletion 함수를 호출하여 완료해야 합니다.
  • 소비자는 NdkCloseObject 를 호출한 후 선행 개체를 사용하지 않으므로 공급자는 선행 개체에 대한 추가 공급자 함수 실패에 대한 처리를 추가할 필요가 없습니다(그러나 선택하는 경우일 수 있음).
  • 공급자는 달리 필요하지 않은 경우 마지막 후속 개체가 닫히기 전까지 다른 부작용이 없는 간단한 역참조처럼 닫기 요청을 처리할 수 있습니다(필요한 부작용이 있는 아래 NDK 수신기 닫기 사례 참조).

공급자는 후속 개체에 대한 진행 중인 닫기 완료 콜백이 공급자에게 반환되기 전에 선행 개체( NDK_ADAPTER 닫기 요청 포함)에 대한 닫기 요청을 완료하지 않아야 합니다. 이는 NDK 소비자가 안전하게 언로드할 수 있도록 하기 위한 것입니다.

NDK 소비자는 소비자 콜백 함수 내에서 NDK_ADAPTER 개체(차단 호출)에 대해 NdkCloseObject를 호출하지 않습니다.

어댑터 개체 닫기

다음 시나리오를 고려하세요.

  1. 소비자는 CQ(완료 큐) 개체에서 NdkCloseObject 를 호출합니다.
  2. 공급자는 STATUS_PENDING 반환하고 나중에 소비자의 완료 콜백을 호출합니다.
  3. 이 완료 콜백 내에서 소비자는 이제 NDK_ADAPTER 닫아도 괜찮다는 이벤트를 알릴 수 있습니다.
  4. 또 다른 스레드는 이 신호를 깨우고 NDK_ADAPTER 닫고 언로드를 진행합니다.
  5. 그러나 소비자의 CQ 닫기 완료 콜백이 호출된 스레드는 여전히 소비자의 콜백 함수(예: 함수 에필로그) 내에 있을 수 있으므로 소비자 드라이버가 언로드하는 것이 안전하지 않습니다.
  6. 완성 콜백 컨텍스트는 소비자가 이벤트에 신호를 보낼 수 있는 유일한 컨텍스트이므로 소비자 드라이버는 안전 언로드 문제 자체를 해결할 수 없습니다.

소비자가 모든 콜백이 제어를 반환했음을 확신할 수 있는 지점이 있어야 합니다. NDKPI에서 이 점은 NDK_ADAPTER 대한 닫기 요청이 컨트롤을 반환하는 시점입니다. NDK_ADAPTER 닫기 요청은 차단 호출입니다. NDK_ADAPTER 닫기 요청이 반환되면 해당 NDK_ADAPTER 개체에서 내림차순인 모든 개체의 모든 콜백이 컨트롤을 공급자에게 반환하도록 보장됩니다.

닫기 요청 완료

공급자는 다음까지 개체에 대한 닫기 요청을 완료하면 안됩니다.

  • 개체에 대해 보류 중인 모든 비동기 요청이 완료되었습니다(즉, 완료 콜백이 공급자에게 반환됨).
  • 소비자의 모든 이벤트 콜백(예: CQ의 NdkCqNotificationCallback (NDK_FN_CQ_NOTIFICATION_CALLBACK), 수신기의 NdkConnectEventCallback (NDK_FN_CONNECT_EVENT_CALLBACK))이 공급자에게 반환되었습니다.

공급자는 닫기 완료 콜백이 호출된 후 또는 닫기 요청이 STATUS_SUCCESS 반환한 후에 더 이상 콜백이 발생하지 않도록 보장해야 합니다. 또한 닫기 요청은 보류 중인 비동기 요청의 필요한 플러시 또는 취소를 시작해야 합니다.

참고 NDK 소비자가 소비자 콜백 함수 내에서 NDK_ADAPTER 개체(차단 호출)에 대해 NdkCloseObject를 호출해서는 안 됨을 논리적으로 따릅니다.

NDKPI(네트워크 직접 커널 공급자 인터페이스)