0

I am developing an application where I want to set network changes detector. In order to achieve that I have tried to create connection to GDBus in background thread, but i cant make it work.

Could someone tell me what I am doing wrong?

This is my code:

typedef struct connectivity_struct
{
    GMainLoop *loop;
    GDBusProxy *    proxy;

} CONNECTIVITY_STRUCT;

static void
on_signal(GDBusProxy *proxy,
          char *      sender_name,
          char *      signal_name,
          GVariant *  parameters,
          gpointer    user_data)
{
    guint32 new_state;

    /* We are only interested in "StateChanged" signal */
    if (strcmp(signal_name, "StateChanged") == 0) {
        GVariant *tmp = g_variant_get_child_value(parameters, 0);
        new_state     = g_variant_get_uint32(tmp);
        g_variant_unref(tmp);
        g_print("NetworkManager state is: (%d) \n",
                new_state);

void* thread_function(void *data)
{
    g_print (" *** Thread executed!");
    CONNECTIVITY_STRUCT* conn = (CONNECTIVITY_STRUCT*)(data);
    GMainContext *context = g_main_context_new();
    g_main_context_push_thread_default(context);
    conn->loop = g_main_loop_new(context, FALSE);
    g_signal_connect((conn->proxy), "g-signal", G_CALLBACK(on_signal), NULL);
    g_main_loop_run ((conn->loop) );
    g_print("after launching loop run");
    return nullptr;
}

int
main(int argc, char *argv[])
{
    GMainLoop *     loop;
    GError *        error = NULL;
    GDBusProxyFlags flags;
    GDBusProxy *    proxy;

    /* Monitor 'StateChanged' signal on 'org.freedesktop.NetworkManager' interface */
    g_print("Monitor NetworkManager's state\n");
    g_print("==============================\n");

    flags =
     static_cast<GDBusProxyFlags>(G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START);
    proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
                                          flags,
                                          NULL, /* GDBusInterfaceInfo */
                                          "org.freedesktop.NetworkManager",
                                          "/org/freedesktop/NetworkManager",
                                          "org.freedesktop.NetworkManager",
                                          NULL, /* GCancellable */
                                          &error);

    if (proxy == NULL) {
        g_dbus_error_strip_remote_error(error);
        g_printerr("Error creating D-Bus proxy: %s\n", error->message);
        g_error_free(error);
        return -1;
    }

    GThread *ps_thread;
    CONNECTIVITY_STRUCT sConnectivity;
    sConnectivity.loop = loop;
sConnectivity.proxy = proxy;
    ps_thread = g_thread_new("thread", thread_function, &sConnectivity);

    /* wait probe_wait */
    gdouble time_passed = 0 ;
    gdouble probe_wait = 15.0;
    GTimer *timer = g_timer_new();
    g_timer_start( timer );
    while(time_passed < probe_wait){
        time_passed = g_timer_elapsed ( timer, NULL );
    }

    // is this needed??????
    //g_thread_join(ps_thread);

    if (g_main_loop_is_running(loop)) {
        g_main_loop_quit(loop);
        g_main_loop_unref(loop);
    }
    g_object_unref(proxy);

    return 0;
}

I am not sure if join instruction is needed. Ideally I would like the thread to start running while i am doing other tasks. If i remove the join without the sleep added for testing the program ends inmediately I assume I am missing somehting, but I am not able to see what.

RuLoViC
  • 825
  • 7
  • 23

0 Answers0