Asyncronous WinHTTP API & APC mix - winhttp

I perform asyncronous WinHttp API calls ( WINHTTP_FLAG_ASYNC flag is set in WinHttpOpen(...) ) inside APC callback.
I'm afraid WinHttp reentrance, mentioned in https://learn.microsoft.com/en-us/windows/win32/winhttp/winhttp-security-considerations :
"WinHTTP is not reentrant in synchronous mode. Because WinHTTP is not reentrant in synchronous mode, do not schedule asynchronous procedure calls (APC) that can call into WinHTTP on an application thread that executes inside a WinHTTP function. While in synchronous mode, WinHTTP performs an "alertable wait," and if the waiting thread is pre-empted to execute an APC and then later re-enters WinHTTP again, WinHTTP's internal state can be corrupted."
Can i be sure that asyncronous WinHttp API never perform alertable wait state internally?

Related

Can a C++20 co-routine implement a synchronous interface without blocking?

I am writing a GRPC service and am trying to use the asynchronous methods with the help from Asio. The service calls into a C++ library that have synchronous methods. The code in that library uses interfaces that must be implemented by the user of the library. These interfaces contains synchronous methods.
I wish to implement these interfaces by using asynchronous GRPC calls to other services. My challenge is that I cannot see how I can implement an adaptor between the synchronous - and asynchronous world. Is this at all possible in C++?
In (my) theory I want this co-routine adaptor to send the GRCP request and then the thread should continue executing other co-routines - and not be blocking - while waiting for the GRPC reply. When the reply is received the synchronous method call is returned to the library. This way I would be able to implement my GRPC service with only one thread and I do not have to worry about multi-threading issues.
When using co_await in a method then the return value is reflecting the async nature of the method, so I cannot use co_await (directly) when implementing a synchronous interface. Instead I can post a lambda containing the co_wait, but then I have to do a blocking wait on a future (or similar) and my single threaded service is deadlocked. I have been thinking of using co_yield and make a type of generator since it seems to be that the consumer of these generators can be synchronous.
Best regards

Asynchronous controller AND Ajax request

I have an asynchronous controller,
I know the action will work asynchronously (no other action wait for that) and returns after completion of the task.
So my question is how it is deferent from making an asynchronous Ajax request to an action.
I think both are same in result.
An async request from javascript is not the same as an async task on the server.
An async task from javascript is still processed synchronously on the server, and as such, you may encounter thread pool starvation on large applications.
Having an async request that is processed asynchronously on the server is different, it frees up the IIS thread to immediately process other requests while that request, either from javascript or a full post/get is processed in the background.
some reading may help
http://msdn.microsoft.com/en-us/library/ee728598(v=vs.98).aspx#processing_asynchronous_requests

Is it possible to dictate use of RPC callback threads?

I am working on a bug that related to an unmanaged MTA COM object. The object has Lock and Unlock methods and uses a mutex that requires the same thread that called Lock to call Unlock.
The problem is that when Lock and Unlock are called from a managed STA thread (using COM interop), the calls come into the COM object on a RPC callback thread but the callback thread that is used is not always the same for both calls. When it is not the same, the Unlock call fails because it can't unlock the mutex.
In other words:
Managed STA thread 1 -> RPC callback (thread 11) -> Lock
Managed STA thread 1 -> RPC callback (thread 12) -> Unlock -> Error
I am trying to evaluate all possible solutions before making any decisions on a fix. As such, I am trying to find out:
1) Is there is a way to prevent a RPC callback thread from being used in the first place? In my testing, if I make the calls to the object from an unmanaged STA thread, the calls seem to come in on the calling thread itself. What is different when the call is coming from .Net that necessitates the use of an RPC callback thread? Is there any way to prevent RPC callbacks from being used? (except for using an MTA calling thread)
2) If not, is there a way to force a consistent RPC callback thread to be used from the same managed STA thread?
This is by design for a free-threaded server. COM takes your word for it and allows stubs to use arbitrary RPC threads. You cannot make any assumptions about the thread identity, the RPC thread is picked from a pool and is recycled. Unfortunately it often picks the same one when the calls are sequenced so it will look like it works fine at first. But trouble starts as soon as more than one concurrent server call is made. There is no option to make it selective, a free-threaded server promises to not care. Nor could that work well in practice, it would either scale horribly or induce deadlock.
You therefore cannot use a mutex to implement locking, it has thread affinity. A semaphore is a good choice.

