From 9098efdf0dd82dea36b517e92ce7c5740e00b1eb Mon Sep 17 00:00:00 2001 From: "Doug Cook (WINDOWS)" Date: Sat, 30 Nov 2024 17:47:38 -0800 Subject: EmulatorPkg: BlockIo2 APIs do not signal event BlockIo2 Read/Write/Flush APIs should signal the token's event when the I/O operation completes, but the Emulator APIs do not. As a result, any code that tries to implement async I/O will hang on emulator. Both Windows and Unix emulator hosts work the same way: - All I/O is completed synchronously. - All I/O implementations contain the comment: `// Caller is responsible for signaling EFI Event` However, the protocol implementations do not signal the event, so the event is never signalled. Fix is to signal the event in the appropriate protocol implementations. - If the host API returns success then the I/O is complete since it's always synchronous. - If there is a Token and Token->Event is not null and the I/O is successful then the event should be signalled. Signed-off-by: Doug Cook --- EmulatorPkg/EmuBlockIoDxe/EmuBlockIo.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/EmulatorPkg/EmuBlockIoDxe/EmuBlockIo.c b/EmulatorPkg/EmuBlockIoDxe/EmuBlockIo.c index 4e8caf2514..685824b79b 100644 --- a/EmulatorPkg/EmuBlockIoDxe/EmuBlockIo.c +++ b/EmulatorPkg/EmuBlockIoDxe/EmuBlockIo.c @@ -96,6 +96,11 @@ EmuBlockIo2ReadBlocksEx ( Status = Private->Io->ReadBlocks (Private->Io, MediaId, LBA, Token, BufferSize, Buffer); gBS->RestoreTPL (OldTpl); + + if (Token && Token->Event && !EFI_ERROR (Status)) { + gBS->SignalEvent (Token->Event); + } + return Status; } @@ -152,6 +157,11 @@ EmuBlockIo2WriteBlocksEx ( Status = Private->Io->WriteBlocks (Private->Io, MediaId, LBA, Token, BufferSize, Buffer); gBS->RestoreTPL (OldTpl); + + if (Token && Token->Event && !EFI_ERROR (Status)) { + gBS->SignalEvent (Token->Event); + } + return Status; } @@ -195,6 +205,11 @@ EmuBlockIo2Flush ( Status = Private->Io->FlushBlocks (Private->Io, Token); gBS->RestoreTPL (OldTpl); + + if (Token && Token->Event && !EFI_ERROR (Status)) { + gBS->SignalEvent (Token->Event); + } + return Status; } -- cgit