Closing a non-blocking socket with linger enabled may cause leak
This article helps you resolve the leak problem when closing a non-blocking socket with linger enabled and the linger timeout set to 0.
Original product version: Winsock
Original KB number: 2770054
Symptoms
Memory usage and thread handle count increases at the same rate that your program closes sockets. It appears to be a memory and thread handle leak.
Cause
Sockets may be shut down in either a graceful or abortive manner. If a socket hasn't been shut down, and the closesocket
function is called on that socket, the closesocket
function will shut down the socket before closing it. The closesocket
function will attempt a graceful shutdown if the linger option is enabled on the socket.
When the closesocket
function attempts to gracefully shut down a non-blocking socket, it will attempt to create a worker thread to perform the shutdown. The worker thread will attempt to notify the other end of the communication channel that the socket is shutting down. If the other end of the channel is unresponsive, the worker thread will wait for the linger timeout to expire; then do an abortive shutdown.
If the linger timeout in the above scenario equals 0, then the worker thread will wait an infinite amount of time for the other end of the channel to respond. This thread is unable to perform any useful work, and won't exit. It has been leaked. The memory associated with the thread and the socket it's trying to shut down has also been leaked.
Resolution
Best practice is to explicitly shut down the socket using the shutdown
or WSASendDisconnect
functions, then call the closesocket
function.
Alternatively, you may set the linger timeout value to a value other than 0 - for example 1 second. The worker thread will only wait for the specified linger timeout value before shutting down the socket and exiting.
More information
The closesocket
function and the worker thread function are implemented in the afd.dll
.
For more background information about linger, see Graceful Shutdown, Linger Options, and Socket Closure.