What is C's analogy to LabVIEW's Event Structure? - c

One programming construct I use quite a bit in LabVIEW is the Event Structure. This gives me the benefit of not having to needlessly waste CPU cycles via polling but only perform actions when an event I'm interested in is generated.
As an experienced LabVIEW programmer with a decent understanding of C, I'm curious how one would go about emulating LabVIEW's event structure in C; preferably under Linux. A small code sample (like the one in the link above) illustrating how this might be done would be much appreciated. Also, if there already exists 3rd party libraries (for Linux) to add this event framework to C, that would be nice to know as well. Thanks.

The Event Structure is really just an abstraction that hides the thread of execution from you. There has to be some code running somewhere on the computer that is checking for these events and then calling your event handlers. in C, you'd be expected to provide this code (the "main loop" of the program) yourself. This code would check the various event sources you are interested in and call your event handler functions.
The trick then becomes how to not have this main loop wildly spinning the CPU. One easy trick is to have the main loop sleep for a period of time and then check if any events need to be handled, and then sleep again. This has the downside of introducing latency. A better trick, when applicable, is to have the Operating System do these checks as part of its normal operations, and then wake your application's main loop up when something interesting happened. In Linux, this is done with the 'select' system call, but select has the limitation that it can only specify a resource that can be associated with a file descriptor, so devices, stdin, files, network ports are fine.
Edit: To clarify for my downvoters: I am not denying the existance of hardware interrupts. Yes, in cases where code has direct access to hardware interrupts for all events that it wishes to handle (such as an embedded system or device driver) you can write truly "event driven" code with multiple entry points that does not busy wait or sleep. However, in a normal application level C program running under Linux, this code architecture does not literally exist but is emulated at the application level. Any Linux application is going to have a main loop, and at least one thread of execution. This thread may get paused by the scheduler, but it always exists and always has an instruction pointer at a particular instruction. If the code leaves the main() the program ends. There is no facility for the code to return from main and get a callback later on from the kernel. The code has a single entry point and must call its various event handlers manually. Other than in a device driver (or very specific system code using signals), you can not have the kernel or hardware automatically call a certain function if the user clicked on a certain menu item, instead your code is running, detects this event itself, and calls the correct event handler.
You can tell LabView "Call this function when XX happens". In C, you tell your own event dispatch code "Call this function when XX happens".
What I'm trying to say (poorly?) is that the Event framework architecture is not native to a C / Linux application. It must be emulated by your code by having a main dispatch thread that gives the appearance of an event driven framework. Either you do this manually, or use an event library that does this behind the scenes to give the appearance of an event driven model. LabView takes the second approach, so it appears that no code is running when no events are happening, but in reality there is LabView's own C++ code running managing the event queues. This doesn't mean that it is busy waiting all the time, as I said before there are system calls such as select and sleep that the code can use to yield cpu time when it has no work to do, but the code can not simply stop executing.
Lets say you want to write an "event driven" program with two event handlers. One that gets called every ten seconds called tick() and one that gets called every time a key gets pressed called key(), and one that gets called everytime the word "foobar" gets typed called foobar(). You can define these three event handlers, but in addition you need some dispatch main thread that basically does
while not quitting
If 10 seconds have elapsed, call tick()
If Key has been Pressed
call key()
add save the key to our key buffer
If buffer now contains "foobar" call foobar() and clear buffer
Wait()
If all of the events you care about are system level events or time level events, you can Wait() can simply be telling the kernel 'wake me up when one of these things happens' so I don't need to 'busy wait', But you can't simply tell the Kernel "call foobar() when "foobar is pressed". You have to have application level dispatch code that emulates the Event Structure. You're C program only has a single entry point from the kernel for each thread of execution. If you look at libraries that provide event dispatch models, such as Qt, you will find that they are working like this under the hood.

I like libev for this sort of thing.

Most GUI toolkits (GTK, Qt, etc.) implement their own abstraction of an event loop. I've pastebinned a sample program here, because it was a bit long to include in the answer. It's a port of the LabVIEW example you mentioned to C using the GTK toolkit, because that's the one I'm familiar with. The basics of the event loop are not much different in other toolkits, though.

If all you care about is keyboard input, C standard I/O is what you want. By default input streams are buffered and will stall your program until input is received. Use scanf, getchar, whatever else in <stdio.h>.
If you want mouse input, you'll need to be more specific about your platform as C/C++ has no native support for the mouse or windows.

