How can I write cross platform c++ that handles signals? - c++

This question is more for my personal curiosity than anything important. I'm trying to keep all my code compatible with at least Windows and Mac. So far I've learned that I should base my code on POSIX and that's just great but...
Windows doesn't have a sigaction function so signal is used? According to:
What is the difference between sigaction and signal? there are some problems with signal.
The signal() function does not block other signals from arriving while the current handler is executing; sigaction() can block other signals until the current handler returns.
The signal() function resets the signal action back to SIG_DFL (default) for almost all signals. This means that the signal() handler must reinstall itself as its first action. It also opens up a window of vulnerability between the time when the signal is detected and the handler is reinstalled during which if a second instance of the signal arrives, the default behaviour (usually terminate, sometimes with prejudice - aka core dump) occurs.
If two SIGINT's come quickly then the application will terminate with default behavior. Is there any way to fix this behavior? What other implications do these two issues have on a process that, for instance wants to block SIGINT? Are there any other issues that I'm likely to run across while using signal? How do I fix them?

You really don't want to deal with signal()'s at all.
You want "events".
Ideally, you'll find a framework that's portable to all the main environments you wish to target - that would determine your choice of "event" implementation.
Here's an interesting thread that might help:
Game Objects Talking To Each Other
PS:
The main difference between signal() and sigaction() is that sigaction() is "signal()" on steroids - more options, allows SA_RESTART, etc. I'd discourage using either one unless you really, really need to.

Related

Portable generic shared library setup with Qt event loop

We are trying to write a portable shared library that makes use of some Qt classes for convenience (mainly QTimer and QTcpSocket); no GUI stuff, though. The according signal/slot connections appear to require some Qt event loop, so we "prime" a QCoreApplication as outlined in this answer. Accordingly, we set up a worker object that does the heavy lifting and move it to a QThread.
The problem we run into now is that the queued connections between the QThread's owner object (within the main thread) and the worker object within the QThread seem to never get handled on Linux systems, at least as long as the program that implements our library does not provide any further Qt event loop of its own in the main thread. This is not very helpful, since the data passed from the worker to the main thread should be passed further using some callback functions, which now never get called, though.
My question is thus: is there a way to get an event loop to work in the library main thread without locking it or the host program up (which seems to be the case when just putting a QCoreApplication::exec() or similar there)? Or will we have to set up a different inter-thread communication scheme (independent from Qt) in order to deal with these data transfers?
Since we do not know if the host software is going to run on a QApplication or not, ideally I'd also have a check for that before setting up a main thread event loop. Is a simple if(qApp != nullptr) enough for that?
P.S.: A few things I tried but which did not work for me, either:
Settings up a QEventLoop in a std::thread launched from the main thread (probably not working because still not in the main thread)
Setting up a QEventLoop in the main thread class and triggering its processEvents() function periodically using a QTimer (probably not working due to the missing event loop for the QTimer::timeout signal in the main function)
Starting the QCoreApplication in a std::thread (gives a run-time warning on Windows that QCoreApplication should be started in the main thread)
In Qt parlance, a callback is called Qt::DirectConnection. But of course those callbacks will run on your worker thread. But that’d be the case with any other library that uses callbacks, so Qt is not a problem here, and neither is your code: the basic idea has this property.
If the host application is not using an event loop (any event loop, not necessarily Qt’s), then there’s nothing you can do other than polling – see below.
If the host application runs an X11 event loop, then you need to ensure that your copy of Qt is using the same underlying event loop as the host application. Usually, this would be the glib’s event loop, and then it should work automagically. Otherwise, you’ll need to pass to the user the file descriptor of the synchronization primitive used by Qt’s event loop, and the user will need to integrate it into their event loop. You’ll face the same problem whether you use Qt or not: rolling your own communication method won’t fix it, since you still need a waitable primitive that will interoperate with whatever event loop the user is using.
The user can of course poll for callbacks whenever they feel like it: expose a mainPoll() method that forwards to QCoreApplication::processEvents().
Despite accepting another answer (which I deem more correct), I'd still like to mention a workaround that worked surprisingly well: We actually managed to get around the event loop/thread problems on most systems by connecting the worker thread signals with lambda functions in constructor of the class that sets up the worker.
Now, I doubt that this behaviour is properly thread-safe, and having relatively lengthy lambda functions declared in connect function calls is certainly not good style. But in case anyone else ends up struggling with this issue, this may be a short-term solution or (temporary) workaround.

Signals instead of exceptions

