On 2/4/22 14:50, Jinoh Kang wrote:
Notice that they are using "!async->pending" as a covering condition for "async->unknown_status". So I'd argue it's not semantically undefined at all; the semantics of "unknown_status" actually _entails_ that the async is not "pending". It turns out this plays a significant role in the lifecycle of IRP-based asyncs. Assuming the device file is not opened for synchronous I/O, the process is as follows:
Initially, queue_irp() marks the IRP async as having unknown status.
async_handoff() sees that the unknown_status flag is set, and keeps the wait handle open. The wait handle returned to the client.
The client starts to block on the wait handle.
Later, the driver signals the initial status of the IRP as STATUS_PENDING (the IRP has been queued internally by the driver).
The get_next_device_request handler sets the initial status and pending state of async, and wakes up the client.
The client stops waiting and returns the status, which is possibly STATUS_PENDING.
In steps 1-4, the async stays in the "not pending" state. Had the async been in "pending" state and the I/O failed,
correction: and the I/O failed (step 4 set an error code instead of STATUS_PENDING),
step 5 would erroneously trigger APC / IOCP notification mechanism since the failure is treated as asynchronous instead of synchronous.
In this regard, I would argue that the pending flag is best documented as "has the async entered the asynchronous phrase, so that the status would be reported to the client even if it failed?".
In conclusion, we depend on it and we should care.