Even if the server didn't initially request client context via SIGUSR1, another thread might call NtGetContextThread() in the meanwhile and make `select()` return `STATUS_MORE_PROCESSING_REQUIRED`
I don't think it is a problem with the current patch. select() can't return STATUS_MORE_PROCESSING_REQUIRED from the select called without possibility to get a context, that is why the added flag is needed. Without the patch if a thread is in select called without context it doesn't process NtGetContextThread or suspend. For those SIGUSR1 is always sent (stop_thread() is used on the server). SIGUSR1 will issue new select "on top" of the one, then return to the interrupted one once complete. If we are already in select from sigusr1 with the patch, it may happen that it processes some system APCs first and then gets STATUS_MORE_PROCESSING_REQUIRED, that is fine. And implicitly tested, e. g., in kernel32/tests:sync.c test_apc_deadlock().
We can use `sigqueue(3)` if available to send a hint whether to send the context the first time.
Could you please elaborate how do you see it can be used? First as far as I can see it sends the signal to a process, we need specific thread. Then, what is the difference for our case to current way of sending signal?
Meanwhile, if it would be possible to send a distinct signal for contexts that would solve the major concern (worsening the performance for some paths, even if not most frequent), and also probably would simplify the thing. Technically SIGUSR2 looks like a good candidate, but maybe there are considerations against that which I am not aware about, like maybe it is known to be handled by libraries we depend upon.
@jacek @julliard do you think introducing SIGUSR2 as "stop_thread" handle is a go?