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互動
請考慮下列案例:
- 取用者會建立連接器 (NDK_CONNECTOR) ,然後呼叫 NdkConnect (NDK_FN_CONNECT) 。
- 提供者會處理連線要求、叫用失敗,並在 NdkConnect 呼叫的內容中呼叫取用者的完成回呼 (,而不是因為內部實作選擇而傳回內嵌失敗) 。
- 即使NdkConnect呼叫尚未傳回給取用者,取用者仍會在此完成回呼的內容中呼叫NdkCloseObject。
若要避免死結,提供者在步驟 2 (起始 NdkConnect 呼叫內完成回呼的點之後,提供者不得觸碰連接器物件) 。
關閉前項和後續物件
在取用者呼叫後續物件的NdkCloseObject之前,取用者必須準備好呼叫NdkCloseObject才能關閉前項物件。 如果取用者這麼做,以下是提供者必須執行的動作:
- 提供者在關閉所有後續物件之前,都必須關閉前項物件,亦即提供者必須從關閉要求傳回STATUS_PENDING,並在關閉要求後呼叫已註冊 的 NdkCloseComplet) ion 函式,以完成 (。
- 取用者不會在呼叫 NdkCloseObject 之後使用前項物件,因此提供者不需要在前項物件上新增任何無法進一步提供者函式的處理, (,但如果它選擇) 。
- 除非另有需要,否則提供者可能會將關閉要求視為沒有其他副作用的簡單取值,除非另有需要,否則 (請參閱下方的 NDK 接聽程式關閉案例,其具有必要的副作用) 。
提供者不得在前項物件上完成關閉要求, (包括 NDK_ADAPTER 關閉要求) ,才能在任何後續物件上任何進行中的關閉完成回呼傳回給提供者。 這是允許 NDK 取用者安全地卸載。
NDK 取用者不會針對NDK_ADAPTER物件呼叫NdkCloseObject (這是取用者回呼函式內的封鎖呼叫) 。
關閉配接器物件
請考慮下列案例:
- 取用者會在完成佇列上呼叫 NdkCloseObject , (CQ) 物件。
- 提供者會傳回STATUS_PENDING,稍後會呼叫取用者的完成回呼。
- 在此完成回呼內,取用者會發出事件,指出現在可以關閉NDK_ADAPTER。
- 另一個執行緒會在此訊號上喚醒,並關閉 NDK_ADAPTER 並繼續卸載。
- 不過,呼叫取用者 CQ 關閉完成回呼的執行緒可能仍位於取用者的回呼 (函式內,例如,函式 結尾) ,因此消費者驅動程式無法放心卸載。
- 因為完成回呼內容是取用者可以發出事件訊號的唯一內容,所以取用者驅動程式無法解決安全卸載問題本身。
取用者必須確定其所有回呼都有傳回控制權的點。 在 NDKPI 中,這是 當NDK_ADAPTER 上的關閉要求傳回控制項時。 請注意, NDK_ADAPTER 關閉要求是封鎖呼叫。 當 NDK_ADAPTER 關閉要求傳回時,保證從該 NDK_ADAPTER 物件遞減的所有物件上,所有回呼都會傳回給提供者。
正在完成關閉要求
提供者在下列之前,不得在 物件上完成關閉要求:
- 物件上所有擱置的非同步要求都已完成 (,換句話說,其完成回呼已傳回給提供者) 。
- 例如, NdkCqNotificationCallback (NDK_FN_CQ_NOTIFICATION_CALLBACK CQ 、 NdkConnectEventCallback) 、NdkConnectEventCallback ( (NDK_FN_CONNECT_EVENT_CALLBACK 接聽程式) 上) 的所有 (事件回呼都已傳回提供者。
提供者必須保證在呼叫關閉完成回呼之後,或關閉要求傳回STATUS_SUCCESS之後,不會再發生回呼。 請注意,關閉要求也必須起始任何所需的清除或解除擱置非同步要求。
注意其邏輯上會遵循上述內容,NDK 取用者不得針對NDK_ADAPTER物件呼叫NdkCloseObject (,這是取用者回呼函式內的封鎖呼叫) 。