GLIB usage without mainloop - c

I have a problem using Glib. I want to subscribe to a dbus signal without launching the mainloop with g_main_loop_run.
I create the connection to the correct bus and call the function g_dbus_connection_signal_subscribe.
I replaced the call to g_main_loop_run in the main function by a while(1).
Unfortunately, it's not working. If I understand correctly the GLib, there is no need to launch the mainloop for a such treatment.
Please help.
Sample code :
session_bus = g_bus_get_sync(G_BUS_TYPE_SESSION,
NULL,
NULL );
g_dbus_connection_signal_subscribe(session_bus,
"org.freedesktop.Notifications",
"org.freedesktop.Notifications",
"NotificationClosed",
"/org/freedesktop/Notifications",
NULL,
G_DBUS_SIGNAL_FLAGS_NONE,
(GDBusSignalCallback) onNotifClosed,
NULL,
NULL );
loop = g_main_loop_new(NULL, FALSE);
g_main_loop_run(loop);
g_main_loop_unref(loop);
g_object_unref(session_bus);

If I understand correctly the GLib, there is no need to launch the
mainloop for a such treatment.
If you want to wait for incoming DBus events, you have to run main loop. What main loop does is to wait and process events, and you want to wait and then process events. As an alternative to g_main_loop_run, you may try to run g_main_context_iteration in while(1).

I had a similar need to process GLib events in a non-blocking manner and I couldn't find a complete answer anywhere, so I'm posting my solution here for reference.
As el.pescado said, the one alternative to g_main_loop_run() is calling g_main_context_iteration() repeatedly on the context of the GMainLoop object. This may be done in a loop for example, allowing some intervening_task() to be performed between event processing cycles until some sort of termination_condition() is met:
GMainLoop *loop = g_main_loop_new();
while (!termination_condition())
{
g_main_context_iteration(g_main_loop_get_context(loop), FALSE);
intervening_task();
}
g_main_loop_unref(loop);
In the snippet above, the loop context is retrieved by g_main_loop_get_context(), and any pending GLib events are processed by g_main_context_iteration(). Setting the may_block argument to FALSE causes the function to return immediately if there are no pending events (otherwise it would block waiting for something to process).
It's worth noticing however that if the above is all you want to do, then you might as well stick to g_main_loop_run() and use g_timeout_add() or g_idle_add() to register the intervening task and termination condition as event callbacks — the later would call g_main_loop_quit() to terminate the loop. The point here is not to use that code as-is, but merely to demonstrate how GLib events can be processed in a non-blocking manner, so it can be integrated to the main loop of another framework. e.g. Qt or ROS.

Related

NetworkManager libnm thread safety

I'm trying to use NetworkManager's libnm binding from a multithreaded program. Is libnm thread safe? I could not found any information about it.
libnm is written using glib and gobject. Although they don't seem to explicitly mention it in their doc, in general anything that uses glib runs on the main event loop and expects that the API will only be called on the main event loop (ie: on the thread that the event loop runs on).
Glib itself, however, is thread safe in general, or provides ways to ensure thread safety. For example, to connect to signal of libnm, you can use g_signal_connect from any thread; however the signal handler which you provide will be invoked on the thread running the main loop. Also, you can use something like g_idle_add from any thread, in order to schedule a function to be called from the main event loop.
You can also use the GTask lib to help you with threading in glib. Thre is more info about the Glib main context here.

Is it possible to change signal handler return point?

My first post here, so sorry if something not according to the rules.
Need advice for a problem in C.
I'm using a signal handler(SIGALRM) with timeout on an input from user (Stdin).
If the user didn't type anything then:
timeout expired
signal handler called
(PROBLEM) - > it returns to the same line before timeout occurred.
IMPORTANT :
I can't use select and can't use poll functions because it's a third party mechanism I use and must use their methods.
They eventually use select, but it's not straightforward and I just need to use their method.
The problem is:
After returning from signal handler i"m still 'stuck' on the same line waiting for input.
I can't use longjmp, can't call other method, can't print message to the user, can't use goto.
All unsafe from handler and creating errors.
The code looks something like this:
sa.sigaction(SIGALRM, &handler,Null):
.
.
While(done! =1)
{
alarm(20); //20 seconds timeout started
If(ReadLineMethod()>0) //wait for successful input from stdin
{
If(inputErr ==1)
{
**here(for example) I want to print user that timeout occured and return from the program (exit) **
}
alarm(0);
done==1;
// Do stuff here
}
}
/* Rest of the program before exit */
The while is for asking for a specific input until he types it right or timeout kicks him out.
void handler (int signum)
{
inputErr==1;// global parameter
}
Is there any work around for me to skip that line of reading the input after returning from the handler?
Or at least managing to print a proper message to the user that timeout occured?and not just return and get stuck on the input again lol.
Thanks a lot in advance.
Use a flag that the handler raises. Condition the printing with this flag. You will need to protect this flag with a mutex.
If you aren't allowed to reimplement ReadLineMethod() to be more reasonable, how about using threads? I'm not an expert on pthread, but you could probably set things up so that ReadLineMethod happens on one thread and polling for the error happens on another thread. There even seems to be a pthread_cancel function that can forcibly stop the reader thread if need be: http://man7.org/linux/man-pages/man3/pthread_cancel.3.html
Because you have so many restrictions, one way to get total control over this system will be:
Create a thread and run ReadLineMethod() in that thread.
Create another thread and use a timer in that thread. Do not use signals but detect otherwise that the rime has run out.
When the timer thread understands that the timer has run our, let it kill the thread in (1).
Else, if ReadLineMethod() has run to completion cleanly, let the timer thread do nothing and complete.
Of course, this is convoluted because of the requirements. If the fundamental requirement is known, there may be better alternatives.

