From 152dfbbc9448f7e7bd3f653dc312fab8d621db71 Mon Sep 17 00:00:00 2001 From: Christian Eltzschig Date: Fri, 13 Aug 2021 14:11:56 +0200 Subject: [PATCH] iox-#903 timed{send,receive} supported in mac os Signed-off-by: Christian Eltzschig --- CHANGELOG.md | 1 + iceoryx_hoofs/platform/mac/source/socket.cpp | 36 +++++++++++++++++-- .../posix_wrapper/unix_domain_socket.cpp | 21 ----------- 3 files changed, 35 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7f68b1a0c..69412215b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ **Features:** +- Enhance MacOS performance with timed{send,receive} functionality in unix domain socket[\#903](https://github.com/eclipse-iceoryx/iceoryx/issues/903) - Enhance posixCall[\#805](https://github.com/eclipse-iceoryx/iceoryx/issues/805) - New chunk available callback for the new C++[\#391](https://github.com/eclipse-iceoryx/iceoryx/issues/391) - Git Hooks on iceoryx[\#486](https://github.com/eclipse-iceoryx/iceoryx/issues/486) diff --git a/iceoryx_hoofs/platform/mac/source/socket.cpp b/iceoryx_hoofs/platform/mac/source/socket.cpp index 6750572c86..cd61170f7a 100644 --- a/iceoryx_hoofs/platform/mac/source/socket.cpp +++ b/iceoryx_hoofs/platform/mac/source/socket.cpp @@ -17,6 +17,24 @@ #include "iceoryx_hoofs/platform/socket.hpp" #include +#include + +static struct timeval getTimeoutOfSocket(int sockfd, int option_name) +{ + struct timeval tv; + socklen_t optionLength = sizeof(struct timeval); + if (getsockopt(sockfd, SOL_SOCKET, option_name, &tv, &optionLength) == -1) + { + return {0, 0}; + } + return tv; +} + +static void sleepFor(struct timeval& tv) +{ + std::this_thread::sleep_for(std::chrono::seconds(tv.tv_sec) + std::chrono::microseconds(tv.tv_usec)); +} + int iox_bind(int sockfd, const struct sockaddr* addr, socklen_t addrlen) { return bind(sockfd, addr, addrlen); @@ -35,12 +53,26 @@ int iox_setsockopt(int sockfd, int level, int optname, const void* optval, sockl ssize_t iox_sendto(int sockfd, const void* buf, size_t len, int flags, const struct sockaddr* dest_addr, socklen_t addrlen) { - return sendto(sockfd, buf, len, flags, dest_addr, addrlen); + auto timeout = getTimeoutOfSocket(sockfd, SO_SNDTIMEO); + ssize_t sentBytes = sendto(sockfd, buf, len, flags, dest_addr, addrlen); + if (sentBytes <= 0 && timeout.tv_sec != 0 && timeout.tv_usec != 0) + { + sleepFor(timeout); + return sendto(sockfd, buf, len, flags, dest_addr, addrlen); + } + return sentBytes; } ssize_t iox_recvfrom(int sockfd, void* buf, size_t len, int flags, struct sockaddr* src_addr, socklen_t* addrlen) { - return recvfrom(sockfd, buf, len, flags, src_addr, addrlen); + auto timeout = getTimeoutOfSocket(sockfd, SO_RCVTIMEO); + ssize_t receivedBytes = recvfrom(sockfd, buf, len, flags, src_addr, addrlen); + if (receivedBytes <= 0 && timeout.tv_sec != 0 && timeout.tv_usec != 0) + { + sleepFor(timeout); + return recvfrom(sockfd, buf, len, flags, src_addr, addrlen); + } + return receivedBytes; } int iox_connect(int sockfd, const struct sockaddr* addr, socklen_t addrlen) diff --git a/iceoryx_hoofs/source/posix_wrapper/unix_domain_socket.cpp b/iceoryx_hoofs/source/posix_wrapper/unix_domain_socket.cpp index 397be48d5c..e276d9eac0 100644 --- a/iceoryx_hoofs/source/posix_wrapper/unix_domain_socket.cpp +++ b/iceoryx_hoofs/source/posix_wrapper/unix_domain_socket.cpp @@ -232,16 +232,6 @@ cxx::expected UnixDomainSocket::timedSend(const std::string& ms } struct timeval tv = timeout; -#if defined(__APPLE__) - if (tv.tv_sec != 0 || tv.tv_usec != 0) - { - std::cerr - << "socket: \"" << m_name - << "\", timedSend with a timeout != 0 is not supported on MacOS. timedSend will behave like send instead." - << std::endl; - } -#endif - auto setsockoptCall = posixCall(iox_setsockopt)(m_sockfd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)) .failureReturnValue(ERROR_CODE) .ignoreErrnos(EWOULDBLOCK) @@ -289,17 +279,6 @@ UnixDomainSocket::timedReceive(const units::Duration& timeout) const noexcept } struct timeval tv = timeout; -#if defined(__APPLE__) - if (tv.tv_sec != 0 || tv.tv_usec != 0) - { - std::cerr - << "socket: \"" << m_name - << "\", timedReceive with a timeout != 0 is not supported on MacOS. timedReceive will behave like receive " - "instead." - << std::endl; - } -#endif - auto setsockoptCall = posixCall(iox_setsockopt)(m_sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) .failureReturnValue(ERROR_CODE) .ignoreErrnos(EWOULDBLOCK)