On Wed Feb 5 20:23:32 2025 +0000, Elizabeth Figura wrote:
When ntsync is used, no waits go to server_select [except a handful of cherry-picked internal waits that go through server_wait_for_object()]. Hence the state of the mutex object in the server [as opposed to the kernel] is never changed after creation. Rather, the internal state of the kernel object is mutable, and when NtReleaseMutant() is called that does NTSYNC_IOC_MUTEX_UNLOCK on the underlying ntsync object which changes its state instead. Similarly for waits. Same for events and semaphores. Other objects (timers, processes, etc.) still change state like normal, and the server alters their state using ioctls when anything happens that would change the object's signaled state.
Okay, this is not obvious from the code, maybe it could be made more obvious that the inproc_sync and the server-side state are mutually exclusive. Maybe a union of the server state members with the inproc pointer?
Also, creating the inproc_sync on object creation instead of using lazy init would make it more obvious that in this particular case the owner that is passed to the kernel is always the initial mutex owner.
Btw I see that this is true for every other object type, where the lazy init makes it non-obvious that the values passed to every inproc sync creation are the initial state values.