A good analogy to LabVIEWs event structure is Win32's "event pull" function GetMessage(). GetMessage() waits forever until a GUI event occurs. There are much more events, even for every child window (LabVIEW: control or indicator) in Windows than in LabVIEW. GetMessage() simply returns on every event, fine filtering (as in LabVIEW) has to be done later, typically using DispatchMessage() and the Window's event handler procedure WindowProc() with its more or less large switch() statement.
Most tookits use "event push" style which is not adaequate to the event structure. Interrupt driven programs too.
If a timeout is used, think that MsgWaitForMultipleObjects() with zero file handles is called before PeekMessage(). The timeout case applies when no event arrived in the given time span.
Actually, LabVIEWs event structure should be inside a separate loop. A separate loop is a thread. For typical Win32 programming, GetMessage() is used in the main thread, and additional ("worker") threads are generated by user interaction as needed.
LabVIEW cannot easily create a thread. It is only possible by invoking an asynchronous SubVI. Really! Therefore, most LabVIEW programs use a second while loop as a permanently available worker thread that will run when something has to be done and block (i.e. stop consuming CPU power) otherwise. To instruct what has to be done in background, a queue is used.
As a bad side effect, when the worker thread does something, the user cannot do something else in background as there is only one worker thread.
The LabVIEWs event structure has a big difference to other programming languages: LabVIEW events can have multiple consumers! If multiple event structures are used, everything continues to work well (except for events with boolean return values). In Windows, events are posted to a specific thread, mostly to a Windows' thread. To feed multiple threads, events have to be posted multiple times. Similar to other programming languages. Events there are handled by something similar to LabVIEWs “Queue” related functions: If someone receives the event, it is out off the queue.
Multiple-targetting require that every consumer registers itself somehow to the producer. For GUI events, this is done automatically. For user events, this must be done programmatically. See LabVIEW examples.
Distributing events to multiple listeners is realized in Windows using DDE but that's merely for processes than for threads. Registering to a thread is done using DdeConnect() or similar, and events are pushed to a callback function. (To be more exact how Win32 works, GetMessage() receives DDE messages, and DispathcMessage() actually calls the callback function.)

Related

How to create a non single-shot timer in C?

