We occasionally observe es_mute_process_events() called on an es_client_t while an AUTH event delivered by the same client is still outstanding.
In the problematic state, es_mute_process_events() stops returning inside IOConnectCallStructMethod. Subsequent calls to es_respond_flags_result() and a fallback es_respond_auth_result() on the same es_client_t also block in IOConnectCallStructMethod, eventually causing the AUTH deadline to be missed.
If you're able to reproduce this issue, please file a bug that includes both spindump of the point your client hung and a sysdiagnose collected after the problem, then post the bug number back here.
I've shared my thoughts on your questions below, but my intuition is that the actual failure here is different than you're describing.
Is it supported to call es_mute_process_events() before responding to an outstanding AUTH event delivered by the same es_client_t?
Yes, but that’s because your client couldn't actually prevent this if it wanted to. Event delivery is asynchronous and outside of your client’s control, so there isn't any reliable way for you to "know" whether or not a given process has outstanding auth events.
Are mute operations and es_respond_*() calls serialized internally for a single es_client_t?
There's a lock inside the user clients that serializes most es user client calls; however, the actual work of the kernel client is highly optimized and should not block for any significant period of time.
Can es_mute_process_events() wait for in-flight/outstanding AUTH processing?
Can an in-progress mute operation prevent a concurrent es_respond_*() call from completing?
I wouldn't expect these operations to ever interfere with each other. Things like process muting and the result caching happen "before" we generate the auth events your client receives, so muting a process stops future events from reaching your client without having any impact on current auth events.
Is the recommended pattern to respond to the AUTH message first and update mute state asynchronously afterward?
As I noted above, you can't actually "do" this. Your client doesn't know what events have been queued up for it, so even if you've responded to the "current" auth event, you don't have any way to guarantee another one isn't right behind it. Similarly, as far as the kernel is concerned, there's no difference between a message your app is actively examining and a message that’s queued up waiting for delivery.
Having said that...
Is the recommended pattern to respond to the AUTH message first and update mute state asynchronously afterward?
...yes, I'd consider this the recommended pattern, just not for the reason(s) you’re thinking of. Your client’s primary goal is to respond to auth messages as quickly as possible, so:
-
You'd typically respond before muting since, by definition, muting first would be "delaying" the response.
-
Whatever thread you're responding from is likely responsible for processing "future" messages, so muting on that thread is also imposing some small level of delay on the "next" event that thread will next be processing.
However, on the third hand, the actual time required for either of these calls (mute or respond) is sufficiently small that, on their own, I don't think calling them from the same thread would have any real-world impact. In any situation where it appeared to be having a real-world impact, I suspect it would almost always be a secondary contributing factor, NOT the primary cause of any issue.
Ultimately, the real justification for moving mute off of your response thread is simply that your auth thread should not be doing ANY unnecessary work, and the mute simply doesn't HAVE to be on the auth thread.
__
Kevin Elliott
DTS Engineer, CoreOS/Hardware