diff options
author | Joe Crayne <joe@jerkface.net> | 2019-10-18 00:29:32 -0400 |
---|---|---|
committer | Joe Crayne <joe@jerkface.net> | 2020-01-01 19:46:43 -0500 |
commit | afe40dd42f257cb90a1de207867a1c399a26e38c (patch) | |
tree | bb552fd67e8162d82ac92c0f6f17c853bdc0defe /dht | |
parent | bbe88b6faf37f3031312c7eaabaefd8d149f3e33 (diff) |
Use O_NONBLOCK to interrupt blocking recvFrom.
Diffstat (limited to 'dht')
-rw-r--r-- | dht/src/Network/QueryResponse.hs | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/dht/src/Network/QueryResponse.hs b/dht/src/Network/QueryResponse.hs index c4ff50e3..f72763de 100644 --- a/dht/src/Network/QueryResponse.hs +++ b/dht/src/Network/QueryResponse.hs | |||
@@ -553,9 +553,14 @@ sockAddrFamily _ = AF_CAN -- SockAddrCan constructor depre | |||
553 | -- | Packets with an empty payload may trigger EOF exception. | 553 | -- | Packets with an empty payload may trigger EOF exception. |
554 | -- 'udpTransport' uses this function to avoid throwing in that | 554 | -- 'udpTransport' uses this function to avoid throwing in that |
555 | -- case. | 555 | -- case. |
556 | ignoreEOF :: a -> IOError -> IO a | 556 | ignoreEOF :: Socket -> MVar () -> a -> IOError -> IO (Maybe a) |
557 | ignoreEOF def e | isEOFError e = pure def | 557 | ignoreEOF sock isClosed def e = do |
558 | | otherwise = throwIO e | 558 | done <- tryReadMVar isClosed |
559 | case done of | ||
560 | Just () -> do close sock | ||
561 | pure Nothing | ||
562 | _ -> if isEOFError e then pure $ Just def | ||
563 | else throwIO e | ||
559 | 564 | ||
560 | -- | Hard-coded maximum packet size for incoming UDP Packets received via | 565 | -- | Hard-coded maximum packet size for incoming UDP Packets received via |
561 | -- 'udpTransport'. | 566 | -- 'udpTransport'. |
@@ -589,9 +594,10 @@ udpTransport' bind_address = do | |||
589 | setSocketOption sock IPv6Only 0 | 594 | setSocketOption sock IPv6Only 0 |
590 | setSocketOption sock Broadcast 1 | 595 | setSocketOption sock Broadcast 1 |
591 | bind sock bind_address | 596 | bind sock bind_address |
597 | isClosed <- newEmptyMVar | ||
592 | let tr = Transport { | 598 | let tr = Transport { |
593 | awaitMessage = \kont -> do | 599 | awaitMessage = \kont -> do |
594 | r <- handle (ignoreEOF $ Just $ Right (B.empty, SockAddrInet 0 0)) $ do | 600 | r <- handle (ignoreEOF sock isClosed $ Right (B.empty, SockAddrInet 0 0)) $ do |
595 | Just . Right <$!> B.recvFrom sock udpBufferSize | 601 | Just . Right <$!> B.recvFrom sock udpBufferSize |
596 | kont $! r | 602 | kont $! r |
597 | , sendMessage = case family of | 603 | , sendMessage = case family of |
@@ -609,7 +615,12 @@ udpTransport' bind_address = do | |||
609 | addr@(SockAddrInet6 {}) -> \bs -> dput XMisc ("Discarding packet to "++show addr) | 615 | addr@(SockAddrInet6 {}) -> \bs -> dput XMisc ("Discarding packet to "++show addr) |
610 | addr4 -> \bs -> saferSendTo sock bs addr4 | 616 | addr4 -> \bs -> saferSendTo sock bs addr4 |
611 | _ -> \addr bs -> saferSendTo sock bs addr | 617 | _ -> \addr bs -> saferSendTo sock bs addr |
612 | , closeTransport = close sock | 618 | , closeTransport = do |
619 | -- close sock | ||
620 | tryTakeMVar isClosed >> putMVar isClosed () | ||
621 | -- set O_NONBLOCK using fcntl | ||
622 | setNonBlockIfNeeded (fdSocket sock) -- setSocketOption sock ??? 0 | ||
623 | |||
613 | } | 624 | } |
614 | return (tr, sock) | 625 | return (tr, sock) |
615 | 626 | ||