What thread pool wcf uses when usesynchronizationcontext=false

I have a wcf client I generated using SVCUTIL with the /async flag.
The server is syncronic, but I only use the Begin/End methods in my client.
Also, I added the attribute UseSynchronizationContext=false in the CallbackBehavior.
My question is: How does WCF work with threads in this mode?
Or better phrased - Is WCF using the ThreadPool class to acquire new threads for the callback when I call simultanous functions? Or does it have some custom implementation?
I Googled the subject for hours, didn't find anything near an answer.
EDIT: I see I've been a little unclear here - I'm not asking about the server app, I'm asking about the client app - how does it manage the threads on which it returns the callbacks when I set the usesynchronizationcontext flag to false?
Your service's threading is unaffected by how the client calls it. When you use proxy Begin/End methods, the proxy is using a different client thread to make the service call so that your application code does not block.
With .NET 4.5 task based asynchronous calls are now preferred.
See Synchronous and Asynchronous Operations for an overview of the different patterns.

WCF client deadlocking due to callback even when callback IsOneWay

new to WCF.
I have a client which is deadlocking when calling a WCF service.
The service will invoke a callback to the client at the time of the call which is marked as IsOneWay. I have confirmed that the service is not blocking on the callback.
The client then immediately calls the same service again (in a tight loop), without having yet serviced the callback. The client then deadlocks (and a breakpoint on the service side never gets triggered).
So to recap:
CLIENT SERVICE
Call service -----------------------> (service breakpoint triggers)
(waiting for dispatch thread) <------ Invoke callback (IsOneWay - doesn't block)
Service returns
Call service again immediately -----? (service breakpoint doesn't trigger)
(deadlock)
I am assuming that the callback has grabbed some WCF lock at the client end, and then the second service call from the client also wants that lock, so deadlock results. But this is just assumption.
I have read about ConcurrencyMode but I can't decide which mode to use, or where to put it because I'm not 100% clear on what is going on, and what is being blocked exactly.
I would also prefer to keep all callbacks being serviced by the dispatch thread if possible as it keeps the code simpler.
Can any WCF experts shed light on exactly what is going on here?
Many thanks
OK, think I've sussed it.
WCF services default to single threaded. All calls and callbacks get marshalled to a single thread (or SynchronizationContext to be more accurate).
My app is a single threaded WPF app, so the SynchronizationContext gets set to the dispatch thread.
When the callback comes in it tries to marshal the call to the dispatch thread, which of course is sat blocking on the original service call. I'm not clear it locks exactly, but there's obviously some global lock that it tries to get before waiting for the dispatch thread.
When the dispatch thread then calls the service again, it deadlocks on this global lock.
Two ways around it:
1) Create the service proxy on a different thread in the first place. All calls will get marshalled through this thread instead and it won't matter that the dispatch thread is blocked.
2) Apply [CallbackBehavior(UseSynchronizationContext = false)] attribute to the client class that implements the callback. This means WCF will ignore the synchronisation context when the callback comes in, and it will service it on any available thread.
I went with 2. Obviously this means I need to marshal callbacks that could update the GUI to the dispatch thread myself, but luckily my callback implementation is a small wrapper anyway, so I just do a _dispatcher.BeginInvoke() in each callback method to marshal ASYNCHRONOUSLY. The dispatch thread will then service when it gets a chance which is what I wanted in the first place.
The sequence that you have depicted resembles a synchronous call. While in an async call, the sequence would be:
Client Server
Call service --------------->ProcessRequest(1) //Your for loop for instance.
Call service --------------->ProcessRequest(2)
Call service --------------->ProcessRequest(3)
Call service --------------->ProcessRequest(4)
Call service --------------->ProcessRequest(5)
Callback awake <---------------Response1 //Responses tends to pour in...
Callback awake <---------------Response2
Callback awake <---------------Response3
Callback awake <---------------Response4...
In each case of each async web service call, the system creates a separate IO thread(IOCP thread), and processes the request. In this, seldom you will find a deadlock.
I have found this way, even when called within a loop, to be working very well.
You can, for instance, register for the event .OnProcessComplete, and then call the ProcessCompleteAsync method.