assert(nl);
assert(m);
+ serial = message_get_serial(m);
+ if (serial != 0) {
+ NetlinkIgnoredSerial *s = hashmap_remove(nl->ignored_serials, UINT32_TO_PTR(serial));
+ if (s) {
+ /* We are not interested in the message anymore. */
+ free(s);
+ return 0;
+ }
+ }
+
if (ordered_set_size(nl->rqueue) >= NETLINK_RQUEUE_MAX)
return log_debug_errno(SYNTHETIC_ERRNO(ENOBUFS),
"sd-netlink: exhausted the read queue size (%d)", NETLINK_RQUEUE_MAX);
if (sd_netlink_message_is_broadcast(m))
return 0;
- serial = message_get_serial(m);
if (serial == 0)
return 0;
assert(nl);
+ hashmap_free(nl->ignored_serials);
+
ordered_set_free(nl->rqueue);
hashmap_free(nl->rqueue_by_serial);
hashmap_free(nl->rqueue_partial_by_serial);
return usec_add(netlink_now(nl, CLOCK_MONOTONIC), usec);
}
+static void netlink_trim_ignored_serials(sd_netlink *nl) {
+ NetlinkIgnoredSerial *s;
+ usec_t now_usec = 0;
+
+ assert(nl);
+
+ HASHMAP_FOREACH(s, nl->ignored_serials) {
+ if (s->timeout_usec == USEC_INFINITY)
+ continue;
+
+ if (now_usec == 0)
+ now_usec = netlink_now(nl, CLOCK_MONOTONIC);
+
+ if (s->timeout_usec < now_usec)
+ free(hashmap_remove(nl->ignored_serials, UINT32_TO_PTR(s->serial)));
+ }
+}
+
+int sd_netlink_ignore_serial(sd_netlink *nl, uint32_t serial, uint64_t timeout_usec) {
+ int r;
+
+ assert_return(nl, -EINVAL);
+ assert_return(!netlink_pid_changed(nl), -ECHILD);
+ assert_return(serial != 0, -EINVAL);
+
+ timeout_usec = timespan_to_timestamp(nl, timeout_usec);
+
+ NetlinkIgnoredSerial *existing = hashmap_get(nl->ignored_serials, UINT32_TO_PTR(serial));
+ if (existing) {
+ existing->timeout_usec = timeout_usec;
+ return 0;
+ }
+
+ netlink_trim_ignored_serials(nl);
+
+ _cleanup_free_ NetlinkIgnoredSerial *s = new(NetlinkIgnoredSerial, 1);
+ if (!s)
+ return -ENOMEM;
+
+ *s = (NetlinkIgnoredSerial) {
+ .serial = serial,
+ .timeout_usec = timeout_usec,
+ };
+
+ r = hashmap_ensure_put(&nl->ignored_serials, &trivial_hash_ops_value_free, UINT32_TO_PTR(s->serial), s);
+ if (r < 0)
+ return r;
+
+ TAKE_PTR(s);
+ return 0;
+}
+
int sd_netlink_send(
sd_netlink *nl,
sd_netlink_message *message,
assert(nl);
+ netlink_trim_ignored_serials(nl);
+
r = process_timeout(nl);
if (r != 0)
goto null_message;
int sd_netlink_call(sd_netlink *nl, sd_netlink_message *message, uint64_t timeout, sd_netlink_message **ret);
int sd_netlink_read(sd_netlink *nl, uint32_t serial, uint64_t timeout, sd_netlink_message **ret);
+int sd_netlink_ignore_serial(sd_netlink *nl, uint32_t serial, uint64_t timeout_usec);
+
int sd_netlink_get_events(sd_netlink *nl);
int sd_netlink_get_timeout(sd_netlink *nl, uint64_t *ret);
int sd_netlink_process(sd_netlink *nl, sd_netlink_message **ret);