Is using timers/signals in c static libraries bad practice? - c

I'm building two static c libraries. Each of the libraries have a routine that needs to run once every second after calling mylib_init();
I implemented this in each library using setitimer, which uses the ITIMER_REAL resource and the SIGALRM signal.
void Start1msTimer()
{
struct itimerval new;
memset(&new,0, sizeof(new));
new.it_interval.tv_sec=1;
new.it_value.tv_sec=1;
signal (SIGALRM, OneSecTimeout);
setitimer (ITIMER_REAL, &new,NULL);
}
Ok so far so good everything was working.
Now I'm building a sample application that uses both of these libraries, and conflicts are arising. I have realized an application can only have one handler for each signal, and ITIMER_REAL can only be used for one timer, not both. So obviously things are not working now.
What would be a better way for me to implement the timing in each of my libraries?
In general, is it a bad idea to have any signal handlers inside of a library?

Yes, it's a very bad idea to "use up" application-level resources in a library, since the application developer using the library won't get a say in how the resources should be allocated.
And, as you discovered, you get interoperability problems when multiple libraries want to own the same resource.
One way to fix this is to factor out the requirement, have a function mylib_update() and document that the application must call it once a second. That leaves the question of how to implement such a timer-based updating to the application, where it belongs.

You could use threads + a syncronization method. Instead of writing a signal handler, you write a thread. Using a semaphore, you can even run your event thread either on timeout or on demand (ie the app calls a library function that post the semaphore).

Related

Non-blocking library API in C without threads

How can I implement a non-blocking library API in c, without the use of threads?
In short, I have a library that I wrote that issues some read/write calls via a serial controller in order to get data the client of the library needs. These calls to the serial device, via a proprietary driver, are blocking, and I can't change them.
Without the use of threads in my library, or writing a system service to co-exist with my library, is there any way to "wrap" my library API calls so they are non-blocking (i.e. like co-routines in python)? The desired end result is a simple, synchronous, non-blocking API call to query the status of the library with minimal wait involved.
Thank you.
Short answer: no.
You cannot change the delay as it is inherent to the operation requested (sending data takes a certain amount of time) so you cannot make the call shorter.
Therefore your choice is either to wait for a call to complete or not wait for it.
You cannot skip waiting for it without some sort of threading as this is how the processor exposes the abstraction of it doing two things at once (i.e. sending data on the serial port and continuing on with more code)... thus you will need threads to achieve this.
I think first of all you should change you lib to make all calls non-blocking. Here is good explanation Linux Blocking vs. non Blocking Serial Read
Most close technique to python's co-routines in C is Protothread. It implements simple cooperative multitasking without using threads
Its probably better to do this with threads in general.
However, there is a way that will work with limitations for simple applications.
Please forgive the use of a C++11 lambda, I think it makes things a little clearer here.
namespace
{
sigjmp_buf context;
} // namespace
void nonBlockingCall(int timeoutInSeconds)
{
struct sigaction* oldAction = nullptr;
struct sigaction newAction;
if (sigsetjmp(::context,0) == 0)
{
// install a simple lambda as signal handler for the alarm that
// effectively makes the call time out.
// (e.g. if the call gets stuck inside something like poll() )
newAction.sa_handler = [] (int) {
siglongjmp(::context,1);
};
sigaction(SIGALRM,&newAction,oldAction);
alarm(timeoutInSeconds); //timeout by raising SIGALM
BLOCKING_LIBRARY_CALL
alarm(0); //cancel alarm
//call did not time out
}
else
{
// timer expired during your call (SIGALM was raised)
}
sigaction(SIGALRM,oldAction,nullptr);
}
Limitations:
This is unsafe for multi-threaded code.
If you have multi-threaded code it is better to have the timer in a
monitoring thread and then kill the blocked thread.
timers and signals from elsewhere could interfere.
Unless BLOCKING_LIBRARY_CALL documents its behaviour very well you may be in undefined behaviour land.
It will not free resources properly if interrupted.
It might install signal handlers or masks or raise signals itself.
If using this idiom in C++ rather than C you must not allow any objects to be constructed or destroyed between setjmp and longjmp.
Others may find additional issues with this idiom.
I thought I'd seen this in Steven's somewhere, and indeed it is discussed in the signals chapter where it discusses using alarm() to implement sleep().

C: How to make threads communicate with each other?

