_public_ int sd_bus_call_async(
                sd_bus *bus,
                sd_bus_slot **slot,
                sd_bus_message *_m,
                sd_bus_message_handler_t callback,
                void *userdata,
                uint64_t usec) {

        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
        _cleanup_(sd_bus_slot_unrefp) sd_bus_slot *s = NULL;
        int r;

        assert_return(m, -EINVAL);
        assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
        assert_return(!m->sealed || (!!callback == !(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)), -EINVAL);

        if (!bus)
                bus = m->bus;

        assert_return(!bus_pid_changed(bus), -ECHILD);

        if (!BUS_IS_OPEN(bus->state))
                return -ENOTCONN;

        /* If no callback is specified and there's no interest in a slot, then there's no reason to ask for a reply */
        if (!callback && !slot && !m->sealed)
                m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;

        r = ordered_hashmap_ensure_allocated(&bus->reply_callbacks, &uint64_hash_ops);
        if (r < 0)
                return r;

        r = prioq_ensure_allocated(&bus->reply_callbacks_prioq, timeout_compare);
        if (r < 0)
                return r;

        r = bus_seal_message(bus, m, usec);
        if (r < 0)
                return r;

        r = bus_remarshal_message(bus, &m);
        if (r < 0)
                return r;

        if (slot || callback) {
                s = bus_slot_allocate(bus, !slot, BUS_REPLY_CALLBACK, sizeof(struct reply_callback), userdata);
                if (!s)
                        return -ENOMEM;

                s->reply_callback.callback = callback;

                s->reply_callback.cookie = BUS_MESSAGE_COOKIE(m);
                r = ordered_hashmap_put(bus->reply_callbacks, &s->reply_callback.cookie, &s->reply_callback);
                if (r < 0) {
                        s->reply_callback.cookie = 0;
                        return r;
                }

                s->reply_callback.timeout_usec = calc_elapse(bus, m->timeout);
                if (s->reply_callback.timeout_usec != 0) {
                        r = prioq_put(bus->reply_callbacks_prioq, &s->reply_callback, &s->reply_callback.prioq_idx);
                        if (r < 0) {
                                s->reply_callback.timeout_usec = 0;
                                return r;
                        }
                }
        }

        r = sd_bus_send(bus, m, s ? &s->reply_callback.cookie : NULL);
        if (r < 0)
                return r;

        if (slot)
                *slot = s;
        s = NULL;

        return r;
}
_public_ int sd_bus_call_async(
                sd_bus *bus,
                sd_bus_slot **slot,
                sd_bus_message *_m,
                sd_bus_message_handler_t callback,
                void *userdata,
                uint64_t usec) {

        _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = sd_bus_message_ref(_m);
        _cleanup_(sd_bus_slot_unrefp) sd_bus_slot *s = NULL;
        int r;

        assert_return(m, -EINVAL);
        assert_return(m->header->type == SD_BUS_MESSAGE_METHOD_CALL, -EINVAL);
        assert_return(!m->sealed || (!!callback == !(m->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED)), -EINVAL);

        if (!bus)
                bus = m->bus;

        assert_return(!bus_pid_changed(bus), -ECHILD);

        if (!BUS_IS_OPEN(bus->state))
                return -ENOTCONN;

         
        if (!callback && !slot && !m->sealed)
                m->header->flags |= BUS_MESSAGE_NO_REPLY_EXPECTED;

        r = ordered_hashmap_ensure_allocated(&bus->reply_callbacks, &uint64_hash_ops);
        if (r < 0)
                return r;

        r = prioq_ensure_allocated(&bus->reply_callbacks_prioq, timeout_compare);
        if (r < 0)
                return r;

        r = bus_seal_message(bus, m, usec);
        if (r < 0)
                return r;

        r = bus_remarshal_message(bus, &m);
        if (r < 0)
                return r;

        if (slot || callback) {
                s = bus_slot_allocate(bus, !slot, BUS_REPLY_CALLBACK, sizeof(struct reply_callback), userdata);
                if (!s)
                        return -ENOMEM;

                s->reply_callback.callback = callback;

                s->reply_callback.cookie = BUS_MESSAGE_COOKIE(m);
                r = ordered_hashmap_put(bus->reply_callbacks, &s->reply_callback.cookie, &s->reply_callback);
                if (r < 0) {
                        s->reply_callback.cookie = 0;
                        return r;
                }

                s->reply_callback.timeout_usec = calc_elapse(bus, m->timeout);
                if (s->reply_callback.timeout_usec != 0) {
                        r = prioq_put(bus->reply_callbacks_prioq, &s->reply_callback, &s->reply_callback.prioq_idx);
                        if (r < 0) {
                                s->reply_callback.timeout_usec = 0;
                                return r;
                        }
                }
        }

        r = sd_bus_send(bus, m, s ? &s->reply_callback.cookie : NULL);
        if (r < 0)
                return r;

        if (slot)
                *slot = s;
        s = NULL;

        return r;
}