WinHTTP Questions: About Callbacks

Hello All, I am continuing the "WinHTTP Questions" series with some questions on WinHTTP callbacks.

Is it correct that WinHTTP Callbacks will occur *only* during an in-progress WinHTTP operation? Is it possible that an external event (such as the remote server resetting the underlying tcp connection) result in a callback even when there's no outstanding operation?

No. For external callbacks, WinHTTP will indicate informational callbacks only when there is a pending operation. Essentially, there are two types of callbacks in WinHTTP. Completion callbacks and Informational callbacks.

  • Completion callbacks are invoked as a completion of a pending API call e.g. read complete is invoked when the read API completes. Similarly, handle-closed callback is invoked in response to the close handle API.
  • Informational callbacks, on the other hand, are invoked to inform the application about important events seen during the processing of a call.

So, when an async API is invoked and it returns TRUE, the application will receive zero or more informational callbacks and then a completion callback.

When an operation like WinHttpReadData fails immediately (i.e., this call returned FALSE), does it guarantee that user will not receive a STATUS_REQUEST_ERROR callback?

Yes.

Does WinHTTP synchronize WinhttpSetStatusCallback with worker threads? Here is our usage scenario: We are implementing a DLL that get dynamically loaded implements an asynchronous Download function with progress notifications and supports a Cancel call. After Cancel or Download completion our DLL should be able to be safely unloaded. Cancel calls WinHttpSetStatusCallback to unregister notifications, closes the request, connection and sessions handles. However we occasionally still get status callbacks after the DLL is unloaded.

No, WinHTTP does not synchronize WinHttpSetStatusCallback with worker threads. For e.g.  If a  callback originating in another thread is in progress when an application calls WinHttpSetStatusCallback, the application still receives a callback notification even after WinHttpSetStatusCallback successfully sets the callback function to NULL and returns. The thread will continue to process, so one will need to wait until the current call finishes.

Please also refer to the following links for more on callbacks.

Next time we will go a bit deeper into safe request cancellation.

  -- Deepak & Ari

Comments

  • Anonymous
    May 28, 2008
    Thanks for writing this blog.  It is very helpful. I'm looking forward to your next blog on the safe cancellation of asynchronous requests.  Is there anything we need to do other than closing the request handle as documented in the WinHttpCloseHandle MSDN page (http://msdn.microsoft.com/en-us/library/aa384090(VS.85).aspx)?

  • Anonymous
    February 09, 2009
    I just started playing around with WinHTTP, namely the "WinHttpSetStatusCallback" method, and found something troubling.   When I use the "WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS", I ultimately receive the "WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE" notification, which is good. If I then try to use the "WINHTTP_CALLBACK_FLAG_ALL_NOTIFICATIONS" for the notification-flags, then I no longer receive the "WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE" notification.  In fact, if I apply any of the old "deprecated" notification-flags along with the "WINHTTP_CALLBACK_FLAG_ALL_COMPLETIONS" flag, I still don't get the "WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE" notification.  Why would this be (aside from a possible bug in my code that I'm not detecting)?