rtnetlink_server: Fix edge triggering
We need to receive messages until there are no more pending or else we
will leave messages in the file descriptor.
Change-Id: I3f4a5a7e57ccca62be76591d47c8317d995e527e
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/netlink.cpp b/src/netlink.cpp
index 5a3dc74..1577161 100644
--- a/src/netlink.cpp
+++ b/src/netlink.cpp
@@ -125,7 +125,7 @@
} // namespace detail
-void receive(int sock, ReceiveCallback cb)
+size_t receive(int sock, ReceiveCallback cb)
{
// We need to make sure we have enough room for an entire packet otherwise
// it gets truncated. The netlink docs guarantee packets will not exceed 8K
@@ -146,27 +146,29 @@
// We only do multiple recvs if we have a MULTI type message
bool done = true;
+ size_t num_msgs = 0;
do
{
ssize_t recvd = recvmsg(sock, &hdr, 0);
- if (recvd < 0)
+ if (recvd < 0 && errno != EAGAIN)
{
throw std::system_error(errno, std::generic_category(),
"netlink recvmsg");
}
- if (recvd == 0)
+ if (recvd <= 0)
{
if (!done)
{
throw std::runtime_error("netlink recvmsg: Got empty payload");
}
- return;
+ return num_msgs;
}
std::string_view msgs(buf.data(), recvd);
do
{
detail::processMsg(msgs, done, cb);
+ num_msgs++;
} while (!done && !msgs.empty());
if (done && !msgs.empty())
@@ -174,6 +176,7 @@
throw std::runtime_error("Extra unprocessed netlink messages");
}
} while (!done);
+ return num_msgs;
}
std::tuple<rtattr, std::string_view> extractRtAttr(std::string_view& data)
diff --git a/src/netlink.hpp b/src/netlink.hpp
index 754b4b4..be44d24 100644
--- a/src/netlink.hpp
+++ b/src/netlink.hpp
@@ -34,7 +34,7 @@
* @param[in] sock - The socket to receive the messages on
* @param[in] cb - Called for each response message payload
*/
-void receive(int sock, ReceiveCallback cb);
+size_t receive(int sock, ReceiveCallback cb);
/* @brief Call on an rtnetlink payload
* Updates the input to remove the attr parsed out.
diff --git a/src/rtnetlink_server.cpp b/src/rtnetlink_server.cpp
index cf68340..2c093bc 100644
--- a/src/rtnetlink_server.cpp
+++ b/src/rtnetlink_server.cpp
@@ -61,7 +61,8 @@
static void eventHandler(sdeventplus::source::IO&, int fd, uint32_t)
{
- receive(fd, handler);
+ while (receive(fd, handler) > 0)
+ ;
}
static stdplus::ManagedFd makeSock()