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.