Interesting that this seems to be a basic question, and yet I couldn't find any example of it for the C language (in SO, I found only for Python, C# and C++).
The point is: as a Qt programmer, when I need to make some data to be transmitted between different threads, I start a signal-slot connection between then and use the emit signal mechanism to do the work.
But now I'm working in a C application for Embedded Linux where I need to do a similar work, but I don't have Qt's mechanism available. The question is: how can I make two or more threads communicate with each other in C in a manner similar to that of Qt with signals and slots?
I know that one of the ways to share data is with global variables with changes protected by mutexes. But even then I would probably be unable to do the system in a asynchronous way: I would have to have a loop that would constantly check if the variable has changed or not. But what if I want to execute a specific method of a thread just after another one finished some work (so, in an asynchronous way)? Then it seems such way fails.
Note: although I'm using Embedded Linux and, therefore, mentioning some options that would take POSIX functions and other "Linux-related ways" would be helpful, it would still be better for the community if more time is given to solutions that are not based strictly to one specific platform (if that is possible).
Read a good tutorial on pthreads. You want to know more about condition variables to be used with mutexes.
Condition variables and mutexes should probably be enough for your needs.
You could also use most traditional inter-process communication mechanisms between threads, e.g. a pipe(7) (probably with poll(2)...). So read Advanced Linux Programming and study syscalls(2) and pthreads(7)
Avoid using signal(7)-s between threads and be aware of signal-safety(7). See however signalfd(2), eventfd(2), userfaultfd(2) (you might cleverly handle SIGSEGV with it) and take inspiration from the approach suggested by Calling Qt functions from Unix signal handler.
Observe a running multi-threaded Linux process with strace(1), ltrace(1), gdb(1). You'll understand that several pthreads(7) primitives are using futex(7).
Both GNU glibc and musl-libc are open source and implement the pthreads specification (and Glib, GTK, Qt or POCO are built above them). I invite you to study their source code.
One way is to use message passing between threads via asynchronous queues. This way you can avoid using shared data between threads and only the queues need to be thread-safe.
Asynchronous queues can be implemented using different synchronisation primitives:
Pipes or sockets.
Queues protected with a mutex and a condition variable.
Non-blocking or lock-free queues.
Thread which you want to notify of an event like "data available" can register a callback function which can be trigerred by the notifier thread. You can use a function pointer for this.
Ex: Thread 2 registers a callback function for one or more events. Thread 1 on occurrence of the condition or event calls the registered function.
producer and consumer threads should capture each other's tid. producer on producing can send:
pthread_kill(consumerID, SIGUSR1);
consumer is setup with the signal handler for SIGUSR1, and can retrieve the produced result from the common std::queue saved by pthread_setspecific().
producer and consumer can continue their tasks without being locked by semaphore or cond var/mutex.

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.

Signals and slots in GTK

I have used Signals and slots in Qt and I want to implement same stuff in GTK+.
I have 2 threads in which I need to pass data. I have done it using signals and slots in Qt but now I have to implement this same stuff in GTK+ and C. How should I do it?
Here's a general tutorial for the signal/event mechanism without threads.
When using threads, you'll have to make sure to
init the Gtk main loop for threads by calling g_thread_init() and gdk_threads_init().
use gdk_threads_add_idle() or
use GDK_THREADS_ENTER() and GDK_THREADS_LEAVE() in the callback (= event handler).
There are probably hundreds of tutorials for threading in Gdk out there, so I'll leave it at that.
GTK/GLib has its own signal mechanism.
Qt does some of its own stuff behind the scenes to make signal/slot connections threadsafe. The last I was working with GTKmm, that wasn't the case for GTK. That being the case, you'd probably have to do up your own, or (my recommendation) use boost if you can. If you do have to roll your own, you'll want to have an event posting/polling mechanism. They aren't overly complex, but are enough of a pain you should definitely prefer pre-built solutions.

Asynchronous APIs

When trying to implement an asynchronous API calls / Non-blocking calls, I know a little in a All Plain-C application I have, I read a about APM (Asynchronous Programming Model) by 'Delegates'. Basically what I want to do is call one API f1() to do a functionality(which takes long time 8-10 seconds), So I call that API f1(), forget about it, and continue doing some other work, e.g. I/O for to fetch data for next call of the f1() or some functionality not dependent on result of f1().
If any one has used that APM model of programming, I am looking at some concise explanation for implementing non-blocking calls.
Is there any other way of implementing asynchronous APIs , any other library/framework which might help in this?
You basically need to create a multi-threaded (or multi-process) application. The f1() API needs to spawn a thread (or process) to process the data in a separate execution space. When it completes, the f1() routine needs to signal the main process that the execution is done (signal(), message queues, etc).
A popular way to do asynchronous programming in a plain C programs is to use an "event loop". There are numerous libraries that you could use. I suggest to take a look at
glib.
Another alternative is to use multiple pre-emptive threads (one for each concurrent operation) and synchronize them with mutexes and condition variables. However, pre-emptive threading in plain C is something I would avoid, especially if you want to write portable programs. It's hard to know which library functions are re-entrant, signal handling in threaded programs is a hassle, and in general C libraries and system functions have been designed for single-threaded use.
If you're planning to run your application only on one platform (like Windows) and the work done with f1() is a relatively simple thing, then threading can be OK.
If the function f1() which you are referring to is not itself implemented in a asynchronous fashion, you will need to wrap it up in its own thread yourself. When doing this, you need to be careful with regards to side effects that may be caused by that particular function being called. Many libraries are not designed in a thread-safe way and multiple concurrent invocations of functions from such libraries will lead to data corruption. In such cases, you may need to wrap up the functionality in an external worker process. For heavy lifting that you mention (8-10 seconds) that overhead may be acceptable. If you will only use the external non-threadsafe functions in one thread at a time, you may be safe.
The problem with using any form of event-loop is that an external function which isn't aware of your loop will never yield control back to your loop. Thus, you will not get to do anything else.
Replace delegates with pointers to functions in C, everything else is basically same to what you have read.
Well. Basically I've seen 2 types of async API:
Interrupt. You give a call a callback which should be performed after the call. GIO (part of previously mentioned GLib) works in such a way. It is relatively easy to program with but you usually have the thread in which the callback will be run changed (except if it is integrated with the main loop as in the case of GIO).
Poll. You check if the data is available. The well-known BSD Sockets operate in such a manner. It has an advantage of not necessarily being integrated with the main loop and running callback in a specific thread.
If you program for Gnome or Gtk+-based I'd like to add that GTask seems to be a very nice (potentially nice? I haven't used it). Vala will have better support for GIO-like async calls.

Resources