Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Erstellen, Verwenden und Schließen von NDK-Objekten
Ein NDK-Consumer initiiert eine Erstellungsanforderung für ein NDK-Objekt, indem die Create-Funktion des NDK-Anbieters für dieses Objekt aufgerufen wird.
Wenn der Consumer eine Create-Funktion aufruft, übergibt er ein NdkCreateCompletion (NDK_FN_CREATE_COMPLETION) als Parameter.
Der Konsument initiiert verschiedene Anforderungen durch Aufrufen von Funktionen des Anbieters in der Dispatch-Tabelle des Objekts und übergibt einen NdkRequestCompletion (NDK_FN_REQUEST_COMPLETION) Abschluss-Callback als Parameter.
Wenn ein Objekt nicht mehr benötigt wird, ruft der Consumer die NdkCloseObject (NDK_FN_CLOSE_OBJECT)-Funktion des Anbieters auf, um eine schließende Anforderung für das Objekt zu initiieren, und übergibt einen NdkCloseCompletion -Rückruf (NDK_FN_CLOSE_COMPLETION) als Parameter.
Der Anbieter ruft die Rückruffunktion des Verbrauchers auf, um die Anforderung asynchron abzuschließen. Dieser Aufruf gibt dem Consumer an, dass der Anbieter den Vorgang abgeschlossen hat (z. B. das Schließen des Objekts) und das Steuerelement an den Consumer zurückgibt. Wenn der Anbieter die Schließen-Anforderung synchron abgeschlossen hat, entweder erfolgreich oder fehlerhaft, ruft er die Rückruffunktion des Verbrauchers nicht auf.
Die Regeln für Abschlussrückrufe
Wenn ein Anbieter ein Objekt auf Anforderung eines Consumers erstellt hat, ruft der Anbieter den NdkCreateCompletion-Rückruf des Verbrauchers auf, um anzugeben, dass das Objekt einsatzbereit ist.
Der Consumer kann andere Anbieterfunktionen für dasselbe Objekt aufrufen, ohne darauf zu warten, dass der erste Rückruf zurückgegeben wird.
Der Consumer ruft die NdkCloseObject-Funktion für ein Objekt erst auf, wenn alle Anbieterfunktionen für dieses Objekt zurückgegeben wurden.
Wenn die Anbieterfunktion jedoch eine Abschlussanforderung initiiert, kann der Consumer NdkCloseObject innerhalb dieses Abschlussrückrufs aufrufen, auch wenn die Anbieterfunktion nicht zurückgegeben wurde.
Eine Anbieterfunktion kann eine Abschlussanforderung initiieren, bevor sie von einem Rückruf zurückgegeben wird, indem Sie eine der folgenden Aktionen ausführen:
- Direktes Aufrufen des Abschluss-Callbacks
- Einen Abschlussanforderung in die Warteschlange zu einem anderen Thread einreihen
Durch das Initiieren einer Abschlussanforderung gibt der Anbieter effektiv die Kontrolle an den Verbraucher zurück. Der Anbieter muss davon ausgehen, dass das Objekt jederzeit geschlossen werden kann, nachdem der Anbieter die Abschlussanforderung initiiert hat.
Anmerkung Um das Deadlock nach dem Initiieren einer Abschlussanforderung zu verhindern, muss der Anbieter eine der folgenden Aktionen ausführen:
- Es werden erst andere Vorgänge für das Objekt ausgeführt, wenn der Abschlussrückruf zurückgegeben wird.
- Ergreifen Sie die erforderlichen Maßnahmen, um das Objekt intakt zu halten, wenn der Anbieter das Objekt unbedingt berühren muss.
Beispiel: Consumer-Provider Interaktion
Betrachten Sie das folgende Szenario:
- Der Consumer erstellt einen Connector (NDK_CONNECTOR) und ruft dann NdkConnect (NDK_FN_CONNECT) auf.
- Der Anbieter verarbeitet die Verbindungsanforderung, trifft einen Fehler und ruft den Abschlussrückruf des Verbrauchers im Kontext des NdkConnect-Aufrufs auf (im Gegensatz zur Rückgabe von Inlinefehlern aufgrund einer internen Implementierungsauswahl).
- Der Consumer ruft NdkCloseObject im Kontext dieses Abschluss-Callbacks auf, obwohl der NdkConnect-Aufruf noch nicht an den Consumer zurückgekehrt ist.
Um deadlock zu vermeiden, darf der Anbieter das Connectorobjekt nach Schritt 2 nicht berühren (der Punkt, an dem er den Abschlussrückruf innerhalb des NdkConnect-Aufrufs initiiert hat).
Schließen von Antecedent- und Nachfolgerobjekten
Der Anbieter muss darauf vorbereitet sein, dass der Verbraucher die NdkCloseObject-Funktion aufruft, um ein vorheriges Objekt zu schließen, bevor der Verbraucher NdkCloseObject für Nachfolgerobjekte aufruft. Wenn der Verbraucher dies tut, muss der Anbieter folgendes tun:
- Der Anbieter darf das vorangehende Objekt erst schließen, wenn alle Nachfolgerobjekte geschlossen sind, d. h., der Anbieter muss STATUS_PENDING aus der Close-Anforderung zurückmelden und diese vollständig abschließen (durch Aufrufen der registrierten NdkCloseCompletion-Funktion für die Close-Anforderung), sobald alle Nachfolgerobjekte geschlossen sind.
- Der Verbraucher verwendet das vorausgehende Objekt nach dem Aufrufen von NdkCloseObject nicht, sodass der Anbieter keine Behandlung für weitere Anbieterfunktionen, die auf dem vorausgehenden Objekt fehlschlagen, hinzufügen muss (er kann dies jedoch tun, wenn er sich dazu entscheidet).
- Der Anbieter kann die Schließanforderung wie eine einfache Dereferenzierung behandeln, die keinen anderen Nebeneffekt hat, bis das letzte Nachfolgeobjekt geschlossen wird, es sei denn, es ist anders erforderlich (siehe den Schließvorgang des NDK-Listeners unten, der einen erforderlichen Nebeneffekt aufweist).
Der Anbieter darf die Schließenanfrage für ein vorhergehendes Objekt (einschließlich der NDK_ADAPTER-Schließenanfrage) nicht abschließen, bevor ein laufender Abschlussrückruf für ein Nachfolgerobjekt an den Anbieter zurückgegeben wird. Dadurch können NDK-Verbraucher sicher entladen werden.
Ein NDK-Verbraucher ruft NdkCloseObject nicht für ein NDK_ADAPTER-Objekt auf (was ein blockierender Aufruf ist), während er sich in einer Verbraucherrückruffunktion befindet.
Schließen von Adapterobjekten
Betrachten Sie das folgende Szenario:
- Der Consumer ruft NdkCloseObject für ein CQ-Objekt (Completion Queue) auf.
- Der Anbieter gibt STATUS_PENDING zurück und ruft später den Abschlussrückruf des Verbrauchers auf.
- Innerhalb dieses Abschlussrückrufs signalisiert der Verbraucher ein Ereignis, dass es jetzt „OK“ ist, die NDK_ADAPTER zu schließen.
- Ein weiterer Thread reaktiviert auf diesem Signal und schließt die NDK_ADAPTER und fährt mit dem Entladen fort.
- Der Thread, in dem der CQ-Schließungsrückruf des Consumers aufgerufen wurde, befindet sich jedoch möglicherweise noch innerhalb der Rückruffunktion des Consumers (z. B. der Funktion epilog), sodass es für den Consumertreiber nicht sicher ist, ihn zu entladen.
- Da der Abschlussrückrufkontext der einzige Kontext ist, in dem der Verbraucher das Ereignis signalisieren kann, kann der Treiber des Verbrauchers das Problem eines sicheren Entladens nicht selbst lösen.
Es muss einen Punkt geben, an dem der Konsument sicher sein kann, dass alle Rückrufe die Kontrolle zurückgegeben haben. In NDKPI gibt dieser Punkt an, wann die Close-Anforderung an einen NDK_ADAPTER die Kontrolle zurückgibt. Beachten Sie, dass NDK_ADAPTER Schließanforderung ein blockierender Aufruf ist. Wenn eine Schließanforderung von einem NDK_ADAPTER zurückkehrt, ist garantiert, dass alle Rückrufe bei allen Objekten, die von diesem NDK_ADAPTER-Objekt abstammen, die Kontrolle an den Anbieter zurückgegeben haben.
Abschluss von Schließen-Anfragen
Der Anbieter darf eine Close-Anforderung für ein Objekt erst abschließen, wenn:
- Alle ausstehenden asynchronen Anforderungen für das Objekt wurden abgeschlossen (d. h. ihre Abschlussrückrufe wurden an den Anbieter zurückgegeben).
- Alle Ereignisrückrufe des Verbrauchers (z. B. NdkCqNotificationCallback (NDK_FN_CQ_NOTIFICATION_CALLBACK) für einen CQ, NdkConnectEventCallback (NDK_FN_CONNECT_EVENT_CALLBACK) für einen Listener) sind zum Anbieter zurückgekehrt.
Der Anbieter muss sicherstellen, dass nach dem Aufruf des Abschlussrückrufs keine weiteren Rückrufe auftreten, oder nachdem die Schließenanforderung STATUS_SUCCESS zurückgegeben wird. Beachten Sie, dass eine Close-Anforderung auch alle erforderlichen Lösch- oder Abbruchvorgänge von ausstehenden asynchronen Anforderungen initiieren muss.
Anmerkung Daraus folgt logisch, dass ein NDK-Consumer NdkCloseObject nicht für ein NDK_ADAPTER-Objekt (das ein Blockierungsaufruf ist) innerhalb einer Consumerrückruffunktion aufrufen darf.