Notice: This website is an unofficial Microsoft Knowledge Base (hereinafter KB) archive and is intended to provide a reliable access to deleted content from Microsoft KB. All KB articles are owned by Microsoft Corporation. Read full disclaimer for more details.

WinHttp: WinHttpReadData can behave synchronously even for asynchronous requests leading to recursion.


Summary

Consider the following scenario. You are developing an application using the WinHttp API and following the recommended procedure as explained in the section: "Asynchronous Completion in WinHTTP" on MSDN: http://msdn.microsoft.com/en-us/library/aa383138.aspx.

When the WinHttp API is operating asynchronously, the functions WinHttpQueryDataAvailable and WinHttpReadData can complete either synchronously or asynchronously each time they are called.

If the function behaves synchronously and you use a debugger to observe the callstack, you will notice a recursive behavior, where each call to WinHttpReadData will recurse itself.

This behavior is by design.



↑ Back to the top


More Information

The recursion of the WinHttpReadData function is bounded, which means that although the WinHttpReadData is acting synchronously and it tends to recurse, it will only recurse for a specified maximum number of times after which it will continue the completions on another thread. This other thread can also have recursion up to the amount specified.

The number of times WinHttpReadData will recurse depends on the operating system you are running your WinHttp application on. The information is as follows:

Operating SystemMaximum number of recursions
Windows XP SP2 and above

Windows 2003 and the service packs

Windows Vista, 2008 and the service packs
64
Windows 7, Windows 2008 R22

WinHttpReadData can behave synchronously if there is enough data buffered at the local socket, where no further wait is needed and the data is available immediately.

This recursive behavior is usually seen for a large file transfer over the localhost server or a high speed network connection.

Using WinHttp API logging, you will see the below behavior which explains the recursion:

HH:MM:SS:ZZZ ::*000000n* :: WinHttpQueryDataAvailable(0xdb0000, 0x0, 0x124fa7c)
HH:MM:SS:ZZZ ::*000000n* :: WinHttpReadData(0xdb0000, 0xc75e20, 455, 0x0)
HH:MM:SS:ZZZ ::*000000n* :: WinHttpQueryDataAvailable(0xdb0000, 0x0, 0x124eac8)
………
………
HH:MM:SS:ZZZ ::*000000n* :: WinHttpReadData(0xdb0000, 0xc76018, 8192, 0x0)
HH:MM:SS:ZZZ ::*000000n* :: WinHttpQueryDataAvailable(0xdb0000, 0x0, 0x124db14)
HH:MM:SS:ZZZ ::*000000n* :: WinHttpQueryDataAvailable() returning TRUE
HH:MM:SS:ZZZ ::*000000n* :: WinHttpReadData() returning TRUE
HH:MM:SS:ZZZ ::*000000n* :: WinHttpQueryDataAvailable() returning TRUE
HH:MM:SS:ZZZ ::*000000n* :: WinHttpReadData() returning TRUE
HH:MM:SS:ZZZ ::*000000n* :: WinHttpQueryDataAvailable() returning TRUE

If you control the stack size of each thread and set the maximum thread stack size to a very low value, you will experience a stack overflow due to the 64 levels of recursive behavior on operating systems earlier than Windows 7 and Windows 2008 R2. Therefore care should be taken when designing applications and prevent allocating too little of the default thread stack size available for each application thread.

Please reference: http://msdn.microsoft.com/en-us/library/ms686774.aspx for more information on thread stack size and how to control it.




↑ Back to the top


Keywords: kb

↑ Back to the top

Article Info
Article ID : 2427068
Revision : 1
Created on : 1/7/2017
Published on : 10/4/2010
Exists online : False
Views : 379