Просмотр исходного кода

LibCore: Add a timeout option to UDPSocket::connect

This allows us to set a timeout during connection and during receive and
send operations. I didn't add this to the other connect calls as it's
not used anywhere else for the time being.
sin-ack 3 лет назад
Родитель
Сommit
17d3592cab
2 измененных файлов с 16 добавлено и 5 удалено
  1. 12 3
      Userland/Libraries/LibCore/Stream.cpp
  2. 4 2
      Userland/Libraries/LibCore/Stream.h

+ 12 - 3
Userland/Libraries/LibCore/Stream.cpp

@@ -390,6 +390,12 @@ ErrorOr<void> PosixSocketHelper::set_close_on_exec(bool enabled)
     return {};
     return {};
 }
 }
 
 
+ErrorOr<void> PosixSocketHelper::set_receive_timeout(Time timeout)
+{
+    auto timeout_spec = timeout.to_timespec();
+    return System::setsockopt(m_fd, SOL_SOCKET, SO_RCVTIMEO, &timeout_spec, sizeof(timeout_spec));
+}
+
 void PosixSocketHelper::setup_notifier()
 void PosixSocketHelper::setup_notifier()
 {
 {
     if (!m_notifier)
     if (!m_notifier)
@@ -438,18 +444,21 @@ ErrorOr<size_t> PosixSocketHelper::pending_bytes() const
     return static_cast<size_t>(value);
     return static_cast<size_t>(value);
 }
 }
 
 
-ErrorOr<NonnullOwnPtr<UDPSocket>> UDPSocket::connect(String const& host, u16 port)
+ErrorOr<NonnullOwnPtr<UDPSocket>> UDPSocket::connect(String const& host, u16 port, Optional<Time> timeout)
 {
 {
     auto ip_address = TRY(resolve_host(host, SocketType::Datagram));
     auto ip_address = TRY(resolve_host(host, SocketType::Datagram));
-    return connect(SocketAddress { ip_address, port });
+    return connect(SocketAddress { ip_address, port }, timeout);
 }
 }
 
 
-ErrorOr<NonnullOwnPtr<UDPSocket>> UDPSocket::connect(SocketAddress const& address)
+ErrorOr<NonnullOwnPtr<UDPSocket>> UDPSocket::connect(SocketAddress const& address, Optional<Time> timeout)
 {
 {
     auto socket = TRY(adopt_nonnull_own_or_enomem(new (nothrow) UDPSocket()));
     auto socket = TRY(adopt_nonnull_own_or_enomem(new (nothrow) UDPSocket()));
 
 
     auto fd = TRY(create_fd(SocketDomain::Inet, SocketType::Datagram));
     auto fd = TRY(create_fd(SocketDomain::Inet, SocketType::Datagram));
     socket->m_helper.set_fd(fd);
     socket->m_helper.set_fd(fd);
+    if (timeout.has_value()) {
+        TRY(socket->m_helper.set_receive_timeout(timeout.value()));
+    }
 
 
     TRY(connect_inet(fd, address));
     TRY(connect_inet(fd, address));
 
 

+ 4 - 2
Userland/Libraries/LibCore/Stream.h

@@ -14,6 +14,7 @@
 #include <AK/Result.h>
 #include <AK/Result.h>
 #include <AK/Span.h>
 #include <AK/Span.h>
 #include <AK/String.h>
 #include <AK/String.h>
+#include <AK/Time.h>
 #include <AK/Variant.h>
 #include <AK/Variant.h>
 #include <LibCore/Notifier.h>
 #include <LibCore/Notifier.h>
 #include <LibCore/SocketAddress.h>
 #include <LibCore/SocketAddress.h>
@@ -247,6 +248,7 @@ public:
 
 
     ErrorOr<void> set_blocking(bool enabled);
     ErrorOr<void> set_blocking(bool enabled);
     ErrorOr<void> set_close_on_exec(bool enabled);
     ErrorOr<void> set_close_on_exec(bool enabled);
+    ErrorOr<void> set_receive_timeout(Time timeout);
 
 
     void setup_notifier();
     void setup_notifier();
     RefPtr<Core::Notifier> notifier() { return m_notifier; }
     RefPtr<Core::Notifier> notifier() { return m_notifier; }
@@ -321,8 +323,8 @@ private:
 
 
 class UDPSocket final : public Socket {
 class UDPSocket final : public Socket {
 public:
 public:
-    static ErrorOr<NonnullOwnPtr<UDPSocket>> connect(String const& host, u16 port);
-    static ErrorOr<NonnullOwnPtr<UDPSocket>> connect(SocketAddress const& address);
+    static ErrorOr<NonnullOwnPtr<UDPSocket>> connect(String const& host, u16 port, Optional<Time> timeout = {});
+    static ErrorOr<NonnullOwnPtr<UDPSocket>> connect(SocketAddress const& address, Optional<Time> timeout = {});
 
 
     UDPSocket(UDPSocket&& other)
     UDPSocket(UDPSocket&& other)
         : Socket(static_cast<Socket&&>(other))
         : Socket(static_cast<Socket&&>(other))