Closing a non-blocking socket with linger enabled may cause leak

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 has not been shut down, and the closesocket function is called on that socket, closesocket will shut down the socket before closing it. closesocket will attempt a graceful shut down if the linger option is enabled on the socket.


When closesocket() attempts to gracefully shut down a non-blocking socket, it will attempt to create a worker thread to perform the shut down. 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 shut down.

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 will not exit. It has been leaked. The memory associated with the thread and the socket it is 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 closesocket.

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 afd.dll

Please see the following MSDN help article for more background information about linger,

Graceful Shutdown, Linger Options, and Socket Closure

Propiedades

Id. de artículo: 2770054 - Última revisión: 18 oct. 2012 - Revisión: 1

Windows Embedded CE 6.0 R3

Comentarios