WSPRdmaWrite function
WSPRdmaWrite transfers data from a source buffer in an address space that is accessible only by a local socket to a target buffer in an address space that is accessible by the socket's remote peer.
Syntax
int WSPRdmaWrite(
_In_ SOCKET s,
_In_ LPWSABUFEX lpBuffers,
_In_ DWORD dwBufferCount,
_In_ LPVOID lpTargetBufferDescriptor,
_In_ DWORD dwTargetDescriptorLength,
_In_ DWORD dwTargetBufferOffset,
_Out_ LPDWORD lpdwNumberOfBytesWritten,
_In_ DWORD dwFlags,
_In_opt_ LPWSAOVERLAPPED lpOverlapped,
_In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
_In_ LPWSATHREADID lpThreadId,
_Out_ LPINT lpErrno
);
Parameters
s [in]
Descriptor that identifies a connected socket.lpBuffers [in]
Pointer to an array of WSABUFEX structures. Each WSABUFEX structure contains members that describe a previously registered buffer in the source buffer array. Each buffer was registered in a call to the WSPRegisterMemory function.dwBufferCount [in]
Number of WSABUFEX structures at lpBuffers.lpTargetBufferDescriptor [in]
Pointer to a memory block that contains a descriptor. This descriptor identifies the target RDMA buffer in the address space that is accessible by the socket's remote peer. This descriptor was returned from a previous call to the WSPRegisterRdmaMemory function.dwTargetDescriptorLength [in]
Size, in bytes, of the memory block at lpTargetBufferDescriptor.dwTargetBufferOffset [in]
Offset, in bytes, in the target RDMA buffer at which to begin the data transfer. The descriptor at lpTargetBufferDescriptor identifies this target RDMA buffer.lpdwNumberOfBytesWritten [out]
Pointer to a variable that receives the number of bytes that WSPRdmaWrite transfers from source to target buffers.dwFlags [in]
Set of flags that specify how the call is made.lpOverlapped [in, optional]
Pointer to a WSAOVERLAPPED structure that provides a communication medium between the initiation of an overlapped I/O operation and its subsequent completion. Ignored for nonoverlapped sockets.lpCompletionRoutine [in, optional]
Pointer to the completion routine that the SAN service provider can initiate after the data transfer operation completes. Ignored for nonoverlapped sockets. The switch specifies NULL for a completion routine. To see the prototype for a completion routine, see WSPIoctl.lpThreadId [in]
Pointer to a WSATHREADID structure that the SAN service provider can use in a subsequent call to the WPUQueueApc function to arrange for the execution of the completion routine at lpCompletionRoutine. A WSATHREADID structure identifies a thread. Because the switch specifies NULL for a completion routine, the SAN service provider does not use lpThreadId. For more information about WPUQueueApc, see the Microsoft Windows SDK documentation.lpErrno [out]
Pointer to a variable that receives the error code.
Return value
Returns zero, if successful and the data transfer operation completed immediately; otherwise, returns SOCKET_ERROR and, at lpErrno, one of the following error codes:
Return code | Description |
---|---|
WSAENETDOWN | Network subsystem failed. |
WSANOBUFS | No memory resources available. |
WSAEFAULT | Either the source buffer at lpBuffers or the target buffer identified by the descriptor at lpTargetBufferDescriptor is not contained completely within a valid part of the user address space. |
WSAEINVAL | Invalid flags specified. |
WSAENOTCONN | Socket not connected. |
WSAENOTSOCK | Descriptor at S is not a socket. |
WSAECONNABORTED | Connection to the remote peer was terminated, because of a time-out or other failure. |
WSAECONNRESET | Remote peer terminated the connection. |
WSA_IO_PENDING | SAN service provider successfully initiated an overlapped data-transfer operation and will indicate completion at a later time. |
WSA_OPERATION_ABORTED | Overlapped operation was canceled, because the socket was closed. |
Remarks
The Windows Sockets switch calls the WSPRdmaWrite function to transfer data from the source buffer at lpBuffers on the local computer to the target buffer that is identified by the descriptor at lpTargetBufferDescriptor. This target buffer is in the address space for the remote peer connection. The switch at the remote peer connection calls the WSPRegisterRdmaMemory function to register the target buffer for write access. The switch at the remote peer connection then calls the WSPSend function to send to the local switch a control message that indicates the location of this target buffer. The local switch can then call the WSPRdmaWrite function to transfer data to the target buffer.
A SAN service provider receives WSPRdmaWrite requests only from the switch, but never directly from an application. The switch calls the SAN service provider's WSPRdmaWrite function only in an overlapped manner. In this call, the switch always specifies an overlapped structure and NULL for a completion routine. In the call to the WSPRdmaWrite function, the switch posts source and target buffers for the data transfer operation. If the data transfer operation cannot complete immediately, the operation proceeds, but WSPRdmaWrite returns with the WSA_IO_PENDING error code. The switch later calls the SAN service provider's WSPGetOverlappedResult function and passes a pointer to the overlapped structure to retrieve the final completion status.
The array of WSABUFEX structures at lpBuffers is transient. If the data transfer operation completes in an overlapped manner, the SAN service provider must capture these WSABUFEX structures before it returns from WSPRdmaWrite with the WSA_IO_PENDING error code. This requirement enables applications to build stack-based WSABUFEX arrays.
Overlapped Socket I/O
If the data transfer operation completes immediately, the SAN service provider returns from the WSPRdmaWrite function with a value of zero and, at lpdwNumberOfBytesWritten, specifies the number of bytes transferred from source to target buffers. If the SAN service provider successfully initiated the data transfer operation and will indicate completion at a later time, the SAN service provider returns from the WSPRdmaWrite function with a value of SOCKET_ERROR and specifies the WSA_IO_PENDING error code at lpErrno. Note that, in this case, the SAN service provider does not specify a value at lpdwNumberOfBytesWritten. After the data transfer operation completes, the switch calls the SAN service provider's WSPGetOverlappedResult function and passes a pointer to a variable that holds data transfer information. In this variable, the SAN service provider specifies the number of bytes transferred from source to target buffers.
The overlapped structure at lpOverlapped must be valid for the duration of the data transfer operation. If multiple data transfer operations are outstanding simultaneously, each must reference a separate overlapped structure.
As mentioned previously, the switch always specifies an overlapped structure and NULL for a completion routine whenever the switch calls the SAN service provider's WSPRdmaWrite function in an overlapped manner. Because the switch specifies NULL for a completion routine, the SAN service provider must call the WPUCompleteOverlappedRequest function in the context of an arbitrary thread to complete the request. If the low order bit of the hEvent member in the WSAOVERLAPPED structure is set, the switch specifically requests to not be notified upon completion of the I/O request. Therefore, the SAN service provider is not required to call the WPUCompleteOverlappedRequest function to complete the I/O request. In this case, the switch calls the WSPGetOverlappedResult function to poll for completion. For more information, see the GetQueuedCompletionStatus function in the Windows SDK documentation.
For more information about WPUCompleteOverlappedRequest, see the Windows SDK documentation.
Completion indications can be delivered in any order and not necessarily in the same order that the overlapped operations are completed.
Requirements
Target platform |
Desktop |
Version |
Requires Windows Sockets version 2.2. |
Header |
Ws2san.h (include Ws2san.h) |
See also