Getting repeatable connection problem after using an event loop

Jimi Damon jdamon at gmail.com
Sat Oct 3 15:28:36 UTC 2020


Hi,

I'm trying to make a friendly API for our developers where one API function
will wait until a heartbeat signal is received or a timeout occurs.  It
should only call the callback 1 time and then unregister the callback
handler since we only want to know that one heartbeat occurred. I have an
event loop to handle the signal received if there is one and a simple
callback function listed here :

The general code is simple:
/* Callback Function */
    int32_t tcb(sd_bus_message* message, void* userdata, sd_bus_error*
error)
    {

        waiting_control_t* ud = userdata;
        if (ud)
        {
            /* printf("CALLBACK CALLED\n"); */
            ud->found = 1;
            sd_bus_slot_unref(ud->slot);
        }

        return EXIT_SUCCESS;
    }

/* Wait for signal */
int32_t
wait_for_signal(sd_bus* bus, char* match, uint64_t time_microseconds)
{

    int32_t r;
    int32_t found          = 0;
    waiting_control_t data = { .slot = NULL, .found = 0 };
    sd_bus_error err       = SD_BUS_ERROR_NULL;

    sd_bus_add_match(bus, &data.slot, match, tcb, &data);
    do
    {
        r = sd_bus_process(bus, NULL);
        if (r < 0)
        {
            fprintf(stderr, "Failed to process bus: %s\n", strerror(-r));
            break;
        }
        r = sd_bus_wait(bus, 1000);
    } while (!data.found && (time_microseconds-=1000) > 0);

    if (data.found)
        return 0;
    else
        return -1;
}

/*Other API function that returns sees -22 on sd_bus_set_property */
int logging_client_set_log_path(char *path)
{
    int32_t r;
    logging_client_bus_struct_t b;
    sd_bus_message* msg;
    sd_bus_error error;
    logging_client_bus_init(&b);
    const char *s;
    r = logging_client_bus_open(&b);
    if (r < 0)
    {
        printf("Failed to open log_client bus\n");
        return r;
    }
    r = sd_bus_set_property(b.bus,
                            LOG_DESTINATION_NAME,
                            LOG_OBJECT_PATH,
                            LOG_INTERFACE_NAME,
                            "logPath",
                            &b.client_bus_error,
                            "s",
                            path
                            );
    return r;
}


The problem I have is that if I call another API function
(logging_client_set_log_path) AFTER I have called this function, then the
second API call (which sets a property)  ALWAYS fails with a -22 return
code (coming from sd_bus_set_property). However, if I don't call this
wait_for_signal API call, then my other API function seems to always
succeed.

Through all of this testing I can always run "busctl set-property ..."
commands to set the logPath property . Hence I know that my server can
correctly see these set-property commands and leads me to believe  that I'm
not cleaning up structures in the function wait_for_signal correctly.


In addition, there was something weird about my code. I had to add this

if (ud) { .. }

block because my callback function was getting called twice. I did not
expect this since  I thought the first

sd_bus_slot_unref(ud->slot);

would have disabled the callback function.

Thanks  for any tips about what I'm not doing correctly to clean up this
signal matcher and maybe why my signal matcher is getting called twice.

-Jimi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/dbus/attachments/20201003/b423a599/attachment.htm>


More information about the dbus mailing list