diff options
author | Matt Fleming <matt.fleming@intel.com> | 2013-07-12 13:47:22 +0100 |
---|---|---|
committer | Matt Fleming <matt.fleming@intel.com> | 2013-07-12 13:53:07 +0100 |
commit | 7ab8f23aa2140951608544ed557f7529cf32d98d (patch) | |
tree | 695692ac25cf676269cc63888d0c03486a91fc2b | |
parent | 3ede311eec28bba77f3469d4e0a834ac000f686e (diff) | |
download | syslinux-7ab8f23aa2140951608544ed557f7529cf32d98d.tar.gz syslinux-7ab8f23aa2140951608544ed557f7529cf32d98d.tar.xz syslinux-7ab8f23aa2140951608544ed557f7529cf32d98d.zip |
efi, udp: implement receive timeoutsyslinux-6.02-pre5
We currently wait indefinitely in core_udp_recv() when reading packets.
Implement a timeout, which is what all the other network stacks do. By
timing out we are now able to handle packet loss on the network, e.g.
we'll now re-send TFTP requests instead of waiting for ACK packets that
will never come.
Signed-off-by: Matt Fleming <matt.fleming@intel.com>
-rw-r--r-- | efi/udp.c | 17 |
1 files changed, 16 insertions, 1 deletions
@@ -182,6 +182,7 @@ int core_udp_recv(struct pxe_pvt_inode *socket, void *buf, uint16_t *buf_len, EFI_UDP4 *udp; size_t size; int rv = -1; + jiffies_t start; (void)socket; @@ -197,8 +198,19 @@ int core_udp_recv(struct pxe_pvt_inode *socket, void *buf, uint16_t *buf_len, if (status != EFI_SUCCESS) goto bail; - while (cb_status == -1) + start = jiffies(); + while (cb_status == -1) { + /* 15ms receive timeout... */ + if (jiffies() - start >= 15) { + if (jiffies() - start >= 30) + dprintf("Failed to cancel UDP\n"); + + uefi_call_wrapper(udp->Cancel, 2, udp, &token); + dprintf("core_udp_recv: timed out\n"); + } + uefi_call_wrapper(udp->Poll, 1, udp); + } if (cb_status == 0) rv = 0; @@ -206,6 +218,9 @@ int core_udp_recv(struct pxe_pvt_inode *socket, void *buf, uint16_t *buf_len, /* Reset */ cb_status = -1; + if (rv) + goto bail; + rxdata = token.Packet.RxData; frag = &rxdata->FragmentTable[0]; |