Duplizieren von Socket handles für ein SAN
Mehrere Anwendungen, die in verschiedenen Prozessen ausgeführt werden, können den Windows Sockets-Switch verwenden, um Vorgänge für einen freigegebenen zugrunde liegenden Socket auszuführen. Es kann jedoch nur eine Anwendung gleichzeitig Vorgänge für diesen freigegebenen zugrunde liegenden Socket ausführen.
Um einen freigegebenen zugrunde liegenden Socket zu verwenden, muss eine Anwendung auf eine der folgenden Arten ein doppeltes Handle für diesen zugrunde liegenden Socket abrufen:
Direkt durch Aufrufen der Windows Sockets WSADuplicateSocket-Funktion
Der Aufruf erfolgt im Kontext des Steuerungsprozesses (dem Prozess, in dem der Socket erstellt wurde).
Indirekt durch Aufrufen der Win32 DuplicateHandle-Funktion
Der Aufruf erfolgt im Kontext eines nicht kontrollierbaren Prozesses (mit Ausnahme des Prozesses, in dem der Socket erstellt wurde).
Verwenden des Handlevererbungsmechanismus
Ein untergeordneter Prozess (der nicht steuernde Prozess) erbt alle oder einen Teil der Handles, die im übergeordneten Prozess (dem Steuerungsprozess) erstellt wurden.
Während des ordnungsgemäßen Verbindungsabschlusses
Wenn eine Anwendung im Steuerungsprozess einen Socket schließt und beendet, während einige Daten noch gesendet werden müssen, werden diese verbleibenden Daten in der Windows Sockets-DLL gepuffert. Eine andere Anwendung im Kontext des Systemdienstprozesses (der nicht kontrollierbare Prozess) sendet diese Daten anschließend.
Der Windows Sockets-Switch erkennt und verarbeitet in Verbindung mit dem TCP/IP-Anbieter jede der vorherigen Bedingungen. Der Switch ermöglicht es nur einem Prozess gleichzeitig, Vorgänge auszuführen, die entweder Daten übertragen oder den Zustand für einen zugrunde liegenden freigegebenen Socket ändern. Verarbeitet dynamisch die Steuerung des zugrunde liegenden Sockets nach Bedarf, um angeforderte Vorgänge auszuführen. Der Switch serialisiert Vorgänge, die von verschiedenen Prozessen für einen freigegebenen Socket ausgeführt werden sollen, und führt diese Vorgänge in fiFO-Reihenfolge (First-in-First-Out) aus. Der Switch wartet, bis alle laufenden Vorgänge abgeschlossen sind, bevor die Steuerung eines zugrunde liegenden Sockets durch einen anderen Prozess ausgetauscht wird. Logischerweise übernimmt der Switch die Kontrolle über den zugrunde liegenden Socket aus dem Steuerungsprozess, sobald ein nicht steuernder Prozess einen qualifizierenden Vorgang anfordert. Nachdem die Steuerung entfernt wurde, behandelt der Switch den ursprünglichen Steuerungsprozess wie einen nicht steuernden Prozess, wenn der ursprüngliche Steuerungsprozess qualifizierende Vorgänge anfordert. Beachten Sie, dass der Switch keine Aktion für ein doppeltes Sockethandle ausführt, bis der nicht kontrollierbare Prozess das doppelte Sockethandle tatsächlich für einen Datenübertragungs- oder Zustandsänderungsvorgang verwendet.
Sowohl der Switch als auch der entsprechende SAN-Dienstanbieter werden in alle Prozesse geladen, die den Zugriff auf einen bestimmten zugrunde liegenden Socket gemeinsam nutzen. Der Switch behält in allen Prozessen, die den Socket gemeinsam nutzen, seinen eigenen Socketkontext und Verbindungsstatusinformationen bei. Der SAN-Dienstanbieter muss seinen Socketkontext und seine Verbindungsstatusinformationen nur in dem Prozess beibehalten, der die Kontrolle über den zugrunde liegenden Socket zu einem bestimmten Zeitpunkt hat. Der SAN-Dienstanbieter muss die Steuerung seiner Kontext- und Verbindungsstatusinformationen aus dem aktuellen Steuerungsprozess in den nächsten Steuerungsprozess austauschen, wenn der Switch den Tausch erfordert, wie in der folgenden Sequenz beschrieben. Um die Menge an Ressourcen zu minimieren, die für den Austausch erforderlich sind, kann ein SAN-Dienstanbieter seine Kontext- und Verbindungsstatusinformationen in allen Prozessen verwalten, die einen zugrunde liegenden Socket gemeinsam nutzen.
Da der Switch den SAN-Socket, der einem Anwendungssocket entspricht, erst erstellt, wenn eine Anwendung entweder die Verbindungs- oder Listenfunktion aufruft, kann der Switch nicht anfordern, dass der SAN-Dienstanbieter einen Auslagerungsvorgang ausführt, bevor der Anwendungssocket verbunden ist oder lauscht. Auch nachdem der Anwendungssocket verbunden ist oder lauscht, muss eine der folgenden Bedingungen erfüllt sein, bevor der Switch anfordert, dass der SAN-Dienstanbieter die Steuerung des Sockets austauscht:
Ein Prozess, der den Socket nicht steuert, initiiert eine Datenübertragung. Der SAN-Dienstanbieter tauscht die Steuerung des Sockets erst aus, wenn alle Datenübertragungsvorgänge abgeschlossen sind, die vom Steuerungsprozess initiiert wurden.
Ein Prozess, der den Socket nicht steuert, ruft die Funktion WSAAccept, WSPAccept oder AcceptEx auf, um einen Verbindungsakzeptanzvorgang für einen Lauschocket zu starten. Der SAN-Dienstanbieter tauscht die Steuerung des Sockets erst aus, wenn alle vom Steuerungsprozess initiierten Anforderungen abgeschlossen sind.
Der Switch führt die folgenden Schritte aus, um die Steuerung eines verbundenen SAN-Sockets vom Steuerungsprozess in den nächsten Steuerungsprozess zu tauschen (eine Übersicht über den Austauschprozess finden Sie in der Tabelle im Abschnitt Hinweise der Dokumentation für die WSPDuplicateSocket-Funktion .):
Der Switch unterbricht die Verarbeitung neuer Anforderungen der Anwendung im Steuerungsprozess. Wenn alle laufenden Sende- und RDMA-Vorgänge auf dem SAN-Socket abgeschlossen sind, ruft der Switch die WSPSend-Funktion des SAN-Dienstanbieters auf, um eine Nachricht an einen verbundenen Peer zu senden, um eine Unterbrechung der Sitzung anzufordern, und ruft die WSPDeregisterMemory-Funktion des SAN-Dienstanbieters auf, um alle lokalen Puffer freizugeben, die für Sendevorgänge verwendet werden. Daher setzt der Switch an der Peerverbindung die Verarbeitung neuer Anwendungsanforderungen aus, wartet, bis alle Sende- und RDMA-Vorgänge auf dem SAN-Socket abgeschlossen sind, und gibt den gesamten RDMA-Arbeitsspeicher frei. Die Peerverbindung sendet als Nächstes eine Antwortmeldung, die angibt, dass die Sitzung angehalten wird. Beim Empfang dieser Bestätigungsmeldung ruft der Switch am lokalen Endpunkt die WSPDeregisterRdmaMemory-Funktion des SAN-Dienstanbieters auf, um den gesamten RDMA-Arbeitsspeicher freizugeben. An diesem Punkt können für SAN-Sockets an beiden Endpunkten der Verbindung nur Empfangsanforderungen ausstehen. Diese Empfangsanforderungen bleiben auf dem SAN-Socket des Remotepeers ausstehend, um die Reaktivierung der Sitzung zu ermöglichen. Die Empfangsanforderungen für den lokalen SAN-Socket im Steuerungsprozess werden im nächsten Schritt abgeschlossen. Während die Verbindung angehalten wird, stellt der Switch an der Remote-Peerverbindung neue blockierende oder überlappende Anforderungen in die Warteschlange, puffert neue Nonblocking sendet bis zur SO_SNDBUF-Einstellung, schlägt neue nicht blockierende Nachrichten nach Erreichen des Pufferlimits fehl, und alle neuen nonblocking empfängt mit WSAEWOULDBLOCK. Der lokale Switch im Steuerungsprozess verarbeitet neue Anforderungen am Anwendungssocket so, als hätte der Prozess keine Kontrolle über den Socket.
Nachdem die Sitzung angehalten wurde, ruft der Switch die WSPDuplicateSocket-Funktion des SAN-Dienstanbieters im Steuerungsprozess auf, um den SAN-Dienstanbieter anweisen, den Socketkontext in den Adressraum des nächsten Steuerungsprozesses zu übertragen. Der Switch gibt den Prozess für die nächste Steuerung im dwProcessId-Parameter von WSPDuplicateSocket an. Die WSPDuplicateSocket-Funktion muss die WPUCompleteOverlappedRequest-Funktion aufrufen, um alle ausstehenden Empfangsanforderungen für den Socket mit einem erfolgreichen status und null Bytes abzuschließen. Der SAN-Dienstanbieter muss auch automatisch alle Puffer freigeben, die diesen Anforderungen zugeordnet sind. Der SAN-Dienstanbieter gibt alle Puffer frei, da der Switch nach der Rückgabe von WSPDuplicateSocket keine weiteren Vorgänge für den SAN-Socket angibt. Die einzige mögliche Ausnahme ist ein WSPCloseSocket-Funktionsaufruf , wie im nächsten Schritt beschrieben. Nachdem WSPDuplicateSocket zurückgegeben wurde, speichert der Switch den Wert im dwProviderReserved-Member der WSAPROTOCOL_INFOW Struktur, auf die der lpProtocolInfo-Ausgabeparameter verweist. Der Switch verwendet diesen Wert, um den zugrunde liegenden Socket im Kontext der nächsten Steuerung zu identifizieren. Daher muss der Wert in dwProviderReserved den zugrunde liegenden Socket und die Verbindung für diesen Socket über alle Prozesse im System hinweg eindeutig identifizieren. Darüber hinaus muss dieser Wert nur im Kontext des Prozesses gültig sein, den der switch im dwProcessId-Parameter von WSPDuplicateSocket angegeben hat.
Nachdem der Socketkontext in den Adressraum des nächsten Controllingprozesses übertragen wurde, ruft der Switch die WSPSocket-Funktion des SAN-Dienstanbieters im Kontext des prozesses für die nächste Steuerung auf. In diesem Aufruf übergibt der Switch den Wert für den zugrunde liegenden Socket, der im WSPDuplicateSocket-Aufruf zurückgegeben wurde, an das dwProviderReserved-Element der WSAPROTOCOL_INFOW Struktur, auf die der lpProtocolInfo-Eingabeparameter verweist. Wenn der Prozess für die nächste Steuerung nicht die Erstellung des SAN-Sockets angefordert hat, muss der SAN-Dienstanbieter einen neuen Socket erstellen und die WPUCreateSocketHandle-Funktion aufrufen, um ein Handle abzurufen, wie für jeden neuen Socket erforderlich. Wenn der SAN-Socket im Kontext der nächsten Steuerung erstellt wurde, kann der SAN-Dienstanbieter den früheren Socket reaktivieren und denselben Deskriptor für den Socket zurückgeben, der zuvor verwendet wurde. In diesem Fall sollte der SAN-Dienstanbieter WPUCreateSocketHandle nicht aufrufen, sondern weiterhin das ursprüngliche Sockethandle verwenden, das der Switch bereitgestellt hat. Alternativ kann der SAN-Dienstanbieter einen neuen Socket erstellen, unabhängig davon, ob zuvor ein Socket im Prozess vorhanden war. In diesem Fall muss der Switch die WSPCloseSocket-Funktion des SAN-Dienstanbieters im Kontext des prozesses für die nächste Steuerung aufrufen, um den früheren Socketdeskriptor zu verwerfen.
Der Switch startet die Verarbeitung neuer Anforderungen aus der Anwendung im Prozess der nächsten Steuerung neu.
Der Switch dupliziert einen Lauschocket auf ähnliche Weise, mit dem Unterschied, dass der Switch nicht zum Anhalten einer Sitzung erforderlich ist. Der Switch wartet, bis er alle WSPAccept-Aufrufe abgeschlossen hat, die durch die Accept - und AcceptEx-Aufrufe einer Anwendung initiiert wurden, bevor er die WSPDuplicateSocket-Funktion des SAN-Dienstanbieters im Steuerungsprozess aufruft.
Da der Switch die Verarbeitung neuer Anforderungen an einem SAN-Socket vor dem Aufrufen der WSPDuplicateSocket-Funktion des SAN-Dienstanbieters aussetzt, kann der SAN-Dienstanbieter alle Ressourcen freigeben, die einem lokalen Endpunkt im Steuerungsprozess zugeordnet sind. Der SAN-Dienstanbieter kann sogar eine zugrunde liegende Verbindung beenden. Wenn der SAN-Dienstanbieter eine zugrunde liegende Verbindung im Steuerungsprozess schließt, muss der SAN-Dienstanbieter die Verbindung erneut herstellen, nachdem der Switch die WSPSocket-Funktion des SAN-Dienstanbieters innerhalb des nächsten Steuerungsprozesses aufgerufen hat. Nachdem der WSPSocket-Aufruf zurückgegeben wurde, muss sich der SAN-Socket im Prozess der nächsten Steuerung aus Sicht des Switches im gleichen Zustand befinden, da der SAN-Socket im Steuerungsprozess vor dem Switch aufgerufen wurde, der die WSPDuplicateSocket-Funktion des SAN-Dienstanbieters aufgerufen hat.
Wenn eine SAN-NIC die Freigabe von Ressourcen zwischen Endpunkten unterstützt, die in verschiedenen Prozessen ausgeführt werden, muss der SAN-Dienstanbieter keine Ressourcen für einen lokalen Endpunkt im Steuerungsprozess freigeben, bevor er einen WSPDuplicateSocket-Aufruf empfängt. In einem solchen Fall bleibt der SAN-Socket, der einem lokalen Endpunkt zugeordnet ist, im früheren Steuerungsprozess inaktiv, bis der Switch entweder den Socketkontext vom nächsten Steuern zurückwechselt oder die WSPCloseSocket-Funktion des SAN-Dienstanbieters aufruft, um den Socket explizit zu schließen. Da die meisten Anwendungen ihren endgültigen Zugriff auf den Socket in dem Prozess ausführen, der ihn ursprünglich erstellt hat – in der Regel zum Schließen der Verbindung –, kann der SAN-Dienstanbieter die Leistung verbessern, wenn der SAN-Dienstanbieter den Socketkontext im Steuerungsprozess behält, nachdem der Switch die Steuerung des Sockets an den nächsten Steuerungsprozess ausgetauscht hat.
Beachten Sie, dass in allen Fällen ein SAN-Socketdeskriptor gültig bleiben muss, bis der Switch die WSPCloseSocket-Funktion des SAN-Dienstanbieters aufruft, um den Socket explizit zu schließen. Selbst wenn der SAN-Dienstanbieter alle Ressourcen für den Socket in einem bestimmten Prozess vor dem Empfang eines WSPDuplicateSocket-Aufrufs freigibt, darf der SAN-Dienstanbieter den Deskriptor für den Socket erst wiederverwenden, wenn der Switch WSPCloseSocket für diesen Deskriptor aufruft.
Ein unerwarteter Prozessausgang oder eine andere Fehlerbedingung kann den Socketduplizierungsvorgang eines SAN-Dienstanbieters unterbrechen. Beispielsweise kann ein Ressourcenmangel zu einer solchen Unterbrechung führen. Der Switch behandelt solche Fehlerbedingungen wie jede andere Fehlersituation. Bei Bedarf schließt der Switch alle Deskriptoren, die dem zugrunde liegenden Socket in allen Prozessen zugeordnet sind, um die Verbindung des Sockets gewaltsam zu beenden. Wenn möglich, sollte der SAN-Dienstanbieter auf dem Remotepeer WSPRecv-Aufrufe abschließen, die eingehende Daten mit einem entsprechenden Fehlercode empfangen, z. B. WSAECONNRESET. Dieser Fehlercode informiert den Remotepeer über die Verbindungsbeendigung. Wenn der Switch auf dem Remotepeer diese Verbindungsabschlussanzeige nicht empfängt, wird für den Switch auf dem Remotepeer ein Timeout für eine angehaltene Verbindung ausgegeben, wenn das System, das die Aussetzung angefordert hat, fehlschlägt.