Threading problems with GTK

I'm building a fairly simple C application using GTK, but have to perform some blocking IO which will trigger updates to the GUI. In order to do this, I start a new pthread right before gtk_main() as such:
/* global variables */
GMainContext *mainc;
/* local variables */
FILE *fifo;
pthread_t reader;
/* main() */
mainc = g_main_context_default();
pthread_create(&reader, NULL, watch_fifo, argv[argc-1]);
gtk_main();
When the pthread reads some data, it updates the GUI like so:
g_main_context_invoke(mainc, set_icon, param);
Where set_icon is
gboolean set_icon(gpointer data)
{
char *p = (char*)data;
gtk_status_icon_set_from_icon_name(icon, p);
return FALSE;
}
This all works most of the time, but every now and again I get this curious error message:
[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not been called
[xcb] Aborting, sorry about that.
mktrayicon: xcb_io.c:274: poll_for_event: Assertion `!xcb_xlib_threads_sequence_lost' failed.
I thought the whole point of using g_main_context_invoke was to avoid issues with threads? Doing a bit of Googling, I came across gdk_threads_init, gdk_threads_enter and friends, but they all seem to be deprecated? I know the GTK documentation says that all GUI updaes should be performed on the main thread, but this does not combine all that well with blocking IO, and I'd prefer not to have to construct some complex communication mechanism between the threads.
And so, my question is, how should I correctly deal with this?
EDIT: The full code can be seen here
EDIT2: As an update based on #ptomato's answer, I've moved to GThreads and using gdk_threads_add_idle() as seen in this commit, but the problem is still present.
Call XInitThreads(). This should be done before gtk_init, that will stop the messages!
Something like this:
#include <X11/Xlib.h>
...
XInitThreads();
...
gtk_init(&argc, &argv);
I don't remember seeing these messages before GLIB 2.32, when
g_thread_init()/gdk_threads_init() were used.
You might want to check out g_thread_pool_new and g_thread_pool_push.
From thread, use g_main_context_invoke to execute in main loop or
just wrap thread between gdk_threads_enter()/gdk_threads_leave()
I do not use a tray so I can not easily check this. I think you are
correct about gdk_threads_add_idle using locks to protect GTK/GDK API.
There is nothing obvious to me that would cause these messages to
appear. The function description for gtk_status_icon_new_from_icon_name
states that "If the current icon theme is changed, the icon will be
updated appropriately. Which to me, implies your code is not the only
code that will access the X display, which could potentially be the
problem.
There is also some related info regarding XInitThreads() at
What is the downside of XInitThreads()?
Note that while GDK uses locks for the display, GTK/GDK do not ever
call XInitThreads.
On a side note: What's protecting the global variable "onclick", which
is passed to execl after a fork(), The child will not inherit the parent's
memory locks, and GLib mainloop is incompatible with fork().
Maybe you could copy the string to local variable.
I'm not sure if bare pthreads are guaranteed to work with GTK. You should use the GThread wrappers.
I think what the problem may be is that g_main_context_invoke() is adding set_icon() as an idle function. (It seems that that is what goes on behind the scenes, but I'm not sure.) Idle functions added using GLib's API, despite being executed on the main thread, need to hold the GDK lock. If you use the gdk_threads_add_idle() API (which is not deprecated) to invoke set_icon(), then everything should work properly with threading.
(Although this is just a wild guess.)
As a work around, if you just want to avoid blocking the UI while waiting for some IO you could use the asynchronous IO from GIO. That would avoid you having to manage threads yourself.
Edit: Thinking about it you could just mark your file descriptors as non-blocking and add them as a source to the glib main loop and it will poll them for you in the main event loop without having to mess about with threads.
You could avoid using threads by using gio_add_watch() which will invoke your callback function when there is data available on the channel.

What to do when waiting for a event to finish

gcc 4.4.3 c89
I have a event loop that runs in a separate thread.
My design is like this below, just sample code to help explain.
I need to somehow wait for the initialization to complete before I can make a call to the get_device_params.
I did put a usleep for 3 seconds just before the call to the get_device_params, but I don't really want to block.
Many thanks for any suggestions,
void* process_events(void *data)
{
switch(event_type)
{
case EVT_INITIALIZED:
/* Device is now initialized */
break;
}
}
int main(void)
{
/* Create and start thread and process incoming events */
process_events();
/* Initialize device */
initialize_device();
/* Get device parameters */
/* However, I cannot run this code until initialization is complete */
get_device_params();
return 0;
}
If this separate thread is a POSIX thread (i.e. you're on a typical UNIX platform), then you can use pthread conditional variables.
You call pthread_cond_wait() in the waiting thread. When the init thread finishes its work, you call pthread_cond_signal(). In my opinion that's a canonical way to wait for initialization in another thread.
I need to somehow wait for the initialization to complete before I can make a call to the get_device_params.
Since you apparently have some sort of a FSM inside the process_events(), and it why ever runs in a separate thread, you shouldn't do anything from the main thread with the device.
In other words, logically, call to the get_device_params(); should be placed inside the FSM, on the event that the device is initialized EVT_INITIALIZED which I presume is triggered by the initialize_device().
Alternatively, you can create second FSM (possibly in another thread) and let the process_events() (the first FSM) after it has finished its own processing, forward the EVT_INITIALIZED event to the second FSM. (Or initialize_device() could send the event to the both FSMs simultaneously.)
To me it seems (from the scarce code you have posted) that your problem is that you try to mix sequential code with an event based one. Rule of thumb: in event/FSM based application all code should run inside the FSM, being triggered by an event; there should be no code which may run on its own outside of the FSM.
If it were me, I would probably use a barrier. In main you can call pthread_barrier_init, indicating that you have 2 threads. Then, in main call pthread_barrier_wait, to wait on the barrier you initialized, after calling your device initialization function. Finally, in the device thread, after you initialize your device, you can call pthread_barrier_wait on the same barrier and when both threads are waiting, the barrier will have been satisfied, so both threads will continue. I find barriers easier to use than condition variables sometime, but I'm sure that's an issue of preference.

Creating a new thread (C, Windows)

OK, I'm a bit confused here. The following code works:
HANDLE CreateSideThread()
{
DWORD dwGenericThread;
HANDLE hThread1 = CreateThread(NULL, 0, CallBackFunc, NULL, 0, &dwGenericThread);
return hThread1;
}
int main()
{
HANDLE Thread1;
Thread1 = CreateSideThread();
WaitForSingleObject(hThread1, INFINITE);
SomeOtherFunction();
return 0;
}
The program does other things but you get the idea. It basically creates a new thread and executes whatever it is in CallBackFunc (which is an endless loop that check db status).
Now, if I remove WaitForSingleObject() then the program will not even try CallBackFunc once and execute SomeOtherFunction().
What's the point then of a thread? I mean, i'm confused here.
What I am trying to do is call that thread with the check for the database status and keep that thread going while I continue with my program, calling other functions.
What am I doing wrong?
Please post a sample snippet.
Thanks
Without the WaitForSingleObject, your call to SomeOtherFunction() probably returns quickly enough for the program to exit before the new thread even gets a chance to run once.
When a C program returns from its main() function, the runtime system calls exit() for you. This forcibly exits your program even if other threads are trying to run at the same time. This is in contrast to other languages like Java for example, where exiting the main thread will not exit the process until all other (non-daemon) threads have finished running too.
Threads are typically used for doing background work and freeing up the calling thread to do other things.
Normally, the behavior you describe (calling SomeOtherFunction()) is exactly what you'd want: I am going to kick of a background 'job' and go about my life.
It would appear that your example is just fine - though if you merely return from main() your thread will of course terminate (as it's owned by the parent process).
Maybe some more detail on why what you're doing isn't what you expect to happen?
What you're finding is that the main thread completes before you notice CallbackFunc is called. When you have the Wait call in, the main thread is blocked until the new thread finishes and so you see the thread func being executed.
Threads are not as cheap as you think, if you replace the SomeOtherFunction with something that takes a long enough time to run, you'll see your thread function being called even without the Wait call.
CallBackFunc will of course be called, but there is no guarantee, when your stared threads will be up and running. They will be working once, but its unpredictable when the start doing so. Thats the job and property of the systems scheduler. In your case they do not anything when the second function is already called.

Resources