Call EFI_TCP6_PROTOCOL.Accept() as blocking

Viewed 33

I am trying to implement Rust std for UEFI as a part of my GSoC 2022 project. While trying to implement networking using the EFI_TCP6_PROTOCOL, I am unsure how to proceed. The Rust network operations are synchronous. However, the UEFI side is non-blocking.

So how can I convert a non-blocking UEFI operation to a blocking one? I think it should be possible by using the ListenToken->CompletionToken->Event. However, since this event should be of the EVT_NOTIFY_SIGNAL, it's not possible to call EFI_BOOT_SERVICES.WaitForEvent() on this event. So what am I missing here?

The specific function I am trying to implement is the TcpListener::accept() function. I know this can be non-blocking if the set_nonblocking() option is used, but the default seems to be the blocking. I will also need to make the transmit and receive stuff blocking.

1 Answers

Create the event with a callback function, in the callback function set a flag to true. Set the flag to false before calling Accpet, after you called Accept wait for that flag and call Poll in the loop.

The http example in the UEFI specification (Chapter 29.6.2.1) uses this technique.

You may not use a static flag for the sake of concurrency.

Related