I need to use a non single shot Timer (such as QTimer from the Qt library) in a C code for embedded Linux (by no single shot Timer I mean one that triggers once ever x seconds indefinitely till a "stop timer" is called, not one that triggers only once or one that blocks the code while it's counting).
Some libraries that are available to me do implement such a timer using signal handlers, but I would like to avoid using such a system (I learned that is not the best solution). I know I can emulate what I want with single shot Timers by restarting the timer (calling it again) once it's finished, and that is an acceptable solution (actually the libraries I talked about work that way), but I don't know how to implement that without blocking the running code till the timer is triggered.
And one more thing: I need to be capable of implementing more then just one of them (here is where signal handlers stop being a viable solution AFAIK).
So how could I do such a solution? The closes to what Qt's QTimer has to offer, the better!
If you do need an unspecified number of triggers at varying intervals/times, a dedicated timer thread (as described by nneonneo in another answer) has the least number of pitfalls in my experience.
Timers are a limited resource (the number of timers available is configurable, and varies from system to system, so you cannot make any sweeping statements like "I'm sure there's enough for my purposes").
Signals interrupt blocking syscalls unless SA_RESTART flag is used; even then there are a few exceptions (see man 7 signal, Interruption of system calls and library functions by signal handlers chapter for details).
A dedicated timer thread is built around two components:
A queue, list, tree, or heap holding all timer events
A typical implementation only needs to know when the next event occurs, so a min-heap or a priority queue works quite well. I've found a min-heap to be simple and robust to implement, and efficient enough (O(log N) time complexity for both inserts and deletes); using absolute times (using CLOCK_MONOTONIC in Linux) for the events as keys.
Note that if you use the timer events as timeouts, you'll also need to make sure cancelling an event is efficient. In normal operation, timeouts are rare, so something like a web server is likely to cancel just about all the timeouts it sets, without any of them actually ever triggering.
A thread that waits for either the next event, or another thread inserting a new timer event
Personally, I use an array to hold the min-heap of events, protected by a pthread_mutex_t, with a pthread_cond_t for other threads to signal on after adding a new event. Then, it's a simple matter to use pthread_cond_timedwait() to wait/sleep for either the specified time, or until a thread notifies of a new event, whichever happens sooner.
When the next event occurs -- note that due to scheduling, you might find more than one separate event to occur, so you might not wish to sleep at all (but you might still check if new events were added) --, you perform the event. If the event is periodic, you reinsert it into the heap/queue, too, primed for the next time.
Choosing how events are performed is very important, and really, the only truly tricky bit. You can use flags -- switching from zero to nonzero is safe in practice, even if the change is not atomic, as long as you don't rely on any specific nonzero value --; you can cause a condition variable to be signaled or broadcast on; you can post a semaphore; you can raise a specific signal in a specific thread (even an empty signal handler will cause blocking I/O calls to interrupt, if the handler is installed without SA_RESTART flag; I've used this as an I/O timeout quite successfully); you can even use __atomic or __sync to modify a value atomically if using GCC (or Intel CC, Pathscale, or Portland Group C compilers); and so on.
If you need a specific function to be called, I recommend using a separate thread (or, if most of the work in the application/program/game is done in these timer events, a thread pool) to execute the events. This keeps the timer thread simple and precise, while keeping all resource use easily controlled. The worker thread or thread pool should simply have a FIFO queue of events protected by a mutex and a condition variable, so that the timer thread can add each event to the queue and then signal on the condition variable to notify the (next) worker thread that work is available.
Indeed, in the couple of instances I used other event action models, I now believe the function worker model would have been easier. Especially if you make the worker functions to take a pointer (to a structure), defined by the caller, so that they all have the same signature, this interface becomes quite straightforward to implement, but extremely powerful and versatile.
There is one downside to the timer-thread plus worker-thread(s) approach, and that is the (minimal) added latency. The worker thread will not get the work at the appointed time, but a short while afterwards. However, if you have the worker thread get the current time, compare to the (un-adjusted) target time, and use that as a statistic to trigger the events correspondingly prior to the target time, you can typically take care of this issue. (I have not verified, but I do believe both Qt and GTK+ toolkits do continuously estimate this latency in a similar if not same manner.)
Questions?
You have several options, none of which require any libraries beyond the standard C and POSIX libraries.
POSIX timers API, e.g. timer_create and friends. These have flexible notification scheme based on sigev, which allows you to specify how you want to be notified (signal to a specific thread, creation of a new thread, or arbitrary signal). By specifying that the signal goes to a specific thread, you can set that thread up to be ready for async signals, and use sig_atomic_t to signal work to be done by the thread. The most interesting notification option is to use the creation of a brand new thread, but note that this can get expensive if the timer fires frequently.
Linux timerfd API, e.g. timerfd_create. These create timers that you can poll with poll or epoll, enabling you to add the timers to a low-level event loop, as well as operate on them in a perfectly thread-safe and signal-safe way.
alarm. This uses the SIGALRM asynchronous signal, so again you'll want to use sig_atomic_t and a signal-processing thread to handle the timer.
select, poll, or nanosleep on a dedicated timer thread: This is what QTimer usually does under the covers. You simply create a dedicated timer thread and have the thread repeatedly sleep. To keep the timer on schedule, you adjust the sleep time based on the length of each processing cycle.
The last option is the most portable, but also basically the most work (since you're implementing the timer yourself). The upshot is that you get to customize the "timer" completely since you're implementing it on top of a sleep primitive.

Glib hash table issues with signal handling code

I've got some system level code that fires timers every once in a while, and has a signal handler that manages these signals when they arrive. This works fine and seems completely reasonable. There are also two separate threads running alongside the main program, but they do not share any variables, but use glib's async queues to pass messages in one direction only.
The same code uses glib's GHashTable to store, well, key/value pairs. When the signal code is commented out of the system, the hash table appears to operate fine. When it is enabled, however, there is a strange race condition where the call to g_hash_table_lookup actually returns NULL (meaning that there is no entry with the key used to look it up), when indeed the entry is actually there (yes I made sure by printing the whole list of key/value pairs with g_hash_table_foreach). Why would this occur most of the time? Is GLib's hash table implementation buggy? Sometimes the lookup call is successful.
It's a very particular situation, and I can clarify further if it didn't make sense, but I'm hoping I am doing something wrong so that this can actually be fixed.
More info: The code segments that are not within the signal handler scope but access the g_hash_table variable are surrounded by signal blocking calls so that the signal handler does not access these variables when the process was originally accessing them too.
Generally, signal handlers can only set flags and make system calls
As it happens, there are severe restrictions in ISO C regarding what signal handlers can do, and most library entry points and most API's are not even remotely 100% multi-thread-safe and approximately 0.0% of them are signal-handler-safe. That is, there is an absolute prohibition against calling almost anything from a signal handler.
In particular, for GHashTable, g_hash_table_ref() and g_hash_table_unref() are the only API elements that are even thread-safe, and none of them are signal-handler safe. Actually, ISO-C only allows signal handlers to modify objects declared with volatile sig_atomic_t and only a couple of library routines may be called.
Some of us consider threaded systems to be intrinsically dangerous, practically radioactive sources of subtle bugs. A good place to start worrying is The Problem with Threads. (And note that signal handlers themselves are much worse. No one thinks an API is safe there...)

Any good C implementation of the async-future model in C++11 or the async-await in C#?

My project has a quit a few places that need to handle the asynchronies. So I want to learn how the asynchrony can be implemented in C.
I've done some asynchronous programming "back in the day".
The approach I used was to represent each asynchronous operation as a HANDLE, using a manual-reset event if the operation did not have an inherent HANDLE. Then I made a single main loop for the application that essentially just calls WaitForMultipleObjects and executes completion callbacks.
There are several problems with this approach:
It is quite resource-intensive. Manual-reset event wrappers are needed quite a bit.
It is strictly single-threaded. However, you could modify the approach to make use of thread pools; when I developed my asynchronous programs "back in the day", the OS did not yet provide a thread pool.
It is limited to 64 outstanding asynchronous operations. I did run into this limitation, and wrote what I called an "event demultiplexer" to work around it. Essentially, you just add threads as necessary, with child threads sharing a "notification" HANDLE that is always in the 64 HANDLEs waited on by the main thread.

Ruby C Extension: run an event loop concurrently

I'm implementing a simple windowing library as a Ruby C extension. Windows have a handle_events! method that enters their native event loop.
The problem is that I want one event loop per window and the method blocks. I'd like the method to return immediately and let the loop run in a separate thread. What would be the best way to achieve this?
I tried using rb_thread_call_without_gvl to call the event loop function, and then use rb_thread_call_with_gvl in order to call the window's callbacks, which are Procs. Full source code can be found here.
It still works, but not as I intended: the method still blocks. Is this even possible with Ruby's threading model?
I had the very same problem to solve. And as rb_thread_call_with_gvl() was marked as experimental in 1.9.2 and it was not an exported symbol, I toke a different approach:
I called the blocking handle_event! function from a separate thread. I used a second ruby thread, that blocked on a message queue. While blocking on the message queue, the gvl was released with rb_thread_blocking_region().
If now the thread calling handle_event! was unblocked due to an event, it pulled all required information for the Proc's upcall together in a queue element and pushed that element onto the queue. The ruby thread received the element, returned from rb_thread_blocking_region() and thus reacquired the gvl and call the Proc with the information from the received element.
Kind regards
Torsten
As far as I understand, using rb_thread_call_with_gvl() still needs to be done on the same thread. i.e.: it's about releasing and taking the global lock, not really about changing threads. For example, a long running gzip function can run without the lock so that other ruby threads can run in parallel.
If you want your Procs called back on another thread, shouldn't you need to create a ruby thread for those Procs? Then on that thread, call out using rb_thread_call_without_gvl() to not hold the GVL (allowing other ruby threads to run), then when you have an event on the secondary window thread, call rb_thread_call_with_gvl() to grab the lock and then you should be right to call the Proc on that same thread.
That's the way I understand it... (not having done the C extension stuff very long.)

Scintilla and thread safety

I'm using the Scintilla edit control on Windows (Win32, C/C++) . The control is created in WndProc. I have a second thread, created with Boost.Thread, that act as a spell checker and marks with red squiggle incorrectly spelled words. Therefore, I have two threads altering the content of the Scintilla control.
At first, the program was crashing when editing text. So I researched Scintilla for thread safety. I found little information, but I manage to get this quote in the documentation:
direct calling will cause problems if
performed from a different thread to
the native thread of the Scintilla
window in which case
SendMessage(hSciWnd, SCI_*, wParam,
lParam) should be used to synchronize
with the window's thread.
Of course, I'm using direct calls, accordingly I change all calls in the spell check thread to SendMessage and now the program doesn't crash anymore.
Finally, and that's the question, have I solved the problem, or am I going to encounter other quirks with Scintilla and multithreads?
You should generally access windows (HWNDs) in Windows only from the thread they were created in. Any message sent to the window will be performed in the thread that created it, that's why the crashes stopped happening when you replaced all direct calls to the Scintilla functions by sending messages. If you use SendMessage() in your spell check thread this will cause the following to happen:
the spell check thread will block
a context switch to the GUI thread will be performed
the message loop will process the message (but not necessarily immediately, messages in the queue will be handled in the order they were added, so the message will be handled only after all previously added messages have been handled)
a context switch to the spell check thread will be performed
the SendMessage() call returns the result
So you have indeed fixed the problem, but at a very high price. Every misspelt word will cause two thread context switches, and the spell checking will block for each misspelt word. This could actually be quite a long time, if any other messages that take long to handle were still queued up.
You should change the design of your program. Ideally both threads will be able to work independently, and this can be achieved by adding a thread-safe data structure that the spell check thread adds information about misspelt words to, and that the main thread retrieves the information from. Boost has lots of classes to help you out. By doing so you can continue to use the direct calls, since they will be performed in the context of the main thread. Performance should improve, as multiple words could be underlined in one go, causing only a single repaint of the control. If you use PostMessage() instead of SendMessage() the spell check thread will be able to continue its work independently of the main thread being ready to handle the message.
If you remember to never call any Scintilla code from secondary threads you will not encounter other quirks. And this is nothing specific to the Scintilla control, calling Windows API functions that do not use Windows messages internally would be problematic for any other control just as well.

Resources