Let's suppose we are developing a store, and, depending on the session state, the user is allowed to do different things. For example, suppose a widget must be blocked during a while in some specific moment, because some specific user actions, and the user tries again.
Of course, the most obvious implementation will be launching an exception in the corresponding function (the specific event handler), to say the action is currently blocked. That's similar to a concrete problem of mine. In that case, it was more convenient for me, instead of throwing an exception, make the function a "no-op", but emiting a boost::signal2's signal. The GUI does whatever he wants to do, inform the user or whatever. But perhaps the GUI only wants to inform the user once, so, it just disconnect to the signal after the first call.
And I liked it. It's pretty beautiful and elegant: to make it a no-op and emit a signal. No stack unwinding, functions can be marked as noexcept, you enable more optimizations in consequence, and you deal with the excepcional cases only when you want, connecting and desconnecting to the signals as wished.
Now it comes the question, what if I want to generalize the method substituting each exception for signals? even for non-GUI applications?
In that case, are boost::signals2 more inneficient than exceptions? Because it's a common hearing that try/catch blocks, no-noexcept functions, and stack unwinding causes overhead and avoid the compiler do a lot of possible optimizations. On the other hand, boost::signals2 is thread-safe, which causes extra overhead.
Is it my idea a bad idea at all?
I hope my question is not close for being "too broad" or "opinion-based", because its a question of design (and optimization) after all; although not too much specific, I have to admit.
Note: The GUI is a website. The thing is, I'm using Wt, a library to do websites in C++, which translate a hierarchy of widgets and signals to HTML/Javascript/Ajax, and my long-term project is to create a suite for creating GUIs in both, desktop/mobile (Qt) and web (Javascript) from a common infrastructure with an unique C++ back-end. Wt allows a mapping between C++/Javascript slots for a same event; for example, a click: if Javascript or Ajax is not available, the event is sent to the server and the C++ slot is called. If it is available, the event is executed on the client using the Javascript version. In case a same (GUI) event has more than one slot, the order of execution of slots is unspecified, and if both slots are C++ calls, they could be even executed in parallel on the server if there's enough threads available in the thread pool.

Qt signals (QueuedConnection and DirectConnection)

I'm having trouble with Qt signals.
I don't understand how DirectConnection and QueuedConnection works?
I'd be thankful if someone will explain when to use which of these (sample code would be appreciated).
You won't see much of a difference unless you're working with objects having different thread affinities. Let's say you have QObjects A and B and they're both attached to different threads. A has a signal called somethingChanged() and B has a slot called handleChange().
If you use a direct connection
connect( A, SIGNAL(somethingChanged()), B, SLOT(handleChange()), Qt::DirectConnection );
the method handleChange() will actually run in the A's thread. Basically, it's as if emitting the signal calls the slot method "directly". If B::handleChange() isn't thread-safe, this can cause some (difficult to locate) bugs. At the very least, you're missing out on the benefits of the extra thread.
If you change the connection method to Qt::QueuedConnection (or, in this case, let Qt decide which method to use), things get more interesting. Assuming B's thread is running an event loop, emitting the signal will post an event to B's event loop. The event loop queues the event, and eventually invokes the slot method whenever control returns to it (it being the event loop). This makes it pretty easy to deal with communication between/among threads in Qt (again, assuming your threads are running their own local event loops). You don't have to worry about locks, etc. because the event loop serializes the slot invocations.
Note: If you don't know how to change a QObject's thread affinity, look into QObject::moveToThread. That should get you started.
Edit
I should clarify my opening sentence. It does make a difference if you specify a queued connection - even for two objects on the same thread. The event is still posted to the thread's event loop. So, the method call is still asynchronous, meaning it can be delayed in unpredictable ways (depending on any other events the loop may need to process). However, if you don't specify a connection method, the direct method is automatically used for connections between objects on the same thread (at least it is in Qt 4.8).
in addition to Jacob Robbins answer:
the statement "You won't see much of a difference unless you're working with objects having different thread affinities" is wrong;
emitting a signal to a direct connection within the same thread will execute the slot immediately, just like a simple function call.
emitting a signal to a queued connection within the same thread will enqueue the call into the threads event loop, thus the execution will always happen delayed.
QObject based class has a queued connection to itself
Jacob's answer is awesome. I'd just like to add a comparative example to Embedded Programming.
Coming from an embedded RTOS/ISR background, it was helpful to see the similarities in Qt's DirectConnection to Preemptive behavior of the ISRs and Qt's QueuedConnection to Queued Messages in an RTOS between tasks.
Side note: Coming from an Embedded background, it's difficult for me to not define the behavior in the programming. I never leave the argument as Auto, but that is just a personal opinion. I prefer everything to be explicitly written, and yes that gets difficult at times!

Make Control-C behave like uncaught exception

