Asynchronous I/O APIs provide a method for threaded client server models to perform highly concurrent and memory efficient I/O.
In previous threaded client/server models, typically two I/O models have prevailed. The first model dedicated one thread per client connection. The first model consumes too many threads and can incur a substantial sleep and wake up cost. The second model minimizes the number of threads by issuing the select() API on a large set of client connections and delegating a readied client connection or request to a thread. In the second model, you must select or mark on each subsequent select, which can cause a substantial amount of redundant work.
Asynchronous I/O and overlapped I/O resolve both these dilemmas by passing data to and from user buffers after control has been returned to the user application. Asynchronous I/O notifies these worker threads when data is available to be read or when a connection has become ready to transmit data.
Function | Description |
---|---|
gsk_secure_soc_startInit() | Starts an asynchronous negotiation of a secure session,
using the attributes set for the SSL environment and the secure session. Note: This
API only supports sockets with address family AF_INET or AF_INET6 and type
SOCK_STREAM.
|
gsk_secure_soc_startRecv() | Starts an asynchronous receive operation on a secure
session. Note: This API only supports sockets with address family AF_INET
or AF_INET6 and type SOCK_STREAM.
|
gsk_secure_soc_startSend() | Starts an asynchronous send operation on a secure
session. Note: This API only supports sockets with address family AF_INET
or AF_INET6 and type SOCK_STREAM.
|
QsoCreateIOCompletionPort() | Creates a common wait point for completed asynchronous overlapped I/O operations. The QsoCreateIOCompletionPort() function returns a port handle that represents the wait point. This handle is specified on the QsoStartRecv(), QsoStartSend(), QsoStartAccept(), gsk_secure_soc_startRecv(), or gsk_secure_soc_startSend() functions to initiate asynchronous overlapped I/O operations. Also this handle can be used with QsoPostIOCompletion() to post an event on the associated I/O completion port. |
QsoDestroyIOCompletionPort() | Destroys an I/O completion port. |
QsoWaitForIOCompletionPort() | Waits for completed overlapped I/O operation. The I/O completion port represents this wait point. |
QsoStartAccept() | Starts an asynchronous accept operation. Note: This
API only supports sockets with address family AF_INET or AF_INET6 and type
SOCK_STREAM.
|
QsoStartRecv() | Starts an asynchronous receive operation.
Note: This API only supports sockets with address family AF_INET or AF_INET6
and type SOCK_STREAM.
|
QsoStartSend() | Starts an asynchronous send operation. Note: This
API only supports sockets with the AF_INET or AF_INET6 address families with
the SOCK_STREAM socket type.
|
QsoPostIOCompletion() | Allows an application to notify a completion port that some function or activity has occurred. |
An application creates an I/O completion port using the QsoCreateIOCompletionPort() API. This API returns a handle that can be used to schedule and wait for completion of asynchronous I/O requests. The application starts an input or an output function, specifying an I/O completion port handle. When the I/O is completed, status information and an application-defined handle is posted to the specified I/O completion port. The post to the I/O completion port wakes up exactly one of possibly many threads that are waiting. The application receives the following items:
This application handle can be the socket descriptor identifying the client connection, or a pointer to storage that contains extensive information about the state of the client connection. Since the operation was completed and the application handle was passed, the worker thread determines the next step to complete the client connection. Worker threads that process these completed asynchronous operations can handle many different client requests and are not tied to just one. Because copying to and from user buffers occurs asynchronously to the server processes, the wait time for client request diminishes. This can be beneficial on systems where there are multiple processors.
An application that uses asynchronous I/O has the structure demonstrated by the following code fragment.
#include <qsoasync.h> struct Qso_OverlappedIO_t { Qso_DescriptorHandle_t descriptorHandle; void *buffer; size_t bufferLength; int postFlag : 1; int fillBuffer : 1; int postFlagResult : 1; int reserved1 : 29; int returnValue; int errnoValue; int operationCompleted; int secureDataTransferSize; unsigned int bytesAvailable; struct timeval operationWaitTime; int postedDescriptor; char reserved2[40]; }