I tried to break down my problem to a small example. The real problem is a more complex communication:
I have a function that triggers a communication and connects and sends messages to a server. If there is an answer, the Client-class emits a signal containing the answer.
void communicate()
{
client.setUpMessage(); // the answer is emitted as a signal and
// and processed in the Slot
// 'reactToAnswer(...)'
client.sendMessage("HelloWorld");
}
void reactToAnswer(QString answer)
{
parser.parseAnswer() // an error could occur
}
What if an error is detected in the slot in which the response is processed? I would like to stop the execution of the function communicate(). This means that the function client.sendMessage("HelloWorld") should no longer be executed.
In my naivety I tried to handle the problem with exceptions:
void communicate()
{
try
{
client.setUpMessage(); // the answer is emitted as a signal and
// and processed in the Slot
// 'reactToAnswer(...)'
client.sendMessage("HelloWorld");
}
catch(myException)
{
// do something
}
void reactToAnswer(QString answer)
{
if( !parser.parseAnswer() )
{
throw myException;
}
}
This does not work, throwing an exception from a slot invoked by a qt-signal is undefined behaviour. The usual way is to reimplement QApplication::notify() resp. QCoreApplication()::notify, but this does not work for me. There is already a QApplication for the GUI and I want the communication class (QObject) to stand alone. All things should be treated within this class.
I hope I explained the problem comprehensibly. I do not want to use exceptions in any case, other ways to stop the communication are also right for me.
Thanks in advance!
I'm not sure that what you are trying to accomplish is a particularly good fit for the signals-and-slots paradigm... perhaps you want to go with just a regular old function call instead? i.e. something like:
void communicate()
{
QString theAnswer; // will be written to by setupMessage() unless error occurs
if (client.setUpMessage(theAnswer))
{
reactToAnswer(theAnswer);
client.sendMessage("HelloWorld");
}
}
The reason that signals-and-slots aren't a good fit is that signals are designed to be connectable to multiple slots at once, and the order in which the slots-methods are called is undefined -- so if a slot-method tries to interfere with the signal-emitting process in the way you describe, the behavior is rather unpredictable (because you don't know how many other connected slot-methods, if any, had already been called as part of the signal-emission, before your particular slot-method hit the brakes). And of course if you ever go to queued/asynchronous signals, then it won't work at all, because the slot will be called in a different context entirely, long after the signal-emitting function has already returned.
That said, if you absolutely must use signals-and-slots for this, you can have your slot emit its own error-has-occurred signal, which can be connected back to a slot in the original signal-emitting class. That slot could then set a boolean (or whatever), and your communicate() method could then check the state of that boolean (right after client.setUpMessage() has returned) to decide whether or not to continue executing or return early.
(I don't recommend that though -- signals-and-slots are there to make your program less complicated, and in this case I think using them instead of a regular function call actually makes your program more complicated, with no corresponding benefit)
Related
I'm writing a library with a C (not C++) interface that contains an event loop, call it processEvents. This should be called in a loop, and invokes user-defined callbacks when something has happened. The "something" in this case is triggered by an RPC response that is received in a different thread, and added to an event queue which is consumed by processEvents on the main thread.
So from the point of view of the user of my library, the usage looks like this:
function myCallback(void *userData) {
// ...
}
int main() {
setCallback(&myCallback, NULL);
requestCallback();
while (true) {
processEvents(); /* Eventually calls myCallback, but not immediately. */
doSomeOtherStuff();
}
}
Now I want to test, using Google Test and Google Mock, that the callback is indeed called.
I've used MockFunction<void()> to intercept the actual callback; this is called by a C-style static function that casts the void *userData to a MockFunction<void()> * and calls it. This works fine.
The trouble is: the callback isn't necessarily happen on the first call of processEvents; all I know is that it happens eventually if we keep calling processEvents in a loop.
So I guess I need something like this:
while (!testing::Mock::AllExpectationsSatisfied() && !timedOut()) {
processEvents();
}
But this fictional AllExpectationsSatisfied doesn't seem to exist. The closest I can find is VerifyAndClearExpectations, but it makes the test fail immediately if the expectations aren't met on the first try (and clears them, to boot).
Of course I make this loop run for a full second or so, which would make the test green, but also make it needlessly slow.
Does anyone know a better solution?
If you are looking for efficient synchronization between threads, check out std::condition_variable. Until a next event comes in, your implementation with a while loop will keep on spinning – using up CPU resources doing nothing useful.
Instead, it would make better sense to suspend the execution of your code, freeing up processing time for other threads, until an event comes in, and then signal to the suspended thread to resume its work. Condition variables do just that. For more information, check out the docs.
Furthermore, you might be interested in looking into std::future and std::promise, which basically encapsulate the pattern of waiting for something to come asynchronously. Find more details here.
After posting the question, I thought of using a counter that is decremented by each mock function invocation. But #PetrMánek's answer gave me a better idea. I ended up doing something like this:
MockFunction<void()> myMockFunction;
// Machinery to wire callback to invoke myMockFunction...
Semaphore semaphore; // Implementation from https://stackoverflow.com/a/4793662/14637
EXPECT_CALL(myMockFunction, Call())
.WillRepeatedly(Invoke(&semaphore, &Semaphore::notify));
do {
processEvents();
} while (semaphore.try_wait());
(I'm using a semaphore rather than std::condition_variable because (1) spurious wakeups and (2) it can be used in case I expect multiple callback invocations.)
Of course this still needs an overall timeout so a failing test won't hang forever. An optional timeout could also be added to try_wait() to make this more CPU-efficient. These improvements are left as an exercise to the reader ;)
This question already has answers here:
How to execute a functor or a lambda in a given thread in Qt, GCD-style?
(5 answers)
Closed 6 years ago.
I want to call object's slot in its own thread. In other word, to put slot processing into receiver's thread queue.
As I know, it could be done by using
QMetaObject::invokeMethod(objPtr, "someMethod", Qt:: QueuedConnection);
But as for me, this way is unsafe. Because there are no any compile-time checks about existence of method with such name. And in case of some mistype, error will occur only in runtime and only in logs.
Another way is to create dummy signal like
void callObj();
and connect this dummy signal to slot
connect(this, &Obj1::callObj, objPtr, &Obj2::someMethod, Qt:: QueuedConnection);
But this way is looks really bad.
So is there any way to do this?
Thanks in advance for help.
If you have definition of the interface you'll be calling against, you can use a single shot QTimer with 0ms timeout:
QTimer::singleShot(0, obj, &Class::slot);
you can also call it with a lambda
QTimer::singleShot(0, obj, [obj]{ obj->slot(42); } );
This approach requires the target thread to run its own event loop (i.e. QThread::exec()), but since you want to run slots in its thread I assume that's what you want.
It is not unsafe - nothing bad will happen, invokeMethod() will return false if the method doesn't exist. Check the return value to decide further course of action. It won't crash or anything like that.
You can use qobject_cast to make sure your pointer is of the right type, which should be enough to verify if it has the particular method. Other than that, take care not to mistype it and don't use untested code.
Also, consider that there are several other ways to leverage multithreading besides the implicit object thread affinity.
I wouldn't call the dummy signal approach "really bad" - it is just a hack, and hacks go hand in hand with Qt, as huge as the framework might be, it is far from fullproof.
Exception safety is really important in Modern C++.
There is already a great question about exception safety here.
So I am not talking about Exception safety in general. I am really talking about exception safety with Qt in C++. There is also a question about Qt Exception safety on Stack Overflow and we have the Qt documentation.
After reading everything I could find about exception safety with Qt, I really feel like it is very hard to achieve exception safety with Qt. As a result I am not going to throw any kind of exceptions myself.
The real problem is with std::bad_alloc:
The Qt documentation states that Throwing an exception from a slot invoked by Qt's signal-slot connection mechanism is considered undefined behaviour, unless it is handled within the slot.
As far as I know, any slot in Qt could throw a std::bad_alloc.
It seems to me that the only reasonable option is to exit the application before the std::bad_alloc is thrown (I really do not want to go into undefined behavior land).
A way to achieve this would be to overload operator new and:
if an allocation failure occures in the GUI thread: exit (kill) the application.
if an allocation failure occures in another thread just throw a std::bad_alloc.
Before writing that operator new I would really appreciate some feedback.
Is it a good idea ?
Will my code be exception safe this way ?
Is it even possible to write exception safe code with Qt ?
This problem has been long solved and has an idiomatic solution in Qt.
All slot calls ultimately originate either from:
an event handler, e.g.:
A timer's timeout signal results from the QTimer handling a QTimerEvent.
A queued slot call results from the QObejct handling a QMetaCallEvent.
code you have full control over, e.g.:
When you emit a signal in the implementation of main, or from QThread::run, or from QRunnable::run.
An event handler in an object is always reached through QCoreApplication::notify. So, all you have to do is to subclass the application class and reimplement the notify method.
This does affect all signal-slot calls that originate from event handlers. Specifically:
all signals and their directly attached slots that originated from event handlers
This adds a per-event cost, not a per-signal cost, and not per-slot cost. Why is the difference important? Many controls emit multiple signals per a single event. An QPushButton, reacting to a QMouseEvent, can emit clicked(bool), pressed() or released(), and toggled(bool), all from the same event. In spite of multiple signals being emitted, notify was called only once.
all queued slot calls and method invocations
They are implemented by dispatching a QMetaCallEvent to the receiver object. The call is executed by QObject::event. Since event delivery is involved, notify is used. The cost is per-call-invocation (thus it is per-slot). This cost can be easily mitigated, if desired (see implementation).
If you're emitting a signal not from an event handler - say, from inside of your main function, and the slot is directly connected, then this method of handling things obviously won't work, you have to wrap the signal emission in a try/catch block.
Since QCoreApplication::notify is called for each and every delivered event, the only overhead of this method is the cost of the try/catch block and the base implementation's method call. The latter is small.
The former can be mitigated by only wrapping the notification on marked objects. This would need to be done at no cost to the object size, and without involving a lookup in an auxiliary data structure. Any of those extra costs would exceed the cost of a try/catch block with no thrown exception.
The "mark" would need to come from the object itself. There's a possibility there: QObject::d_ptr->unused. Alas, this is not so, since that member is not initialized in the object's constructor, so we can't depend on it being zeroed out. A solution using such a mark would require a small change to Qt proper (addition of unused = 0; line to QObjectPrivate::QObjectPrivate).
Code:
template <typename BaseApp> class SafeNotifyApp : public BaseApp {
bool m_wrapMetaCalls;
public:
SafeNotifyApp(int & argc, char ** argv) :
BaseApp(argc, argv), m_wrapMetaCalls(false) {}
void setWrapMetaCalls(bool w) { m_wrapMetaCalls = w; }
bool doesWrapMetaCalls() const { return m_wrapMetaCalls; }
bool notify(QObject * receiver, QEvent * e) Q_DECL_OVERRIDE {
if (! m_wrapMetaCalls && e->type() == QEvent::MetaCall) {
// This test is presumed to have a lower cost than the try-catch
return BaseApp::notify(receiver, e);
}
try {
return BaseApp::notify(receiver, e);
}
catch (const std::bad_alloc&) {
// do something clever
}
}
};
int main(int argc, char ** argv) {
SafeNotifyApp<QApplication> a(argc, argv);
...
}
Note that I completely ignore whether it makes any sense, in any particular situation, to handle std::bad_alloc. Merely handling it does not equal exception safety.
You don't need something as complex as overloading operator new. Create a class ExceptionGuard whose destructor checks std::uncaught_exception. Create this object in each slot, with automatic duration, outside any try-catch block. If there's an exception that still escapes, you can call std::terminate just before you'd otherwise return to Qt.
The big benefit is that you can place it in just the slots, not every random call to new. The big downside is that you can forget to use it.
BTW, it's not strictly necessary to call std::terminate. I'd still advice to do so in ExceptionGuard because it's intended as a last resort. It can do application-specific cleanup. If you have cleanup behavior specific to the slot you'd better do that outside ExceptionGuard, in a regular catch block.
Is it a good idea ?
It's unnecessary and needlessly complex. There are a lot of problems with trying to handle std::bad_alloc:
when it is thrown, there typically isn't much you can do about it. You're out of memory, anything you try to do might easily fail again.
in many environments, out-of-memory situations might occur without this exception being thrown. When you call new the OS just reserves a part of your (huge, 64-bit) address space. It doesn't get mapped to memory until much later, when you try to use it. If you're out of memory, then that is the step that will fail, and the OS won't signal that by throwing a C++ exception (it can't, because all you tried to do was read or write a memory address). It generates an access violation/segfault instead. This is the standard behavior on Linux.
it adds complexity to a situation that might already be tricky to diagnose and debug. Keep it simple, so that if it happens, your code won't do anything too unexpected that ends up hiding the problem or preventing you from seeing what went wrong.
Generally speaking, the best way to handle out-of-memory situations is just to do nothing, and let them take down the application.
Will my code be exception safe this way ?
Qt frequently calls new itself. I don't know if they use the nothrow variant internally, but you'd have to investigate that.
Is it even possible to write exception safe code with Qt ?
Yes. You can use exceptions in your code, you just have to catch them before they propagate across signal/slot boundaries.
This is a pretty basic scenario but I'm not finding too many helpful resources. I have a C++ program running in Linux that does file processing. Reads lines, does various transformations, writes data into a database. There's certain variables (stored in the database) that affect the processing which I'm currently reading at every iteration because I want processing to be as up to date as possible, but a slight lag is OK. But those variables change pretty rarely, and the reads are expensive over time (10 million plus rows a day). I could space out the reads to every n iterations or simply restart the program when a variable changes, but those seem hackish.
What I would like to do instead is have the program trigger a reread of the variables when it receives a SIGHUP. Everything I'm reading about signal handling is talking about the C signal library which I'm not sure how to tie in to my program's classes. The Boost signal libraries seem to be more about inter-object communication rather than handling OS signals.
Can anybody help? It seems like this should be incredibly simple, but I'm pretty rusty with C++.
I would handle it just like you might handle it in C. I think it's perfectly fine to have a stand-alone signal handler function, since you'll just be posting to a semaphore or setting a variable or some such, which another thread or object can inspect to determine if it needs to re-read the settings.
#include <signal.h>
#include <stdio.h>
/* or you might use a semaphore to notify a waiting thread */
static volatile sig_atomic_t sig_caught = 0;
void handle_sighup(int signum)
{
/* in case we registered this handler for multiple signals */
if (signum == SIGHUP) {
sig_caught = 1;
}
}
int main(int argc, char* argv[])
{
/* you may also prefer sigaction() instead of signal() */
signal(SIGHUP, handle_sighup);
while(1) {
if (sig_caught) {
sig_caught = 0;
printf("caught a SIGHUP. I should re-read settings.\n");
}
}
return 0;
}
You can test sending a SIGHUP by using kill -1 `pidof yourapp`.
I'd recommend checking out this link which gives the details on registering a signal.
Unless I'm mistaken, one important thing to remember is that any function inside an object expects a referent parameter, which means non-static member functions can't be signal handlers. I believe you'll need to register it either to a static member function, or some kind of global function. From there, if you have a specific object function you want to take care of your update, you'll need a way to reference that object.
There are several possibilities; it would not necessarily be overkill to implement all of them:
Respond to a specific signal, just like C does. C++ works the same way. See the documentation for signal().
Trigger on the modification timestamp of some file changing, like the database if it is stored in a flat file.
Trigger once per hour, or once per day (whatever makes sense).
You can define a Boost signal corresponding to the OS signal and tie the Boost signal to your slot to invoke the respective handler.
I have found that boost::signals2 uses sort of a lazy deletion of connected slots, which makes it difficult to use connections as something that manages lifetimes of objects. I am looking for a way to force slots to be deleted directly when disconnected. Any ideas on how to work around the problem by designing my code differently are also appreciated!
This is my scenario: I have a Command class responsible for doing something that takes time asynchronously, looking something like this (simplified):
class ActualWorker {
public:
boost::signals2<void ()> OnWorkComplete;
};
class Command : boost::enable_shared_from_this<Command> {
public:
...
void Execute() {
m_WorkerConnection = m_MyWorker.OnWorkDone.connect(boost::bind(&Command::Handle_OnWorkComplete, shared_from_this());
// launch asynchronous work here and return
}
boost::signals2<void ()> OnComplete;
private:
void Handle_OnWorkComplete() {
// get a shared_ptr to ourselves to make sure that we live through
// this function but don't keep ourselves alive if an exception occurs.
shared_ptr<Command> me = shared_from_this();
// Disconnect from the signal, ideally deleting the slot object
m_WorkerConnection.disconnect();
OnComplete();
// the shared_ptr now goes out of scope, ideally deleting this
}
ActualWorker m_MyWorker;
boost::signals2::connection m_WorkerConnection;
};
The class is invoked about like this:
...
boost::shared_ptr<Command> cmd(new Command);
cmd->OnComplete.connect( foo );
cmd->Execute();
// now go do something else, forget all about the cmd variable etcetera.
the Command class keeps itself alive by getting a shared_ptr to itself which is bound to the ActualWorker signal using boost::bind.
When the worker completes, the handler in Command is invoked. Now, since I would like the Command object to be destroyed, I disconnect from the signal as can be seen in the code above. The problem is that the actual slot object is not deleted when disconnected, it is only marked as invalid and then deleted at a later time. This in turn appears to depend on the signal to fire again, which it doesn't do in my case, leading to the slot never expiring. The boost::bind object thus never goes out of scope, holding a shared_ptr to my object that will never get deleted.
I can work around this by binding using the this pointer instead of a shared_ptr and then keeping my object alive using a member shared_ptr which I then release in the handler function, but it kind of makes the design feel a bit overcomplicated. Is there a way to force signals2 to delete the slot when disconnecting? Or is there something else I could do to simplify the design?
Any comments are appreciated!
boost::signals2 does clean up the slots during connect/invoke.
So if all the slots disconnect themselves from the signal, invoking the signal a second time will not call anything but it should clean up the slots.
To answer your comment, yes, invoking the signal again is not safe if there are be other slots connected, as they will be invoked again. In that case I suggest you go the other way around and connect a dummy slot, then disconnect it when your "real" slot is invoked. Connecting another slot will clean up stale connections, so your slot should be released.
Just make sure that you don't keep any references that need freeing in the dummy slot, or you're back where you started.
This is an incredibly annoying aspect of boost::signals2.
The approach I took to resolve it is to store the signal in a scoped_ptr, and when I want to force disconnection of all slots, I delete the signal. This only works in cases when you want to forcefully disconnect all connections to a signal.
Is the behaviour any more strict with a scoped_connection?
So, rather than:
void Execute() {
m_WorkerConnection = m_MyWorker.OnWorkDone.connect(boost::bind
(&Command::Handle_OnWorkComplete, shared_from_this());
// launch asynchronous work here and return
}
...
boost::signals2::connection m_WorkerConnection;
Instead using:
void Execute() {
boost::signals2::scoped_connection m_WorkerConnection
(m_MyWorker.OnWorkDone.connect(boost::bind
(&Command::Handle_OnWorkComplete, shared_from_this()));
// launch asynchronous work here and return
} // connection falls out of scope
(copy-constructed from a boost::signals2::connection)
I've not used any sort of signalling so it's more of a guess than anything else, but following Execute() you wouldn't need to disconnect(), since scoped_connection handles it for you. That's more of a 'simplify the design' rather than actually solving your problem. But it may mean that you can Execute() and then immediately ~Command() (or delete the shared_ptr).
Hope that helps.
EDIT: And by Execute() then immediately ~Command() I obviously mean from outside your Command object. When you construct the Command to execute it, you should then be able to say:
cmd->Execute();
delete cmd;
Or similar.
I ended up doing my own (subset) implementation of a signal, the main requirement being that a slot should be destroyed by a call to connection::disconnect().
The implementation goes along the lines of the signal storing all slots in a map from slot implementation pointer to a shared_ptr for a slot implementation instead of a list/vector, thereby giving quick access to individual slots without having to iterate over all slots. A slot implementation is in my case basically a boost::function.
Connections have a weak_ptr to the internal implementation class for the signal and a weak_ptr to the slot implementation type to allow the signal to go out of scope and to use the slot pointer as the key into the signal map as well as an indication on whether the connection is still active (can't use a raw pointer as that could potentially be reused).
When disconnect is called, both of these weak pointers are converted to shared_ptrs and if both of these succeed, the signal implementation is asked to disconnect the slot given by the pointer. This is done by simple erasing it from the map.
The map is protected by a mutex to allow for multithreaded use. To prevent deadlocks, the mutex is not held while calling the slots, however this means that a slot may be disconnected from a different thread just prior to being called by the signal. This is also the case with regular boost::signals2 and in both of these scenarios one needs to be able to handle a callback from a signal even after one has disconnected.
To simplify the code for when the signal is fired, I am forcing all slots to be disconnected during this. This is different from boost::signals2, that does a copy of the list of slots before calling them in order to handle disconnections/connections while firing the signal.
The above works well for my scenario, where the signal of interest is fired very seldom (and in that case only once) but there are a lot of short-lived connections that otherwise use up a lot of memory even when using the trick outlined in the question.
For other scenarios, I've been able to replace the use of a signal with just a boost::function (thus requiring that there can only be a single connection) or just by sticking with the workaround in the question where the listener itself manages its lifetime.
I stumbled upon the same problem and i really miss some kind of explicit cleanup in the API.
In my scenario i am unloading some plug-in dll's and i have to assure there are no dangling objects (slots) which refer to code (vftables or whatsoever) living in the unloaded dll. Simply disconnecting slots didn't work due to the lazy deletion stuff.
My first workaround was a signal wrapper which tweaks the disconnecting code a little bit:
template <typename Signature>
struct MySignal
{
// ...
template <typename Slot>
void disconnect (Slot&& s)
{
mPrivate.disconnect (forward (s));
// connect/disconnect dummy slot to force cleanup of s
mPrivate.connect (&MySignal::foo);
mPrivate.disconnect (&MySignal::foo);
}
private:
// dummy slot function with matching signature
// ... foo (...)
private:
::boost::signals2::signal<Signature> mPrivate;
};
Unfortunately this didn't work because connect() only does some cleanup. It doesn't guarantee cleanup of all unconnected slots. Signal invocation on the other hand does a full cleanup but a dummy invocation would also be an unacceptable behavioral change (as already mentioned by others).
In the absence of alternatives i ended up in patching the original signal class (Edit: i really would appreciate a built-in solution. this patch was my last resort). My patch is around 10 lines of code and adds a public cleanup_connections() method to signal. My signal wrapper invokes the cleanup at the end of the disconnecting methods. This approach solved my problems and i didn't encounter any performance problems so far.
Edit: Here is my patch for boost 1.5.3
Index: signals2/detail/signal_template.hpp
===================================================================
--- signals2/detail/signal_template.hpp
+++ signals2/detail/signal_template.hpp
## -220,6 +220,15 ##
typedef mpl::bool_<(is_convertible<T, group_type>::value)> is_group;
do_disconnect(slot, is_group());
}
+ void cleanup_connections () const
+ {
+ unique_lock<mutex_type> list_lock(_mutex);
+ if(_shared_state.unique() == false)
+ {
+ _shared_state.reset(new invocation_state(*_shared_state, _shared_state->connection_bodies()));
+ }
+ nolock_cleanup_connections_from(false, _shared_state->connection_bodies().begin());
+ }
// emit signal
result_type operator ()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS))
{
## -690,6 +699,10 ##
{
(*_pimpl).disconnect(slot);
}
+ void cleanup_connections ()
+ {
+ (*_pimpl).cleanup_connections();
+ }
result_type operator ()(BOOST_SIGNALS2_SIGNATURE_FULL_ARGS(BOOST_SIGNALS2_NUM_ARGS))
{
return (*_pimpl)(BOOST_SIGNALS2_SIGNATURE_ARG_NAMES(BOOST_SIGNALS2_NUM_ARGS));