Is there a way to make Control-C act like an exception was thrown. i.e. basically the program exits, but on the way up all the destructors are called?
Well, you need a signal handler catch SIGINT (SIGTERM, HUP why not as well?). You don't want to use threads for something simple like this, so use the standard "self-pipe trick": write a byte (the signal value) to one end of a socketpair in your signal handler, and your main loop (there's always a select loop in there somewhere) will asynchronously read the value back. It's at that point you throw, run away, follow ordinary quit procedure, do whatever you like. Everything gets unwound and destructed just as if you were quitting for any other reason in your main application loop.
This is generally impossible or hard to do. I believe that on some systems, like GNU/Linux, you could do that if you supplied -fnon-call-exceptions -fasynchronous-unwind-tables flags to GCC (untested).
Other than the above, you have basically two options:
Either you set some sort of flag in your signal handler that you will check somewhere else to see if SIGINT has been delivered. This is useful for both *NIX and Windows platforms.
On *NIX, if you are using threads in your application already, you can handle SIGINT using, e.g., sigwait() in a separate thread as a synchronous event and force your whole application to terminate orderly.
I would suggest using the 2nd option as that is usable as general approach to the problem on Windows as well. Windows inject a thread into application that execute a user supplied handle for Ctrl-C or Ctrl-Break. If you use the 2nd option, your application will be IMHO more portable.

Function guaranteed to be called in C++ during abrupt termination or exit

What function in C++ is guaranteed to be called during abrupt termination or exit which can perform the clean up activity ..
Depending on what you mean by "abrupt termination" there are several different options:
Global destructors will be called upon normal termination (return from main, or call to exit()).
atexit() registers a function to be called on normal termination.
std::set_terminate registers a function that will be called when an exception is thrown but not caught, or when "exception handling has to be terminated for some other reason".
sigaction() registers functions to be called when your program receives signals, many of which will normally abruptly terminate your program. Signal handlers may be called when the program is in an internally-inconsistent state, and therefore are extremely limited in what they can do. For instance, they cannot do anything that might allocate memory. Also, this API is not available on Windows; there are equivalents but I am not familiar with them.
Note that all operating systems in common use provide at least one way to abruptly terminate your program that cannot be intercepted from your code. For instance, Unix has signal 9 (SIGKILL) which you can't register a handler for. This is a feature, not a bug. You, the user, need a way to make a process go away even if it has done everything in its power to make itself indestructible. Furthermore, no code can protect your process when the user's pet rabbit gnaws through the power cord on the computer. Because of this, it might be a better use of your time to design your program to recover from crashes cleanly, rather than trying to clean up when a crash happens. See this article on "crash-only design" for more about that.
Read about atexit here. However it will not be called in all cases (for example, calling abort will not trigger the function you registered with atexit).
You can implement your own signal handler, then all the signals will pass there and you can do whatever for each of them.
You are looking for set_terminate().
http://www.cplusplus.com/reference/std/exception/set_terminate/
There are other similar function in the same header, that are usable for complementary scenarios.
int main()
{
try
{
// all your code here
}
catch(...)
{
// cleanup
}
return 0;
}
What environment you're working in? by abrupt do you mean Ctrl+C or kill -9 signal?
On unix/linux you can mask some signals and provide handlers, but as far as I am aware, you cannot mask all signal (9 is an example of a signal that can't be masked, and it'll kill your process abruptly)
Some even lower level overriding on OS operation could be available, but I'm not familiar with that.
I am not an expert and I just know some few things about C++, but I know you can create handles in Unix and C in order to detect a concrete signal and then, execute a function and later, terminate the program by "exit(n)" for example.
You can do it using signal or sigaction, but the problem is that you only can use this method for any signal except SIGKILL or SIGSTOP.
Are you familiar with signal handling? I would recommend that you study that first and then come back with questions regarding it. It looks like a couple people have already alluded to it, but here is a good resource to check:
http://www.gnu.org/s/hello/manual/libc/Signal-Handling.html
Writing your own signal handlers will allow you to determine what you want to do when a particular signal is caught. As stated, there are some that can't be overridden, and for good reason. You don't want to let someone override kill -9 simply because a program that's impossible to kill could be created. However, a straight kill signal or something such as ctrl-c, ctrl-d, etc, can be caught and handled in the way of your choosing.
There is no function that captures all scenarios and works on all platfroms. If you need something for Windows you will have to handle SEH(Structured exception handling) as well. You will have to define and set handlers for various scenarios(SEH, C++ Exceptions, SIGABRT, Terminate etc.) that execute common cleanup code and. Check zack's response here for handling SIGABRT signals.
For SEH you can add a SE converter to handle SE excpetions and convert them to C++ exceptions, look at _set_se_translator for more information about how to handle SEH exceptions.
You can refer to this documentation for set_terminate handler and this is a good reference for set_unexpected.
You will have to write your own handler that will be called for every scenario.
In the end I would reccomend using some existing libraries for this purpose, I like crashrprt.