Duplicare gli handle socket per una SAN
Più applicazioni eseguite in processi diversi possono usare il commutatore Windows Sockets per eseguire operazioni su un socket sottostante condiviso. Tuttavia, solo un'applicazione alla volta può eseguire operazioni su quel socket sottostante condiviso.
Per usare un socket sottostante condiviso, un'applicazione deve recuperare un handle duplicato nel socket sottostante in uno dei modi seguenti:
Direttamente, chiamando la funzione WSADuplicateSocket di Windows Sockets
La chiamata viene effettuata nel contesto del processo di controllo (processo in cui è stato creato il socket).
Indirettamente, chiamando la funzione DuplicateHandle Win32
La chiamata viene effettuata nel contesto di un processo non controllante (diverso dal processo in cui è stato creato il socket).
Uso del meccanismo di ereditarietà dell'handle
Un processo figlio (processo non controllante) eredita tutti o alcuni degli handle creati nel processo padre (processo di controllo).
Durante la chiusura della connessione grazia
Se un'applicazione nel processo di controllo chiude un socket e termina mentre alcuni dati rimangono ancora da inviare, questi dati rimanenti vengono memorizzati nel buffer nella DLL di Windows Sockets. Un'altra applicazione nel contesto del processo del servizio di sistema (processo non controllante) invia successivamente questi dati.
L'opzione Windows Sockets, insieme al provider TCP/IP, rileva e gestisce ognuna delle condizioni precedenti. L'opzione consente solo un processo alla volta di eseguire operazioni che trasferiscino dati o cambiano lo stato per un socket condiviso sottostante. Elabora in modo dinamico il controllo di scambio del socket sottostante, in base alle esigenze, per eseguire operazioni richieste. L'opzione serializza le operazioni che diversi processi richiedono di eseguire su un socket condiviso ed esegue queste operazioni nell'ordine FIFO (first-in-first-out). L'opzione attende il completamento di tutte le operazioni in corso prima di scambiare il controllo di un socket sottostante a un altro processo. Logicamente, il commutatore controlla il socket sottostante lontano dal processo di controllo non appena un processo non controllante richiede un'operazione idonea. Dopo che il controllo viene eliminato, l'opzione considera il processo di controllo originale come un processo non controllante se il processo di controllo originale richiede operazioni idonee. Si noti che l'opzione non esegue alcuna azione su un handle socket duplicato fino a quando il processo di non controllo usa effettivamente l'handle socket duplicato per un trasferimento dati o un'operazione di modifica dello stato.
Sia il commutatore che il provider di servizi SAN appropriato vengono caricati in tutti i processi che condividono l'accesso a un determinato socket sottostante. L'opzione gestisce il proprio contesto socket e le informazioni sullo stato di connessione in tutti i processi che condividono il socket. Il provider di servizi SAN è necessario per mantenere il contesto del socket e le informazioni sullo stato della connessione solo nel processo che ha il controllo del socket sottostante in qualsiasi momento. Il provider di servizi SAN deve scambiare il controllo delle informazioni sullo stato del contesto e della connessione dal processo di controllo corrente al processo di controllo successivo ogni volta che l'opzione richiede lo scambio come descritto nella sequenza seguente. Per ridurre al minimo la quantità di risorse necessarie per lo scambio, un provider di servizi SAN può mantenere le informazioni sullo stato di connessione e contesto in tutti i processi che condividono un socket sottostante.
Poiché l'opzione non crea il socket SAN che corrisponde a un socket applicazione fino a quando un'applicazione chiama la funzione di connessione o ascolto , l'opzione non può richiedere che il provider di servizi SAN esegua un'operazione di scambio prima che il socket dell'applicazione sia connesso o in ascolto. Anche dopo che il socket dell'applicazione è connesso o in ascolto, una delle condizioni seguenti deve essere soddisfatta prima delle richieste di cambio che il controllo di scambio del provider di servizi SAN del socket:
Un processo che non controlla il socket avvia un trasferimento dati. Il provider di servizi SAN non scambia il controllo del socket fino al completamento di tutte le operazioni di trasferimento dei dati avviate dal processo di controllo.
Un processo che non controlla il socket chiama la funzione WSAAccept, WSPAccept o AcceptEx per avviare un'operazione di accettazione della connessione in un socket di ascolto. Il provider di servizi SAN non scambia il controllo del socket fino a quando non sono state completate tutte le richieste avviate dal processo di controllo.
L'opzione esegue i passaggi seguenti per scambiare il controllo di un socket SAN connesso dal processo di controllo al processo di controllo successivo (Per una panoramica del processo di scambio, vedere la tabella nella sezione Osservazioni della documentazione per la funzione WSPDuplicateSocket ).
Il commutatore sospende l'elaborazione delle nuove richieste dall'applicazione nel processo di controllo. Quando sono state completate tutte le operazioni RDMA e di invio sul socket SAN, il commutatore chiama la funzione WSPSend del provider di servizi SAN per inviare un messaggio a un peer connesso per richiedere una sospensione della sessione e chiama la funzione WSPDeregisterMemory del provider di servizi SAN per rilasciare tutti i buffer locali usati per le operazioni di invio. Di conseguenza, l'opzione alla connessione peer sospende l'elaborazione delle nuove richieste dell'applicazione, attende che tutte le operazioni di invio e RDMA in corso sul socket SAN venga completata e rilascia tutta la memoria RDMA. La connessione peer invia un messaggio di risposta che indica che la sessione viene sospesa. Quando si riceve questo messaggio di conferma, l'opzione all'endpoint locale chiama la funzione WSPDeregisterRdmaMemory del provider di servizi SAN per rilasciare tutta la memoria RDMA. A questo punto, i socket SAN in entrambi gli endpoint della connessione possono avere solo richieste in sospeso. Queste richieste di ricezione rimangono in sospeso sul socket SAN del peer remoto per consentire la riattivazione della sessione. Le richieste di ricezione sul socket SAN locale nel processo di controllo vengono completate nel passaggio successivo. Mentre la connessione viene sospesa, l'opzione in corrispondenza della coda di connessione peer remota esegue nuove richieste di blocco o sovrapposte, i nuovi buffer non bloccanti inviano fino all'impostazione SO_SNDBUF, non bloccano nuovi invii dopo il raggiungimento del limite di buffer e non riescono a ricevere tutti i nuovi messaggi non bloccanti con WSAEWOULDBLOCK. Il commutatore locale nel processo di controllo gestisce le nuove richieste nel socket dell'applicazione come se il processo non disponesse del controllo del socket.
Dopo la sospensione della sessione, il commutatore chiama la funzione WSPDuplicateSocket del provider di servizi SAN nel processo di controllo per indirizzare il provider di servizi SAN per trasferire il contesto del socket nello spazio degli indirizzi del processo di controllo successivo. L'opzione specifica il processo di controllo successivo nel parametro dwProcessId di WSPDuplicateSocket. La funzione WSPDuplicateSocket deve chiamare la funzione WPUCompleteOverlappedRequest per completare tutte le richieste di ricezione in sospeso nel socket con stato di esito positivo e zero byte. Il provider di servizi SAN deve anche rilasciare automaticamente tutti i buffer associati a queste richieste. Il provider di servizi SAN rilascia tutti i buffer poiché l'opzione non richiede più operazioni sul socket SAN dopo che WSPDuplicateSocket restituisce. L'unica eccezione possibile è una chiamata di funzione WSPCloseSocket , come descritto nel passaggio successivo. Dopo aver restituito WSPDuplicateSocket , l'opzione salva il valore nel membro dwProviderReserved della struttura WSAPROTOCOL_INFOW a cui punta il parametro di output lpProtocolInfo . L'opzione usa questo valore per identificare il socket sottostante nel contesto del processo di controllo successivo. Pertanto, il valore in dwProviderReserved deve identificare in modo univoco il socket sottostante e la connessione per tale socket in tutti i processi nel sistema. Inoltre, questo valore deve essere valido solo nel contesto del processo specificato nel parametro dwProcessId di WSPDuplicateSocket.
Dopo aver trasferito il contesto del socket nello spazio indirizzi del processo di controllo successivo, l'opzione chiama la funzione WSPSocket del provider di servizi SAN nel contesto del processo di controllo successivo. In questa chiamata, l'opzione passa il valore per il socket sottostante restituito nella chiamata WSPDuplicateSocket al membro dwProviderReserved della struttura WSAPROTOCOL_INFOW a cui punta il parametro di input lpProtocolInfo . Se il processo di controllo successivo non ha richiesto la creazione del socket SAN, il provider di servizi SAN deve creare un nuovo socket e chiamare la funzione WPUCreateSocketHandle per ottenere un handle, come richiesto per qualsiasi nuovo socket. Se il socket SAN è stato creato nel contesto del processo di controllo successivo, il provider di servizi SAN può riattivare il socket precedente e restituire lo stesso descrittore per il socket usato in precedenza. In questo caso, il provider di servizi SAN non deve chiamare WPUCreateSocketHandle, ma deve continuare a usare l'handle socket originale fornito. In alternativa, il provider di servizi SAN può creare un nuovo socket, indipendentemente dal fatto che un socket esista in precedenza nel processo. In questo caso, l'opzione deve chiamare la funzione WSPCloseSocket del provider di servizi SAN nel contesto del processo di controllo successivo per eliminare il descrittore socket precedente.
L'opzione riavvia l'elaborazione delle nuove richieste dall'applicazione nel processo di controllo successivo.
Il commutatore duplica un socket di ascolto in modo analogo, ad eccezione del fatto che l'opzione non è necessaria per sospendere una sessione. L'opzione attende fino al completamento di tutte le chiamate WSPAccept avviate dall'accettazione e dalle chiamate AcceptEx di un'applicazione prima di chiamare la funzione WSPDuplicateSocket del provider di servizi SAN nel processo di controllo.
Poiché il commutatore sospende l'elaborazione delle nuove richieste in un socket SAN prima di chiamare la funzione WSPDuplicateSocket del provider di servizi SAN, il provider di servizi SAN può rilasciare tutte le risorse associate a un endpoint locale nel processo di controllo. Il provider di servizi SAN può anche terminare una connessione sottostante. Se il provider di servizi SAN chiude una connessione sottostante nel processo di controllo, il provider di servizi SAN deve ristabilire la connessione dopo che il commutatore chiama la funzione WSPSocket del provider di servizi SAN all'interno del processo di controllo successivo. Dopo aver restituito la chiamata WSPSocket , il socket SAN all'interno del processo di controllo successivo deve trovarsi nello stesso stato, dal punto di vista del commutatore, poiché il socket SAN nel processo di controllo è stato precedente al commutatore che chiama la funzione WSPDuplicateSocket del provider di servizi SAN.
Se una scheda di interfaccia di rete SAN supporta la condivisione delle risorse tra endpoint eseguiti in processi diversi, il provider di servizi SAN non deve rilasciare risorse per un endpoint locale nel processo di controllo prima di ricevere una chiamata WSPDuplicateSocket . In tal caso, il socket SAN associato a un endpoint locale rimane inattivo nel processo di controllo precedente fino a quando il commutatore scambia il contesto del socket dal processo di controllo successivo o chiama la funzione WSPCloseSocket del provider di servizi SAN per chiudere in modo esplicito il socket. Poiché la maggior parte delle applicazioni esegue l'accesso finale al socket nel processo che originariamente è stato creato per chiudere il provider di servizi SAN può migliorare le prestazioni se il provider di servizi SAN mantiene il contesto del socket nel processo di controllo dopo lo scambio del controllo del socket al processo di controllo successivo.
Si noti che, in tutti i casi, un descrittore del socket SAN deve rimanere valido fino a quando il commutatore chiama la funzione WSPCloseSocket del provider di servizi SAN per chiudere esplicitamente il socket. Anche se il provider di servizi SAN rilascia tutte le risorse per il socket in un determinato processo prima di ricevere una chiamata WSPDuplicateSocket , il provider di servizi SAN non deve riutilizzare il descrittore per il socket fino a quando il commutatore chiama WSPCloseSocket su tale descrittore.
Un processo imprevisto o un'altra condizione di errore può interrompere un'operazione di duplicazione del provider di servizi SAN. Ad esempio, una carenza di risorse può causare un'interruzione di questo tipo. L'opzione considera tali condizioni di errore in quanto esegue qualsiasi altra situazione di errore. Se necessario, l'opzione chiude tutti i descrittori associati al socket sottostante in tutti i processi per terminare forzatamente la connessione del socket. Se possibile, il provider di servizi SAN nel peer remoto deve completare le chiamate WSPRecv che ricevono dati in ingresso con un codice di errore appropriato, ad esempio WSAECONNRESET. Questo codice di errore informa il peer remoto della terminazione della connessione. Se l'opzione al peer remoto non riceve questa indicazione di terminazione della connessione, l'opzione al peer remoto timeout una connessione sospesa se il sistema che ha richiesto la sospensione ha esito negativo.